单片机成长之路(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.h

 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.c

1 #include "data.h" 
2 
3 struct OS_DATA DATA;            // 系统数据

interrupt.h

 1 /*--------------------------------------------------------------------------
 2 interrupt.h
 3 --------------------------------------------------------------------------*/
 4 
 5 #ifndef __INTERRUPT_H__
 6 #define __INTERRUPT_H__
 7 
 8 /*----------------------------------------------------*/
 9 void InitMcu(void);
10 #endif

interrupt.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 #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.h

 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.c

  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内核按键状态机.rar

posted @ 2019-09-16 14:09  极客先锋  阅读(1504)  评论(0编辑  收藏  举报