|
開博第一文。希望再次記錄學習的過程。 按鍵掃描,單片機里面再基礎不過的程序了。但對于初學者來說,用好按鍵也不是一件簡單的事情。在毛老師的介紹下,第一次知道了狀態機的思想也可以用于單片機的程序設計,感覺很是新奇。看了老師給發的幾個文檔后對狀態機編程的概念有了一些初步的認識,于是試著用狀態機的思想寫了一個實現單個按鍵長按短按的小程序。
貼個代碼試試....
//文件名:單個按鍵的復用
//作者: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 }
比較凌亂的說...
只是作為一個學習過程的記錄吧!沒什么技術含量。
|
評分
-
查看全部評分
|