为什么你的系统会有误动作?

      为什么你的信号线拉长了会导致系统混乱?

      为什么明明逻辑没有错,但整个系统运行起来是那么地别扭?

      ......

      不要怀疑单片机的质量不行!

      不要怀疑自己的逻辑能力!

      不要怀疑客户的意见!

      ......

      相信自己,但要细心!

      假如你的系统接到外部的一个脉冲信号而触发一个动作,这动作诸如:电机转一个角度、吸合电磁铁或动作继电器等,

那么,这个外部信号就得经过严格的滤波,除了硬件的滤波之外,在软件上仍然要求进行数字滤波。

 

      下面这段程序是我经过验证而且稳定运行于很多我曾经开发的工控产品中,它的功能是:对外部输入信号[ExtSign_Ch1]进行数字滤波,滤波时间[cSetDL_ExtSign_Ch1]是个参数,可以设置,里边涉及到的变量有:

       [b100us]                -- 全局变量,1bit, 是个时间标志位,作用在于每100us调用一次该滤波程序,也可以说是每100us对信号采样一次。

       [bExtSign_Ch1]      -- 全局变量,1bit,反映外部信号的有效(经过滤波后的)当前状态。

       [bOldExtSign_Ch1]  -- 全局变量,1bit,反映外部信号的有效(经过滤波后的)之前状态,和[bExtSign_Ch1]一起配合查询可判断出信号的上升沿或

                                        下降 沿,如:(bExtSign_Ch1 &&  (!bOldExtSign_Ch1)) 便是上升沿。

       [bNowExtSign_Ch1] -- 全局变量,1bit,反映外部信号的(没有经过滤波的)当前状态,由函数[Rd_ExtSignal_Ch1()]读得。  

       [cDL_ExtSign_Ch1]  -- 全局变量,8bits,数字滤波时间计数器。

       [bCh1_Flt_ing ]        -- 全局变量,1bit,滤波进行中标志。

       [cSetDL_ExtSign_Ch1] -- -- 全局变量,8bits,是个参数,用于设定数字滤波的滤波常数,当被设为0时,表示本数字滤波程序不起到滤波的作用。

 

void ChkFlt_ExtSign_Ch1()
{
 if(b100us)
 {
  bOldExtSign_Ch1 = bExtSign_Ch1; 

  Rd_ExtSignal_Ch1();  

 

  if(bCh1_Flt_ing)                                          //滤波中?
  {
   if (bNowExtSign_Ch1^bExtSign_Ch1)          //外部信号有变化?
   {
    if(--cDL_ExtSign_Ch1 == 0)
    {
     bExtSign_Ch1 = bNowExtSign_Ch1;
     bCh1_Flt_ing = FALSE;
    }
   }
   else
   {
    bCh1_Flt_ing = FALSE;                              //信号无效,放弃滤波
   } 
  }
  else
  {
   if (bNowExtSign_Ch1^bExtSign_Ch1)          //外部信号有变化?
   {
    if(cSetDL_ExtSign_Ch1 != 0 )                    //若滤波常数为0,则不进行滤波
    {
     cDL_ExtSign_Ch1 = cSetDL_ExtSign_Ch1 ;
     bCh1_Flt_ing = TRUE;                             //准备滤波 
    }
    else
    {
     bExtSign_Ch1 = bNowExtSign_Ch1;
     bCh1_Flt_ing = FALSE;
    }
   } 
  }
 } 
}

        一个外部信号经过如此这般处理之后,已经变得很干净了,放心查询信号触发你的动作吧。