找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3900|回复: 2
打印 上一主题 下一主题
收起左侧

基于状态机的单个按键长按,短按实现复用

[复制链接]
跳转到指定楼层
楼主
ID:183476 发表于 2017-4-11 11:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
开博第一文。希望再次记录学习的过程。    键扫描,单片机里面再基础不过的程序了。但对于初学者来说,用好按键也不是一件简单的事情。在毛老师的介绍下,第一次知道了状态机的思想也可以用于单片机的程序设计,感觉很是新奇。看了老师给发的几个文档后对状态机编程的概念有了一些初步的认识,于是试着用状态机的思想写了一个实现单个按键长按短按的小程序。
   贴个代码试试....
  
//文件名:单个按键的复用
//作者:CWM
//修改日期:2011-06-15
//版本:V1.0
//功能描述:基于状态机的思想 实现单个按键的复用
//根据按键持续时间的不同,在数码管上分别显示0 1 2 3四个数字
001 #include <reg52.h>
002
003 #define key_state_0 0 //表示没有按下
004 #define key_state_1 1 //表示按键按下
005 #define key_state_2 2 //计时1
006 #define key_state_3 3 //计时2
007 #define key_state_4 4 //计时3
008 sbit KEY=P1^0;
009 sbit LED=P1^1;
010 unsigned char code LED7Code[] = {~0x3F,~0x06,~0x5B,~0x4F,
011 ~0x66,~0x6D,~0x7D,~0x07,~0x7F,~0x6F,
012 ~0x77,~0x7C,~0x39,~0x5E,~0x79,~0x71};//数码管码值表
013
014 int key_stime_counter,time_counter;//中断计时用
015 bit time_1s_ok,key_stime_ok; //时间标志
016
017 void system_Ini()
018 {
019     TMOD|= 0x00;
020     TH1=0x1c;//12.000M
021     TL1=0x18;//定时器1工作在方式0下 定时1ms   
022     IE = 0x8A;   
023     TR1  = 1;
024 }
025
026 char read_key()
027 {
028     static char key_state=0,key_time=0;
029     static char key_press,key_return=0;
030    
031     key_press=KEY;
032     switch(key_state)
033     {
034         case key_state_0://无按键按下
035             if(!key_press) key_state=key_state_1;
036             break;
037         case key_state_1: //有按键按下
038             if(!key_press)
039             {
040                 key_state=key_state_2;
041                 key_time=0;
042             }
043             else
044             {
045                 key_state=key_state_0;
046                 //key_return=0;
047             }
048             break;
049         case key_state_2://计时1
050             if(key_press)//按键松开
051             {
052                  key_state=key_state_0;
053             }
055             else if(++key_time>=10)
056             {
057                 key_state=key_state_3;//计时满一秒
058                 key_time=0;
059                 key_return=1;//输出1 数码管显示1
060             }
061             break;
062         case key_state_3://计时2
063             if(key_press) //按键松开
064             {
065                 key_state=key_state_2;//此时按键已经持续了一秒了 故数码管仍然显示1
066                 //key_return=1;
067             }   
068             else if(++key_time>=10)
069             {
070                 key_state=key_state_4;//此时已经按键持续超过2秒
071                 key_time=0;
072                 key_return=2;//数码管显示2
073             }
074             break;
075         case key_state_4:
076             if(key_press)
077             {
078                 key_state=key_state_3;//此时按键已经持续了二秒了 故数码管仍然显示2
079                 //key_return=2;
080             }   
081             else if(++key_time>=10)
082             {
083                 key_state=key_state_0;//按键松开
084                 key_time=0;
085                 key_return=3;//数码管显示3
086             }
087             break;
088     }
089     return key_return;
090 }
091
092
093 void main()
094 {
095     int result;
096     system_Ini();
097     while(1)
098     {
099         if(key_stime_ok)
100         {
101             key_stime_ok=0;
102             switch(read_key())
103             {
104                 case 0:
105                 P0 = LED7Code[0&0x7f;//无按键或者按键时间少于1s 显示0
106                 break;
107                 case 1:
108                 P0 = LED7Code[1&0x7f;//按键时间大于1s 显示1
109                 break;
110                 case 2:
111                 P0 = LED7Code[2&0x7f;//按键时间大于2s 显示2
112                 break;
113                 case 3:
114                 P0 = LED7Code[3&0x7f;//按键时间大于3s 显示3
115                 break;
116                 default:break;   
117             
118             }
119         }
120     }   
121
122 }
123
124 void Timer1(void) interrupt 3
125 {
126
127     TH1 = 0x1c;//12.000
128     TL1 = 0x18;
129     if(++key_stime_counter>=10)//到达10ms
130     {
131         key_stime_counter=0;
132         key_stime_ok=1;
133    
134     }
135 }

比较凌乱的说...
只是作为一个学习过程的记录吧!没什么技术含量。


评分

参与人数 1黑币 +5 收起 理由
botgs + 5 赞一个!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:4150 发表于 2017-7-29 10:58 | 只看该作者
谢谢楼主的分享
回复

使用道具 举报

板凳
ID:914666 发表于 2021-12-12 17:14 | 只看该作者
51hei有你更精彩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表