|
開博第一文。希望再次記錄學(xué)習(xí)的過程。 按鍵掃描,單片機(jī)里面再基礎(chǔ)不過的程序了。但對于初學(xué)者來說,用好按鍵也不是一件簡單的事情。在毛老師的介紹下,第一次知道了狀態(tài)機(jī)的思想也可以用于單片機(jī)的程序設(shè)計(jì),感覺很是新奇。看了老師給發(fā)的幾個(gè)文檔后對狀態(tài)機(jī)編程的概念有了一些初步的認(rèn)識(shí),于是試著用狀態(tài)機(jī)的思想寫了一個(gè)實(shí)現(xiàn)單個(gè)按鍵長按短按的小程序。
貼個(gè)代碼試試....
//文件名:單個(gè)按鍵的復(fù)用
//作者:CWM
//修改日期:2011-06-15
//版本:V1.0
//功能描述:基于狀態(tài)機(jī)的思想 實(shí)現(xiàn)單個(gè)按鍵的復(fù)用
//根據(jù)按鍵持續(xù)時(shí)間的不同,在數(shù)碼管上分別顯示0 1 2 3四個(gè)數(shù)字
001 #include <reg52.h>
002
003 #define key_state_0 0 //表示沒有按下
004 #define key_state_1 1 //表示按鍵按下
005 #define key_state_2 2 //計(jì)時(shí)1
006 #define key_state_3 3 //計(jì)時(shí)2
007 #define key_state_4 4 //計(jì)時(shí)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};//數(shù)碼管碼值表
013
014 int key_stime_counter,time_counter;//中斷計(jì)時(shí)用
015 bit time_1s_ok,key_stime_ok; //時(shí)間標(biāo)志
016
017 void system_Ini()
018 {
019 TMOD|= 0x00;
020 TH1=0x1c;//12.000M
021 TL1=0x18;//定時(shí)器1工作在方式0下 定時(shí)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://計(jì)時(shí)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;//計(jì)時(shí)滿一秒
058 key_time=0;
059 key_return=1;//輸出1 數(shù)碼管顯示1
060 }
061 break;
062 case key_state_3://計(jì)時(shí)2
063 if(key_press) //按鍵松開
064 {
065 key_state=key_state_2;//此時(shí)按鍵已經(jīng)持續(xù)了一秒了 故數(shù)碼管仍然顯示1
066 //key_return=1;
067 }
068 else if(++key_time>=10)
069 {
070 key_state=key_state_4;//此時(shí)已經(jīng)按鍵持續(xù)超過2秒
071 key_time=0;
072 key_return=2;//數(shù)碼管顯示2
073 }
074 break;
075 case key_state_4:
076 if(key_press)
077 {
078 key_state=key_state_3;//此時(shí)按鍵已經(jīng)持續(xù)了二秒了 故數(shù)碼管仍然顯示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;//數(shù)碼管顯示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;//無按鍵或者按鍵時(shí)間少于1s 顯示0
106 break;
107 case 1:
108 P0 = LED7Code[1&0x7f;//按鍵時(shí)間大于1s 顯示1
109 break;
110 case 2:
111 P0 = LED7Code[2&0x7f;//按鍵時(shí)間大于2s 顯示2
112 break;
113 case 3:
114 P0 = LED7Code[3&0x7f;//按鍵時(shí)間大于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)//到達(dá)10ms
130 {
131 key_stime_counter=0;
132 key_stime_ok=1;
133
134 }
135 }
比較凌亂的說...
只是作為一個(gè)學(xué)習(xí)過程的記錄吧!沒什么技術(shù)含量。
|
評(píng)分
-
查看全部評(píng)分
|