GPIO输入应用:按键
按键原理
按键结构
-
(机械式)按键下有一个反作用力金属簧片,当按下按键时,簧片向下弯曲使得触点接通,松手时簧片回弹使得触点断开
-
这样的设计使得按键在按下与松开时分别对应电路开路与短路的状态,从而产生高低电平的变化
-
再将模拟信号转换为数字信号:
按下时电路接通,与地相连为低电平,输入寄存器读0
松开时电路断开,与电源连接为高电平,输入寄存器读1
按键去抖动
-
抖动的产生
-
理想中按下一次按键,只产生一个下降沿与一个上升沿,边沿近乎垂直无“毛刺”;但实际上按键后的电平存在一个变化过程,在这个过程中处于不确定状态的信号被传递到引脚,会被识别为多个脉冲信号
-
因此,为了保证单片机对按键状态判别不出错误,需要设法消除轻触按键后所产生的抖动信号
-
-
硬件去抖动
在不确定信号到达引脚前,先让它通过RC低通电路(滤去高频的信号波动),再进入施密特触发器(即滞回比较器,使得信号转化为平稳的方波),这样就修正了波形
-
软件延时去抖动
抖动大致持续5-10ms,因此可以让单片机忽略掉抖动期,在信号进入稳定期时才去读取电平状态;具体的做法是检测到按键按下时先延时10-20ms,再判断按键状态
-
这种做法不需要额外硬件,实现难度低,因此非常通用
-
但是极度不推荐此种方式,因为软件延时的期间单片机CPU被占用无法执行任何任务,很可能对其他任务造成影响(当然,使用RTOS就不会有这种问题)
-
代码实现
-
初始化按键
void IO_Init(void) { //配置PA3,PA4,PA5,PA6这些与按键相连的端口 //具体配置哪些端口请看你所用开发板的原理图中,哪些端口与“独立按键”相连 PA_DDR = 0x87; //配置为0输入模式 PA_CR1 = 0x78; //寄存器1配置为1启用上拉输入 PA_CR2 = 0x00; //寄存器2配置为0不启用中断 //本节采用软件查询方式实现功能,暂时不使用中断 }
-
查询按键状态
#define key0 PA_IDR_IDR3 //将寄存器位所控制的硬件命名方便使用,其它省略 void Qurey(void) { if(!key0){//当检测到按键状态发生变化时 delay(10);//软件延时消抖 if(!key0){//等过了抖动期后再次检测按键状态 led0 = ~led0;//取反改变灯的状态 while(!key0);//松手检测,如果按键保持按下的状态则继续运行 } } }//在主函数中不断调用此查询函数即可
按键的扩展
- 如上通过不断查询按键状态实现按键功能的方法有一个重大的缺点,就是占用了CPU资源,让CPU无法进行其他工作,这一点可以通过中断功能来规避
- 另外这种简单的把一个按键连接到一个配置为上拉输入的GPIO引脚的方法在按键变多时就会占用太多引脚,这可以通过组成矩阵键盘的方式规避
本文来自博客园,作者:无术师,转载请注明原文链接:https://www.cnblogs.com/untit1ed/p/18560244
本文使用知识共享4.0协议许可 CC BY-NC-SA 4.0
请注意: 特别说明版权归属的文章以及不归属于本人的转载内容(如引用的文章与图片)除外