單片機成長之路(51基礎篇)- 024 基於 N76E003 的按鍵按鍵狀態機

  前端時間要用按鍵,搞了個狀態機(如圖):前端

 

 

 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

相關文章
相關標籤/搜索