首页 » 99链接平台 » 高可靠性嵌入式软件设计-开关/按键输入去抖扫描(按键开关扫描输入变量)

高可靠性嵌入式软件设计-开关/按键输入去抖扫描(按键开关扫描输入变量)

乖囧猫 2024-10-24 20:00:48 0

扫一扫用手机浏览

文章目录 [+]

原因:

机械开关被按下之后,触点不会立即稳定下来而是会发生抖动,开关的抖动导致输入输入IO口的电平也会发生高、低电平的抖动。

根据其寿命试验,最坏情况下的开关稳定时间为15ms。
按照3倍余量的计算,需要45ms的去抖动时间,在45ms内至少需要4次采样,从而得到最大采样周期为11.25ms。

高可靠性嵌入式软件设计-开关/按键输入去抖扫描(按键开关扫描输入变量) 99链接平台
(图片来自网络侵删)

开关实际输入波形

根据这一要求,设计高可靠开关/按键输入扫描程序:

在switch.h的头文件中,

宏定义开关/按键的数量,

定义开关/按键扫描的结构体类型,

包含记录当前电平状态的成员变量level,

记录当前电平按下/抬起事件的成员变量edge,

记录去抖次数的成员变量debouncecount,

记录去抖之后按键状态的成员变量state;

声明开关/按键扫描使用的结构体变量为外部变量。

#define SWITCH_NUM 8

typedef struct{

u8 level;

u8 edge;

u8 state;

u8 debouncecount;

}stKeyTypeDef;

extern stKeyTypeDef stKeyDet[SWITCH_NUM];

在main.c文件中,

使用由timer模块提供的8ms定时标志timerregs.timer8ms;

判断是否到8ms定时时间,如果标志为TRUE,则8ms定时到,执行扫描程序。

从而其扫描周期为8ms<11.25ms满足要求。

定义const数组保存每个输入的去抖次数,去抖次数需要选择合适的数值。

太小即起不到去抖的效果,太大则会导致开关/按键的操作不灵敏。

去抖时间一般在60-100ms之间比较合适,我通常将去抖动次数设置为10次,对应去抖时间为80ms,如下:

const u8 debouncecount[SWITCH_NUM] = {8, 8, 8, 8, 8, 8, 8, 8};

按键扫描函数如下:

U8 i;U8 level;if(timerregs.timer8ms){for(i= 0; i < SWITCH_NUM ; i++) { level = getkeystate(i);//读IO口,获取当前按键/开关输入状态 if(level != stKeyDet[i].state) //i按键状态有变化 { stKeyDet[i].debouncecount++; //去抖计数累加 } else { stKeyDet[i].debouncecount = 0; //去抖次数清零 } if(stKeyDet[i].debouncecount >= debouncecount[i])//如果去抖次数超过了设定的次数 { stKeyDet[i].state = level; //修改开关/按键状态 stKeyDet[i].edge = TRUE; //开关/按键的按下/弹起事件 stKeyDet[i].debouncecount = 0; } } }

上述代码放在switch.c的RealTime实时函数中,在main主程序中实时调用。

在应用层程序中可以通过stKeyDet[i].state判断当前的开关/按键状态,

通过if((stKeyDet[i].state) && (stKeyDet[i].edge))判断按下事件,

通过if((stKeyDet[i].state == FALSE) && (stKeyDet[i].edge))判断弹起事件,

在main主程序的末尾,调用swith.c提供的状态清除函数,将stKeyDet[i].edge清成FALSE;

该程序有几个设计要求:

1) 根据定时器模块提供的8ms事件实现8ms/次的扫描。

2) 扫描程序在主程序中调用,而不是在中断进行检测,降低中断处理的负载,加快程序的响应。

3)其它模块程序通过state以及edge 变量判断开关/按键的状态和事件,进行逻辑处理。

4) 所有需要用到开关/按键的模块上处理完之后,在main函数的末尾需要把按下/弹起事件变量edge清零。

标签:

相关文章