2011年5月

经过N次的软硬件调试,终于是完美了。
过程中遇到的问题:①信号的误动作②程序跑飞的硬件复位③光耦电路的电阻选取④连续重复测试过程,程序的健壮性
3edd751exa454f18949f5.jpg
3edd751exa454f714443c.jpg
实物图
3edd751exa454f76092f2.jpg
原理图,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秒,超时触发蜂鸣器。