原创 实用可靠的干接点消抖滤波算法

2021-6-19 17:37 809 474 6 分类: MCU/ 嵌入式 文集: C语言
  1. /*
  2. *
  3. * 干接点常用于实现各种电气设备开关停控制的弱电接口,两个触点可以组合出无动作、开、停和关4种状态。
  4. * 干接点信号可以由手控面板发出,也可以由中控设备发出。
  5. * 在手动应用中常常遇到【停】键释放瞬间两路信号硬件滤波参数不对称导致误动作的问题;
  6. * 在中控应用中常常遇到两个触点同时切换瞬间两触点动作不同步或两路信号硬件滤波参数不对称导致误动作的问题。
  7. * 为了提高干接点控制的可靠性,必须采用硬件消抖和软件消抖紧密结合的消抖滤波方案。
  8. *
  9. */
  10. #include "Board.h"
  11. #include "DryContact.h"
  12. #define TIME_CONSTANT 64 // 消抖滤波时间为64ms
  13. // #define TIME_CONSTANT 128 // 消抖滤波时间为128ms
  14. #define THRESHOLD_LOW (int16_t)(48*TIME_CONSTANT) // 对应于最大输出的36.8%
  15. #define THRESHOLD_HIGH (int16_t)(80*TIME_CONSTANT) // 对应于最大输出的63.2%
  16. /*
  17. * 干接点消抖滤波函数,查询周期1ms
  18. */
  19. void DryContacts_Poll_1ms(void)
  20. {
  21. int16_t input0;
  22. int16_t input1;
  23. int16_t input2;
  24. int16_t input3;
  25. static int16_t filter0 = 0;
  26. static int16_t filter1 = 0;
  27. static int16_t filter2 = 0;
  28. static int16_t filter3 = 0;
  29. static uint8_t state = 0; // 当前干接点状态
  30. static uint8_t prev_state = 0; // 前一个干接点状态
  31. if(!Board_GetDryContact0() && !Board_GetDryContact1())
  32. {
  33. input0 = 127;
  34. input1 = 0;
  35. input2 = 0;
  36. input3 = 0;
  37. }
  38. else if(Board_GetDryContact0() && !Board_GetDryContact1())
  39. {
  40. input0 = 0;
  41. input1 = 127;
  42. input2 = 0;
  43. input3 = 0;
  44. }
  45. else if(!Board_GetDryContact0() && Board_GetDryContact1())
  46. {
  47. input0 = 0;
  48. input1 = 0;
  49. input2 = 127;
  50. input3 = 0;
  51. }
  52. else // if(Board_GetDryContact0() && Board_GetDryContact1())
  53. {
  54. input0 = 0;
  55. input1 = 0;
  56. input2 = 0;
  57. input3 = 127;
  58. }
  59. filter0 += input0 - (filter0 + TIME_CONSTANT/2)/TIME_CONSTANT; // 简易一阶IIR滤波
  60. filter1 += input1 - (filter1 + TIME_CONSTANT/2)/TIME_CONSTANT;
  61. filter2 += input2 - (filter2 + TIME_CONSTANT/2)/TIME_CONSTANT;
  62. filter3 += input3 - (filter3 + TIME_CONSTANT/2)/TIME_CONSTANT;
  63. if(filter0 > THRESHOLD_HIGH)
  64. {
  65. state = 0;
  66. }
  67. else if(filter1 > THRESHOLD_HIGH)
  68. {
  69. state = (1<<0);
  70. }
  71. else if(filter2 > THRESHOLD_HIGH)
  72. {
  73. state = (1<<1);
  74. }
  75. else if(filter3 > THRESHOLD_HIGH)
  76. {
  77. state = (1<<0)|(1<<1);
  78. }
  79. if(state != prev_state)
  80. {
  81. if(state == 0)
  82. {
  83. // 在此处处理干接点变化::触点1、触点2都断开
  84. }
  85. else if(state == 1)
  86. {
  87. // 在此处处理干接点变化:触点1接通
  88. }
  89. else if(state == 2)
  90. {
  91. // 在此处处理干接点变化:触点2接通
  92. }
  93. else if(state == 3)
  94. {
  95. // 在此处处理干接点变化:触点1、触点2都接通
  96. }
  97. prev_state = state;
  98. }
  99. }

作者: Qeecoda, 来源:面包板社区

链接: https://mbb.eet-china.com/blog/uid-me-1099225.html

版权声明:本文为博主原创,未经本人允许,禁止转载!

文章评论1条评论)

登录后参与讨论

yzw92 2021-6-20 10:29

感谢分享
相关推荐阅读
Qeecoda 2020-06-11 22:56
一个让人头痛而又有趣的软件bug
这是我前几天遇到的bug,RS485协议程序我已经做过无数次了,有无数个成功的先例。当开始做这个小程序的时候,我认为对我而言这只是小菜一碟,我挥挥手就可以把它搞定。但是事情出乎我的意料!程序工作不正常...
Qeecoda 2020-05-17 16:02
电子产品常见故障现象、原因分析及改进措施(一)
1. 故障现象:通电无反应。原因分析:(1)接插件接不良;(2)470压敏电阻击穿;(3)开关电源的高压整流桥击穿;(4)开关电源的高压整理滤波电容损坏;(5)开关电源的开关管损坏;(6)开关电源的高...
Qeecoda 2020-03-28 11:11
欧姆定律的推导过程
...
Qeecoda 2020-03-23 18:18
环环紧扣,从傅里叶级数到Z变换的推导过程(六)
...
Qeecoda 2020-03-21 16:18
环环紧扣,从傅里叶级数到Z变换的推导过程(五)
...
广告
我要评论
1
474
1
2
3
4
5
6
7
8
9
0
广告
关闭 热点推荐上一条 /3 下一条