Emax 110-220V 通断蜂鸣器
经过N次的软硬件调试,终于是完美了。
过程中遇到的问题:①信号的误动作②程序跑飞的硬件复位③光耦电路的电阻选取④连续重复测试过程,程序的健壮性
实物图
原理图,Port1.0和Port1.1串接到主微动,Port2.0和Port2.1直接连接辅微动。当主微动导通时,由于电阻分压使得光耦导通,P3.3为低电平;辅微动闭合,P3.2为低电平。主微动信号和辅微动信号为互斥的两个信号量,当主微动为闭合状态,辅微动为断开状态,反之亦然。
#include "AT892051.H"
#define uint unsigned int
#define Master_switch P3_3
#define Slave_switch P3_2
#define Yellowlight P3_0
#define Redlight P3_1
#define Bell P3_7
#define rst P1_7
#define delaytime 20 //20*50ms
#define watchtime 40 //40*50ms
#define count 6 //6*50ms
#define chknum 48 //48*20us
static uint dtime;
static uint wait;
static uint dstate;
static uint dcheck;
static uint belltime;
bit checkstate(bit p) //周期(21+chknum*20)us
{
int sum[]={chknum,chknum};
if(p) //检测主微动为0,从微动为1
{
while(sum[0]&&sum[1]) // chknum*20us
{
Slave_switch=1;
if(Slave_switch)
{
sum[0]--;
}
else
{
sum[1]--;
}
}
}
else
{
while(sum[0]&&sum[1])
{
Master_switch=1;
if(Master_switch)
{
sum[0]--;
}
else
{
sum[1]--;
}
}
}
return (bit)sum[0];
}
//看门狗T0监测主程序
void watchdog() interrupt 1 using 3
{
if(!--dtime)
{
rst=0; //主程序跑飞,系统复位
}
if(!--belltime)
{
Bell=1;
}
}
//看门狗T1检测看门狗T0
void int50ms() interrupt 3 using 1
{
if(wait) wait--;
if(dcheck==dtime)
{
if(++dstate>watchtime) rst=0; //看门狗T0停止,系统复位
}
else
{
dcheck=dtime;
dstate=0;
}
}
//初始化
void init()
{
EA = 1;
ET1 = 1;
ET0 = 1;
PT1 = 0;
PT0 = 0;
TMOD = 0X11;
TL1 = 0X00;
TH1 = 0X00;
TL0 = 0XFF;
TH0 = 0X00;
TR1 = 1;
TR0 = 1;
P3 = 0xff;
P1 = 0xff;
dstate = 0;
dcheck = 0;
Bell = 0;
belltime=5;
}
//指示灯状态
void LED()
{
if(checkstate(1)) Redlight=0;
else Redlight=1;
}
void main() using 0
{
init();
for(dtime=watchtime;1;dtime=watchtime)
{
LED();
if(checkstate(0))
{
Yellowlight=0;
wait=delaytime; //在规定时间内,检测从微动断开
while(wait)
{
if(checkstate(1))
{
Redlight=0;
}
else
{
Redlight=1;
wait=delaytime;
break;
}
}
if(!wait) //超时,触发蜂鸣器
{
Bell=0;
belltime=20;
continue;
}
for(dtime=watchtime;checkstate(0);dtime=watchtime)
{
if(checkstate(1)) //若从微动闭合,则在规定时间段内检测主微动为断开状态
{
Redlight=0;
wait=delaytime;
while(wait)
{
if(!checkstate(0))
{
Yellowlight=1;
wait=delaytime;
break;
}
LED();
}
if(!wait) //超时,触发蜂鸣器
{
Bell=0;
belltime=20;
}
}else Redlight=1;
}
Yellowlight=1;
LED();
wait=delaytime;
while(wait) //在规定时间内,检测从微动为闭合状态
{
if(checkstate(1)) //若从微动为闭合状态
{
Redlight=0;
wait=count;
while(wait) //检测持续时间是否满足count*50ms
{
if(!checkstate(1)) //在count*50ms时间内,若从微动断开,则中断退出
{
Redlight=1;
wait=delaytime;
break;
}
}
if(!wait) //检测时间满足count*50ms,退出
{
wait=delaytime;
break;
}
else //未能持续count*50ms,在规定时间段内检测主微动为闭合状态
{
while(wait)
{
if(checkstate(0))
{
Yellowlight=0;
wait=delaytime;
break;
}
}
}
}
else //检测不到从微动闭合的信号量,但在规定时间段内检测到主微动再次为闭合状态,中断退出
{
Redlight=1;
if(checkstate(0))
{
Yellowlight=0;
wait=delaytime;
break;
}
}
}
if(!wait) //超时,触发蜂鸣器
{
Bell=0;
belltime=20;
}
}else
Yellowlight=1;
}
}
主控程序,看门狗T0检测主程序,看门狗T1检测看门狗T0,看门狗T1又作为主辅微动切换时间的定时器,当程序跑飞,触发硬件复位。主辅微动切换最长时间为1秒,超时触发蜂鸣器。