前端時間要用按鍵,搞了個狀態機(如圖):前端
main.c函數
1 #include <N76E003.H> 2 #include <SFR_Macro.h> //N76E003 SFR寄存器設置宏定義 3 #include <Function_define.h> //功能定義 4 #include "data.h" 5 #include "interrupt.h" 6 #include "button.h" 7 /*--------------------------------------------------------*/ 8 // 初始化全部 9 void Init_All(void){ 10 InitMcu(); // 初始化MCU 11 Init_button(); // 鍵盤初始化 12 } 13 /*******************************************************************/ 14 // 發佈版本 15 void main(void){ 16 Init_All(); 17 while(1){ 18 ; 19 } 20 }
data.hspa
1 /*-------------------------------------------------------------------------- 2 data.h 3 --------------------------------------------------------------------------*/ 4 #ifndef __DATA_H__ 5 #define __DATA_H__ 6 7 8 /*----------------------------------------------------*/ 9 // 按鍵狀態(狀態定義) 10 #define Button_DOWN 0 // 按鍵按下 11 #define Button_UP 1 // 按鍵擡起 12 // 按鍵功能模式(軟件模式定義) 13 #define Button_mode_NoOperation 0 // 無動做 14 #define Button_mode_ShortPress 1 // 短按 15 #define Button_mode_longPress 2 // 長按 16 #define Button_mode_evenPress 3 // 連續快按(雙擊) 17 // 鍵盤消抖時間 18 #define Button_TimeDebounce 20/2 // 單位 ms 去抖動時間 19 #define Button_TimeShort_even 100/2 // 單位 ms 短按轉連續按時間 20 #define Button_TimeEvenPressinterval 5000/2 // 單位 ms 雙擊判斷閾值 21 #define Button_TimeState_reset 60000/2 // 單位 ms 60s 無動做 退出設置 22 // 鍵盤狀態機模式 23 #define Button_status_S0 0 // 等待按鍵按下 24 #define Button_status_S1 1 // 去抖驗證 25 #define Button_status_S2 2 // 按下時間(計算是否是長按) 26 #define Button_status_S3 3 // 快安判斷(判斷是否是短按) 27 #define Button_status_S4 4 // 快安去抖 28 #define Button_status_S5 5 // 等待快安退出 29 /*----------------------------------------------------*/ 30 #define Unit_cycle 32000 // 中斷處理週期 31 /*----------------------------------------------------*/ 32 struct Button_data{ 33 unsigned int Button_LiftTime; // 擡起時間 34 unsigned int Button_PressTime; // 按下時間 35 unsigned char Button_State_machine_mode:3; // 按鍵狀態模式(狀態機) 36 unsigned char Button_statusmode:2; // 0無動做 1短按 2連發 3長按 37 unsigned char Button_status:1; // 按鍵的狀態(按鍵鬆開,界面刷新) 38 39 }; 40 /*------------------------ 系統時間 ----------------------------*/ 41 struct OS_DATA{ 42 // 系統初始化 43 unsigned char u8TH0_Tmp; // 中斷高8位 44 unsigned char u8TL0_Tmp; // 中斷低8位 45 // 鍵盤 46 struct Button_data Button0; 47 48 }; 49 50 extern struct OS_DATA DATA; 51 #endif
data.ccode
1 #include "data.h" 2 3 struct OS_DATA DATA; // 系統數據
interrupt.hblog
1 /*-------------------------------------------------------------------------- 2 interrupt.h 3 --------------------------------------------------------------------------*/ 4 5 #ifndef __INTERRUPT_H__ 6 #define __INTERRUPT_H__ 7 8 /*----------------------------------------------------*/ 9 void InitMcu(void); 10 #endif
interrupt.cip
1 #include <N76E003.H> 2 #include <SFR_Macro.h> //N76E003 SFR寄存器設置宏定義 3 #include <Function_define.h> //功能定義 4 #include "data.h" 5 #include "interrupt.h" 6 #include "button.h" 7 8 /*--------------------------------------------------------*/ 9 #define T0_INIT Unit_cycle 10 #define T0_ms 500 11 /*--------------------------------------------------------*/ 12 //初始化單片機 13 void InitMcu(void){ 14 TIMER0_MODE1_ENABLE; //定時器0的模式1 15 set_T0M; //設置定時器0的時鐘爲系統時鐘 16 //u8TH0_Tmp和u8TL0_Tmp 宏變量 中斷可調用 17 //Init_OS_Date();已經初始化 18 DATA.u8TH0_Tmp = (65536-T0_INIT)/256; //計算T0高8位數據 19 DATA.u8TL0_Tmp = (65536-T0_INIT)%256; //計算T0低8位數據 20 TH0 = DATA.u8TH0_Tmp; //數據裝入定時器0(計數器0)數據 21 TL0 = DATA.u8TL0_Tmp; 22 set_ET0; //開啓定時器0中斷 23 set_EA ; //開啓總中斷 24 set_TR0; //啓動定時器0 25 } 26 /************************************************************************** 27 Function: TIM1_UPD_OVF_IRQHandler 28 Description: TIM1溢出中斷 10ms 29 Input: no 30 Output: no 31 Return: no 32 **************************************************************************/ 33 //定時器 ms 34 void Timer0_ISR ( void ) interrupt 1 //interrupt address is 0x000B 35 { 36 //獲取定時器數據 37 TH0 = DATA.u8TH0_Tmp; 38 TL0 = DATA.u8TL0_Tmp; 39 // 按鍵時間模塊 40 All_Buttonrefresh(); 41 } 42 /******************************************************************/
button.hget
1 /*--------------------------------------------------------- 2 button.h 3 按鍵控制 4 ---------------------------------------------------------*/ 5 #ifndef _BUTTON_H_ 6 #define _BUTTON_H_ 7 /*---------------------------------------- 數據初始化 ------------------------------------------*/ 8 #define button0_Num 5 9 sbit button0 = P1^button0_Num; // 按鍵 10 #define Git_button0 button0 11 /*---------------------------------------- 數據獲取部分 ------------------------------------------*/ 12 13 /*---------------------------------------- 鍵盤初始化 ------------------------------------------*/ 14 void Init_button(void); 15 void All_Buttonrefresh(void); 16 17 #endif
button.cit
1 #include <N76E003.H> 2 #include <SFR_Macro.h> //N76E003 SFR寄存器設置宏定義 3 #include <Function_define.h> //功能定義 4 #include "button.h" 5 #include "data.h" 6 7 /*---------------------------------------- 數據宏定義 ------------------------------------------*/ 8 9 /*---------------------------------------- 按鍵初始化 ------------------------------------------*/ 10 // 初始化按鍵 11 void Init_button(void){ 12 //button1 13 P1M1 |= (0x00 << button0_Num); // 設置爲1 14 P1M2 &= ~(0x01 << button0_Num); // 設置爲0 15 } 16 /*---------------------------------------- 功能模塊 ------------------------------------------*/ 17 // 獲取按鍵 18 void Button_Process(struct Button_data* Button,bit status){ 19 switch(Button->Button_State_machine_mode){ 20 case Button_status_S0:{ // 等待按鍵按下 21 if(Button_UP == status){ 22 Button->Button_status = Button_UP; // 按鍵狀態擡起 23 Button->Button_State_machine_mode = Button_status_S0; // 無操做 24 Button->Button_statusmode = Button_mode_NoOperation; // 按鍵無動做 25 DATA.Button0.Button_LiftTime = DATA.Button0.Button_LiftTime + 1; // 低狀態計數 26 } 27 else if(Button_DOWN == status){ // 按鍵按下 28 Button->Button_State_machine_mode = Button_status_S1; // 切換去抖模塊 29 Button->Button_PressTime = Button_TimeDebounce; // 設置去抖時間 30 } 31 }break; 32 case Button_status_S1:{ // 去抖驗證 33 if(Button->Button_PressTime){Button->Button_PressTime = Button->Button_PressTime - 1;} // 等待時間 34 else if(0 == Button->Button_PressTime){ // 去抖時間到 35 if(Button_UP == status){ 36 Button->Button_State_machine_mode = Button_status_S0; // 無操做 37 DATA.Button0.Button_LiftTime = 0; // 清空按鍵擡起計數 38 } 39 else if(Button_DOWN == status){ // 短按成立 40 Button->Button_status = Button_DOWN; // 按鍵按下 41 Button->Button_State_machine_mode = Button_status_S2; // 切換等待按鍵鬆開 42 Button->Button_PressTime = 0; // 清零按下時間 43 } 44 } 45 }break; 46 case Button_status_S2:{ // 按下時間(計算是否是長按) 47 if(Button_DOWN == status){ // 按鍵按下 48 // 計時 49 Button->Button_PressTime = Button->Button_PressTime + 1; // 按鍵計時 50 if(Button->Button_PressTime > Button_TimeEvenPressinterval){ 51 Button->Button_PressTime = Button_TimeEvenPressinterval; 52 } 53 } 54 else if (Button_UP == status){ // 按鍵鬆開 55 if(Button->Button_PressTime == Button_TimeEvenPressinterval){ 56 Button->Button_status = Button_UP; 57 Button->Button_State_machine_mode = Button_status_S0; 58 DATA.Button0.Button_LiftTime = 0; // 清空按鍵擡起計數 59 Button->Button_statusmode = Button_mode_longPress; // 長按 60 }else{ 61 Button->Button_State_machine_mode = Button_status_S3; // 短按 或 雙擊 62 } 63 Button->Button_LiftTime = 0; // 按鍵鬆開計時 64 } 65 }break; 66 case Button_status_S3:{ // 快安判斷(判斷是否是短按) 67 Button->Button_LiftTime = Button->Button_LiftTime + 1; //時間記錄 68 if(Button->Button_PressTime > Button_TimeShort_even){ // 大於快安值 69 Button->Button_status = Button_UP; 70 Button->Button_State_machine_mode = Button_status_S0; // 短按 71 DATA.Button0.Button_LiftTime = 0; // 清空按鍵擡起計數 72 Button->Button_statusmode = Button_mode_ShortPress; // 短按 73 }else{ 74 if(Button_DOWN == status){ // 按鍵按下 75 Button->Button_State_machine_mode = Button_status_S4; // 雙擊去抖 76 Button->Button_PressTime = Button_TimeDebounce; // 設置去抖時間 77 } 78 } 79 }break; 80 case Button_status_S4:{ // 雙擊去抖 81 Button->Button_LiftTime = Button->Button_LiftTime + 1; //時間記錄 82 if(Button->Button_PressTime){Button->Button_PressTime = Button->Button_PressTime - 1;} // 等待時間 83 else if(0 == Button->Button_PressTime){ // 去抖時間到 84 if(Button_UP == status){ // 去抖失敗 85 Button->Button_status = Button_UP; 86 Button->Button_State_machine_mode = Button_status_S0; // 短按 87 DATA.Button0.Button_LiftTime = 0; // 清空按鍵擡起計數 88 Button->Button_statusmode = Button_mode_ShortPress; // 短按 89 } 90 else if(Button_DOWN == status){ // 雙擊成立 91 Button->Button_status = Button_DOWN; // 按鍵按下 92 Button->Button_State_machine_mode = Button_status_S5; // 切換等待按鍵鬆開 93 } 94 } 95 }break; 96 case Button_status_S5:{ // 等待快安退出 97 if(Button_UP == status){ 98 Button->Button_status = Button_UP; 99 Button->Button_State_machine_mode = Button_status_S0; // 雙擊 100 DATA.Button0.Button_LiftTime = 0; // 清空按鍵擡起計數 101 Button->Button_statusmode = Button_mode_evenPress; // 雙擊 102 } 103 }break; 104 default:{ 105 Button->Button_State_machine_mode = Button_status_S0; 106 DATA.Button0.Button_LiftTime = 0; // 清空按鍵擡起計數 107 }break; // 有問題轉等待按鍵 108 } 109 // Button->Button_status = status; 110 } 111 /*---------------------------------------- 中斷調用模塊 ------------------------------------------*/ 112 // 批處理函數 113 void All_Buttonrefresh(void){ 114 Button_Process(&DATA.Button0,(bit)Git_button0); 115 }
工程文件:51內核按鍵狀態機.rario