ARTICLE · 1295300
IO 口偶尔出现毛刺误触发?分享一套实用软件滤波算法
IO 口偶尔出现毛刺误触发?分享一套实用软件滤波算法
前言
在PCBA上有一些过大电流的地方,如果有I/O电平操作,这时就容易受干扰,可能会偶发出现一个毛刺,影响功能。为了设备稳定运行,通常会采用I/O口滤波处理,把偶发的毛刺给过滤掉。
一、简介
在PCBA设计过程中,大电流走线附近往往伴随着较强的电磁干扰。如果此时旁边有I/O信号线在进行电平操作,就极易受到耦合干扰,导致MCU读取到偶发的毛刺信号。
这种毛刺如果被程序误判为有效电平,轻则导致LED闪烁异常,重则引发误触发、状态机错乱,影响设备稳定运行。
为了解决这个问题,通常我们会采用I/O口滤波处理,通过软件算法把偶发的毛刺给过滤掉。
二、I/O电平滤波算法
下面是一个经典的计数式滤波算法,核心思想是:连续检测到N次相同电平后,才确认该电平有效。
1. 数据类型定义
//数据类型定义typedefenum IoLevel_e{ PS_IO_LEVEL_HIGH, PS_IO_LEVEL_LOW, PS_IO_LEVEL_NUM}g_emIoLevel;g_emIoLevel g_emLedLevel = PS_IO_LEVEL_NUM;2. I/O电平滤波处理函数
//I/O电平滤波处理g_emIoLevel PS_GetIoElecLevel(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, uint16_t u16FiltNum){static g_emIoLevel semRetVal = PS_IO_LEVEL_NUM;staticuint16_t s_u16HighLevelCnt = 0;staticuint16_t s_u16LowLevelCnt = 0;if(HAL_GPIO_ReadPin(GPIOx,GPIO_Pin) == GPIO_PIN_SET) { s_u16HighLevelCnt++;if(s_u16HighLevelCnt > u16FiltNum) { s_u16HighLevelCnt = 0; semRetVal = PS_IO_LEVEL_HIGH; } s_u16LowLevelCnt = 0; }else { s_u16LowLevelCnt++;if(s_u16LowLevelCnt > u16FiltNum) { semRetVal = PS_IO_LEVEL_LOW; } s_u16HighLevelCnt = 0; }return semRetVal;}3. 函数调用示例
/***********************函数调用****************************/g_emLedLevel = PS_GetIoElecLevel(GPIOA, GPIO_PIN_0, 500);if(g_emLedLevel == PS_IO_LEVEL_HIGH){ HAL_GPIO_WritePin(LED4_GPIO_PORT, LED4_PIN, GPIO_PIN_SET);}elseif(g_emLedLevel == PS_IO_LEVEL_LOW){ HAL_GPIO_WritePin(LED4_GPIO_PORT, LED4_PIN, GPIO_PIN_RESET);}三、算法原理解析
这个算法的逻辑非常清晰,核心在于两个计数器和一个阈值:
s_u16HighLevelCnt | |
s_u16LowLevelCnt | |
u16FiltNum |
工作流程:
每次调用读取一次GPIO引脚状态。 如果是高电平,高电平计数器+1;如果此时低电平计数器不为0,则清零(说明之前不是连续低电平)。 当高电平计数器超过阈值 u16FiltNum时,才正式确认输出为高电平,并将计数器清零。低电平逻辑同理。
为什么能滤除毛刺?
假设 u16FiltNum = 500,意味着需要连续500次调用都读到高电平,才会确认输出高电平。如果中间出现一次低电平毛刺,低电平计数器会+1,同时高电平计数器被清零,之前的计数全部作废。这样,单个或短时间的毛刺脉冲根本无法通过滤波。
四、使用注意事项
调用周期要稳定:该算法依赖调用频率,建议放在固定的定时器中断或主循环中周期性调用,保证滤波时间常数一致。 滤波阈值选择: u16FiltNum越大,抗干扰能力越强,但响应速度越慢。需要根据实际信号频率和干扰程度权衡。静态变量问题:函数内使用了 static变量,意味着该函数不可重入。如果多个IO口需要滤波,建议将状态变量封装成结构体,或者为每个IO口单独写一个函数。初始状态: semRetVal初始为PS_IO_LEVEL_NUM,调用方需要处理这个无效状态,避免上电瞬间误动作。
五、总结
I/O口滤波是嵌入式软件中非常实用的小技巧,成本低、效果好。对于PCBA上大电流干扰导致的偶发毛刺,这种计数式滤波算法能够有效提升系统的稳定性。
如果你也有类似的抗干扰经验,欢迎在评论区分享交流!
—— END ——
如果觉得有用,欢迎点赞、在看、转发三连支持一下~
【往期推荐】
环形队列(FIFO)的 C 语言实现:串口收发、ADC 采集都好用
低功耗 BLE 玄学 bug!杰理AW313A2 静置越久越容易死机















































































