redelz 发表于 2024-6-21 17:10:53

分享一个STC单片机PLC开关量输入去机械抖动算法程序代码

1,很多人认为开关量输入避开机械抖动可以通过延时再读入的解决,
   实际上这种算法的理论和实际效果都是不正确的。
   特别是有一些几毫秒到十几毫秒的延时去抖动算法既缺乏理论依据也容易产生误动作。
2,下面给大家分享的这个算法,既能够提供快速响应,又避开了复杂的延时算法,
   而且这个输入扫描算法不依赖其他任何算法,也就是完全没有任何其他算法的耦合性。
;----------------------------------------------------------------------
;** Input routine
;----------------------------------------------------------------------
;
ScanInput:                      ;Scan input data
            Mov         INDATA,#0FFh
      nop
      nop
      nop
      nop
      mov   r0,INDATA      ;get input data
      nop
      nop
      nop
      nop
      mov   a,INDATA
      xrl   a,r0
      jnz   scani1
      sjmp    scani2
scani1: nop
      nop
      nop
      nop
      mov   r0,INDATA      ;get data
      nop
      nop
      nop
      nop
      mov   a,INDATA
      xrl   a,r0
      jnz   scani3
      sjmp    scani2
scani3: nop
      nop
      nop
      nop
      mov   r0,INDATA            ;get data
scani2: mov   a,r0
;       cpl   a
      cjne    a,TX0_7,scanip8
      sjmp    scanip9
scanip8:setb    InputChanged
      mov   TX0_7,a          ;update X0...X7



soma 发表于 2024-6-21 21:42:44

纯汇编,还是英文注释

xxxevery 发表于 2024-6-21 21:55:35

有谁能分析一下原理呢

李鑫发 发表于 2024-6-24 15:49:47

天书一样

wugqsh 发表于 2024-6-30 11:43:08

还有人在用汇编{:4_250:}

网老四 发表于 2024-6-30 13:20:15

本帖最后由 网老四 于 2024-6-30 13:21 编辑

信号抖动,分几种情况,
1,状态变化时抖动,然后稳定,大多数机械触点属于这一类.
2,信号不管接通还是断开,由于触点接触不良或者环境噪声导致信号一直抖.

对于第一种情况,用传统延时再确认法有效.也可以死等信号稳定不变再确认状态.
机械开关抖动时间范围很广,几个ms到几十个ms都有,要根据实际情况设置延时时间.

对于第二种情况,就不适合简单的延时确认法,因为再次确认时候可能还是错误信号.用死等稳定的方法也不可以.
这种情况可以考虑用统计概率的办法来处理,在一段时间内多次检测信号状态,计算高电平出现的次数,
当检测到绝大多数都是高电平时候,可以认为信号是高电平,当检测到绝大多数都是低电平时候,可以认为信号是低电平.
这种方法相当于对信号做了简单的平均值滤波.在恶劣环境时候比较有效.

redelz 发表于 2024-6-30 13:42:52

本帖最后由 redelz 于 2024-6-30 14:02 编辑

网老四 发表于 2024-6-30 13:20
信号抖动,分几种情况,
1,状态变化时抖动,然后稳定,大多数机械触点属于这一类.
2,信号不管接通还是断开,由于 ...
感谢专业回复。是啊,虽然不是公式算法,但是这个代码的本质就是滤波算法。实际上这个代码的巧妙之处就是指令延时时间级别的连续采样,同时在有确定结果时及时返回,如果CPU时钟快可以将上述代码重复2次。所有软件算法必须首先理论能够说得通,实践才可行。

jwd 发表于 2024-6-30 15:32:04

我一般软定时器,采样个数,如果采样个数够了就是确认信号

Lkck8210 发表于 2024-6-30 18:33:42

sbit Key = P3^2;
u8 KeyVal = 0;//用完清零
void KeyScan()//10ms运行一次
{
        static u8 DelayXD = 0xFF;
        DelayXD = DelayXD<<1 | Key;
        if(DelayXD==0xFE)KeyVal=1;
}

redelz 发表于 2024-6-30 18:44:55

本帖最后由 redelz 于 2024-6-30 20:06 编辑

jwd 发表于 2024-6-30 15:32
我一般软定时器,采样个数,如果采样个数够了就是确认信号
为什么说单纯延时不可靠,并且没有理论依据的主要原因是,延时占用的时间没有采样信息,也就是无法获得真实滤波效果。
页: [1] 2
查看完整版本: 分享一个STC单片机PLC开关量输入去机械抖动算法程序代码