完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
在我们初学单片机的时候,每当遇到使用按键我们都会遇到按键的消抖与松手检测的问题。传统的方法一般都是使用ms延时的方法来处理,这样处理是最省事,不需要考虑太多的问题。但是这样做带来的结果是白白浪费了单片机的资源。延时函数会让单片机傻傻的等待,不能去处理其他更重要的事情,这对于实时性要求较高,或者还有更多任务要处理的系统来说,是万万不可接受的,基于这个问题,今天跟大家分享一个基于状态机的按键程序,它不会让单片机处于傻等的尴尬状态。这是转载于马朝老师的一本书籍。
一、传统按键消抖处理方法: if(按键按下) delay_ms(10); if(按键确实按下) {进行任务处理} 二、基于状态机的按键处理方法: 1、首先是 keyboard.c 文件 //*************************************************************** // File Name : keyboard.c // Author : // Created : // Modified : // Revision : //*************************************************************** #ifndef _keyboard_c_ #define _keyboard_c_ #include #include #include "keyboard.h" //*************************************************************** //端口定义 //PIN DESCRIPtiON //P17 P16 P15 P14 // | | | | // ------------P10 1 2 3 F1 // ------------P11 4 5 6 F2 // ------------P12 7 8 9 F3 // ------------P13 * 0 # F4 //*************************************************************** #define KeyPort P1 #define key_state_0 0 //定义按键状态(基于状态机) #define key_state_1 1 #define key_state_2 2 #define key_state_3 3 #define NO_key 0 //*************************************************************** // Function : KeyBoardScan // Input : none // Output : Key Number // 0~9、*、#:ASCII code // F1、F2、F3、F4: (A、B、C、D) ASCII code // Description : 4*4 matrix keyboard scanning Function // //*************************************************************** uchar KeyBoardScan(void) { uchar key_temp; uchar key_num = NO_key; static uchar key_status = key_state_0; //按键状态 //线反转法扫描键盘 KeyPort = 0x0f; key_temp = KeyPort; KeyPort = 0xf0; key_temp |= KeyPort; KeyPort = 0xff; switch(key_status) { case key_state_0: //状态零为初始状态 if(key_temp != 0xff) key_status = key_state_1; break; case key_state_1: //状态一为按键按下状态 if(key_temp == 0xff) key_status = key_state_0; //若只是抖动,调回状态零 else { key_status = key_state_2; //若确实按下,调到状态二 switch(key_temp) { case 0x7e: //0111 1110 key_num = '1'; break; case 0xbe: //1011 1110 key_num = '2'; break; case 0xde: //1101 1110 key_num = '3'; break; case 0x7d: //0111 1101 key_num = '4'; break; case 0xbd: //1011 1101 key_num = '5'; break; case 0xdd: //1101 1101 key_num = '6'; break; case 0x7b: //0111 1011 key_num = '7'; break; case 0xbb: //1011 1011 key_num = '8'; break; case 0xdb: //1101 1011 key_num = '9'; break; case 0xb7: //1011 0111 key_num = '0'; break; case 0x77: //0111 0111 key_num = '*'; //* break; case 0xd7: //1101 0111 key_num = '#'; //# break; case 0xee: //1110 1110 key_num = 'A'; //F1 break; case 0xed: //1110 1101 key_num = 'B'; //F2 break; case 0xeb: //1110 1011 key_num = 'C'; //F3 break; case 0xe7: //1110 0111 key_num = 'D'; //F4 break; } } break; case key_state_2: //状态二表示确实有按键按下 if(key_temp == 0xff) key_status = key_state_3; //若检测到松手,调到状态三 break; case key_state_3: if(key_temp == 0xff) key_status = key_state_0; //若判断确实松手后,调回初始状态零 else key_status = key_state_2; //若只是抖动并不是真的松手,调回状态二 break; } return key_num; } #endif //===============================END OF FILE==================================// 2、其次是 keyboard.h 文件 // File Name : keyboard.h // Author : // Created : // Modified : // Revision : //*************************************************************** #ifndef _keyboard_h_ #define _keyboard_h_ #include #include "DataType.h" //*************************************************************** //端口定义 //PIN DESCRIPTION //P17 P16 P15 P14 // | | | | // ------------P10 1 2 3 F1 // ------------P11 4 5 6 F2 // ------------P12 7 8 9 F3 // ------------P13 * 0 # F4 //*************************************************************** //global functions declaration extern uchar KeyBoardScan(void); #endif //===============================END OF FILE==================================// 使用方法:以上程序代码只要添加到工程的源代码便可以。要利用单片机的定时器资源,每10-15ms中断一次,在中断里面调用 KeyBoardScan() 函数。 好了,以上就是今天要分享的知识,希望可以帮到大家,也留给不爱记录的自己,常温故而知新。 |
|
相关推荐
3 个讨论
|
|
你正在撰写讨论
如果你是对讨论或其他讨论精选点评或询问,请使用“评论”功能。
271 浏览 0 评论
298 浏览 0 评论
串口发送中断中对发送I/O口定义为GPIO输出,出现发送数据不完整,缺少2个字节,求解答
1942 浏览 3 评论
848 浏览 0 评论
【xG24 Matter开发套件试用体验】10-Bluetooth示例1
1009 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
10879 浏览 31 评论
浏览过的版块 |
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-8-28 01:27 , Processed in 0.675709 second(s), Total 44, Slave 36 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191