单片机按键程序,够完美吗?
扫描二维码
随时随地手机看文章
写过一段时间单片机程序,也看了一些单片机程序,书上的,网上的,基本都是非常原始的读取按键,延时判断,这些按键相关代码穿插于整个程序,着实不够美观,最重要的是不能复用,so俺就想做个按键框架,只需提供按键处理代码即可,言归正传,先简介一下几个文件,ringfifo.c提供了一个简单的环形缓冲队列,用以通知按键消息,key.c 实现的按键的框架处理(读取按键,调用按键处理函数),key_port.c 需提供底层硬件接口及用户的按键处理函数,目前支持的按键消息类型有4类:keyDown,keyRelease,longPress, double click.
key.h中提供了4个函数:InitKey()为初始化,KeyProc() 须在主循环中调用,KeyScan()须定时(10-20ms)调用,SetKeyHandler()用来设置按键处理函数
key.h
1 #ifndef __KEY_H__
2 #define __KEY_H__
3
4 #define NULL 0
5
6 typedef enum{
7 KEY_EVENT_DOWN = 0,
8 KEY_EVENT_UP,
9 KEY_EVENT_LONGPRESS,
10 KEY_EVENT_DOUBLECLICK,
11 KEY_EVENT_COMBO_KEYDOWN,
12 }KeyEventType;
13
14 typedef void (*pKeyEventCB)(void *para);
15
16 typedef struct _tagKeyInfo
17 {
18 unsigned char keyCode;
19 unsigned char keyStatus;
20 unsigned char comboKeyFlag;
21 unsigned int keyDbClickTime;
22 unsigned int keyDownTime;
23 unsigned int keyRepeatTime;
24 pKeyEventCB FuncCB[5];
25 void * para[5];
26 }KeyInfo;
27
28 typedef struct _tagMessageInfo
29 {
30 unsigned int keyEvent;
31 unsigned int keyCode;
32 KeyInfo* pContext;
33 }MessageInfo;
34
35
36
37 void InitKey(void); //
38
39 void KeyProc(void);// call this func in main loop
40
41 void KeyScan(void); // call it in timer service, 20ms
42
43 pKeyEventCB SetKeyHandler(unsigned char key,KeyEventType event,pKeyEventCB pFunc,void *para);
44
45 #endif
key.c
1#include"key_port.h"2#include"key.h"3#include"ringfifo.h"4#include56#defineKEY_STATE_UP0X07#defineKEY_STATE_DOWN0X38#defineKEY_STATE_LONGRESS0XF9#defineKEY_STATE_RELEASE0XC1011staticKeyInfokInfo[KEY_AMOUNT];12staticRingFifoMsgQ;131415voidPostMessage(MessageInfo*pMsg)16{17PushFifo(&MsgQ,pMsg);18}1920unsignedcharGetMessage(MessageInfo*pMsg)21{22returnPopFifo(&MsgQ,pMsg);23}2425//callitintimerservice26voidKeyScan(void)27{28inti=0;29unsignedcharc=0;30KeyInfo*pInfo=kInfo;31MessageInfoMsg;32for(i=0;i