这个功能较为简单,写了个以STC8H1K08 为例,可以试试。
#include <stc8g.h> //STC8H1K08 IRC内部时钟选12MHZ
typedef unsigned char u8; //对数据类型进行定义声明
typedef unsigned int u16; //对数据类型进行定义声明
sbit key1 = P1^2; //按键输入
sbit key2 = P1^3; //光电开关,0为有信号,1为无信号
sbit key3 = P1^4; //光电开关,0为有信号,1为无信号
sbit key4 = P1^5; //备用输入
sbit kt1 = P3^7; //继电器控制,0开启,1关闭
sbit kt2 = P3^6; //继电器控制,0开启,1关闭,备用
bit flag10ms = 0; //10ms时间标志,按键扫描
/*********************触发扫描*************************/
void scan()
{
static u8 i = 0; //扫描次数
kt1 = key2 | key3; //key2和key3中有1路无信号,则关闭继电器1
if(flag10ms) //检测10ms时间标志
{
flag10ms = 0; //清零10ms标志
if(key1){i = 0;}
else
{
i++;
if(i == 2) {kt1 = ~kt1;}
if(i == 250) {i = 3;}
}
}
}
/*************************主函数******************************/
void main()
{
P1M0 = 0x00; P1M1 = 0x00; //P3设置为准双向口
P3M0 = 0x00; P3M1 = 0x00; //P5设置为准双向口
kt1 = 1; //关闭继电器1
kt2 = 1; //关闭继电器2
PT1 = 0; //设置Tim1中断为低级0 PT1=0
IPH &= 0xF7; //0xF7=11110111 PT1H=0
ET1 = 1; //开启定时器1中断
EA = 1; //开启总中断
AUXR &= 0xBF; //定时器时钟12T模式
TMOD &= 0x0F; //设置定时器模式16位自动重装
TL1 = 0xF0; //设置定时初始值10ms
TH1 = 0xD8; //设置定时初始值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
WDT_CONTR = 0x24; //使能看门狗,溢出时间约为1s
while(1) //主循环
{
WDT_CONTR = 0x34; //清看门狗,否则系统复位
scan(); //调入继电器扫描函数
}
}
/**********定时器Tim1中断 10ms 级别0***********/
void Time1() interrupt 3
{
flag10ms = 1; //产生10ms标志位,用于按键扫描
}
/**********Program Size: data=10.1 xdata=0 code=245***********/
|