單片機(jī)按鍵程序,夠完美嗎?
寫過(guò)一段時(shí)間單片機(jī)程序,也看了一些單片機(jī)程序,書上的,網(wǎng)上的,基本都是非常原始的讀取按鍵,延時(shí)判斷,這些按鍵相關(guān)代碼穿插于整個(gè)程序,著實(shí)不夠美觀,最重要的是不能復(fù)用,so俺就想做個(gè)按鍵框架,只需提供按鍵處理代碼即可,言歸正傳,先簡(jiǎn)介一下幾個(gè)文件,ringfifo.c提供了一個(gè)簡(jiǎn)單的環(huán)形緩沖隊(duì)列,用以通知按鍵消息,key.c 實(shí)現(xiàn)的按鍵的框架處理(讀取按鍵,調(diào)用按鍵處理函數(shù)),key_port.c 需提供底層硬件接口及用戶的按鍵處理函數(shù),目前支持的按鍵消息類型有4類:keyDown,keyRelease,longPress, double click.
key.h中提供了4個(gè)函數(shù):InitKey()為初始化,KeyProc() 須在主循環(huán)中調(diào)用,KeyScan()須定時(shí)(10-20ms)調(diào)用,SetKeyHandler()用來(lái)設(shè)置按鍵處理函數(shù)
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