情景: 有一个端口外接导线,该端口上电后即开始运行特定函数,如跑流水灯等任务,现需加一个信号防抖机制,
要求效果是电源线快速滑过该端口认为是抖动,不亮灯,稳接持续300ms后才亮灯.
已知电源有接触就会上电,理论上程序立即开始运行,那么就要在该流水灯函数运行前做一个防抖判断,
判断该管脚高电平了持续300ms,才解锁亮灯程序运行标志位,真正开始亮灯
当电源线快速滑过时,程序虽然运行,但是持续时间不足300ms,标志位未解锁不会亮灯.
假设P02口是电源输入端口
/*P02输入事件的结构体*/
typedef struct
{
u8 last_state; // 上一次的状态
u8 current_state; // 当前的状态
u16 debounce_counter; // 防抖计数器
}InputEventItem_t;
static InputEventItem_t Input_P02; //P02输入事件的结构体
static u8 P02_val = 0 ; // P02口的最终状态 0低电平,1高电平
/***********
P02口的触发信号防抖函数
************/
u8 P02_debounce(void)
{
Input_P02.current_state = ((GPIO_GetPin(GPIO_PORT_0, GPIO_PIN_2)) ? INPUT_HIGH : INPUT_LOW); // 读取P02口的状态
if (Input_P02.current_state!= Input_P02.last_state ) // 如果状态发生改变即存在抖动
{
//printf("P02口电平状态改变\r\n");
Input_P02.debounce_counter = 0; // 重置防抖计数器
Input_P02.last_state = Input_P02.current_state; // 更新上一次的状态
}else // 如果状态没有改变
{
Input_P02.debounce_counter++; // 防抖计数器加1
if (Input_P02.debounce_counter >= 3) // 如果防抖计数器达到3 主函数中P02_debounce每100ms运行一次,即此条件满足需要300ms
{
if ((Input_P02.current_state == INPUT_HIGH) ) // 如果当前状态为高电平
{
P02_val = 1;
}
if ((Input_P02.current_state == INPUT_LOW))
{
P02_val = 0;
}
Input_P02.debounce_counter = 0; // 重置防抖计数器
}
}
return P02_val;
}
主函数中每100ms运行P02_debounce函数,检测02口的电平状态
while (1)
{
if(BSP_Is1MsTickDone()) // 每1ms执行一次
{
WDT_Feed(); // 喂狗
if(++time_led >=100)
{
time_led = 0;
P02_static = P02_debounce(); // 每100ms检测P02电平状态
}
if(P02_static==1) // 如果是P02是高电平,进行流水灯操作
{
time_ledMiddle++;
if(time_ledMiddle > 60000)
{
time_ledMiddle = 20000;
}
SHOW(time_ledMiddle); // 时间代入依次执行动画
}
else
{
time_ledMiddle = 0; // 检测到P02是低电平,停止动画
Led_All_Close();
}
}
}