一种解决按键开关电平毛刺问题的算法
/*
* 通过检测按键开关的相应管脚电平状态来判断按键是否按下,
* 按键未按下时,对应管脚电平的为高,按下之后对应管脚电平变为低电平,
* 松开之后,回复高电平,通过电平变化的上升延来判断按键被按下
* 具体算法:主循环每轮进行一次电平采样,每次采样值保存在1Byte的最低位bit中
* (0:低电平,1:高电平),保存之前左移一位,确保保存的是最后的8次采样结果。
* 当值为0x0F时,认为按键被按下,进行相应的动作。
*
* 为解决电平毛刺问题,改为64bits,最高的16位为0,最低的16为1时,
* 进行相应的动作,中间32位忽略,经测试能较好解决毛刺问题。
*/
uint64_t SwAutoManualFlag = 0xFFFFFFFFFFFFFFFF; //!!!不能初始化为0,
uint64_t SwPriSecFlag = 0xFFFFFFFFFFFFFFFF; //线路切换按键,值为0x0000XXXXXXXXFFFF 时切换线路,!!!不能初始化为0,
void Process_Press_Button() //处理按键开关
{
SwAutoManualFlag <<= 1;
SwPriSecFlag <<= 1;
if ( GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_7 )) //按键开关低电平中断信号,
{
SwAutoManualFlag |= 0x01;
}
if ( GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_6 )) //按键开关低电平中断信号
{
SwPriSecFlag |= 0x01;
}
if ( (SwAutoManualFlag & 0xFFFF000000000000) == 0x0000000000000000
&& (SwAutoManualFlag & 0x000000000000FFFF) == 0x000000000000FFFF ) //检测到上升沿
{
//按键按下之后的处理函数
SwAutoManualFlag = 0xFFFFFFFFFFFFFFFF;
}
if ( (SwPriSecFlag & 0xFFFF000000000000) == 0x0000000000000000
&& (SwPriSecFlag & 0x000000000000FFFF) == 0x000000000000FFFF ) //检测到上升沿
{
//按键按下之后的处理函数
SwPriSecFlag = 0xFFFFFFFFFFFFFFFF;
}
}
<