1.缺陷
上一講講解的“不支持連按”模式貼合了我們在生活中的實際應(yīng)用,雖然我們僅用“while(KEY4==0);”就把按鍵模式給切換了,不過這條語句嚴(yán)格來說是有缺陷的。
現(xiàn)在我們編寫的都是簡單的程序,如果后面還有更多更復(fù)雜的程序時,“while(KEY4==0);”就成為BUG了。
如果我們對按鍵按下不松手,那程序就一直在循環(huán)等待,不遇到高電平就不往下執(zhí)行代碼,如果這時有重要的程序要執(zhí)行,那豈不是因按鍵而耽誤。
還有我們再看下面這些代碼
while(1) { if(KEY4==0) { delay_ms(10);//等待抖動過去 if(KEY4==0) //二次判斷 { //這里執(zhí)行某些功能語句 } } }
即使我們不使用“while(KEY4==0);”,只要我們按鍵不松手,每次都要執(zhí)行“delay_ms(10);”,這樣的代碼稱不上高效率,我們只能再次完善代碼了。
2.改善
首先我們?yōu)榱俗尦绦蜃龅酵ㄓ眯裕覀兌x一個key_up為unsigned char類型的變量,而不是像宋老師那樣在《手把手教你學(xué)51單片機》文檔8.4.3節(jié)后面的文字內(nèi)容說到的利用bit類型的變量,畢竟bit類型只適合在51單片機,要是移植到其他單片機里就不適用了,所以我們不打算使用這種變量。
我們新定義的key_up變量是用來記錄此時按鍵IO端口的掃描值,進(jìn)一步分析,當(dāng)按鍵按下不松手時,
此時的key_up等于KEY4(也就是0),當(dāng)按鍵松手后,key_up就等于1了。
然后想進(jìn)入執(zhí)行功能語句時,先過了“if(key_up==0)”這一關(guān),因為我們一直讓key_up在死循環(huán)里存取KEY4的值,所以只要沒有按鍵動作,key_up一直等于1,這樣連進(jìn)入功能語句的第一關(guān)都沒有資格。
當(dāng)有按鍵按下時,key_up等于0了,進(jìn)入了第一關(guān),然后我們再設(shè)最后一關(guān),如果通過了最后一關(guān)就可以執(zhí)行功能語句了,最后一關(guān)是判斷“if(KEY4==1)”,也就是說如果按鍵沒松手,就無法執(zhí)行功能語句了。沒錯,我們這次的不支持連按模式是只有按鍵松手之后才去執(zhí)行的,上一講則是按下之后過了10ms就執(zhí)行代碼了。
3.代碼
#include <reg52.h> sbit ADDR2 = P1^2; sbit ADDR1 = P1^1; sbit ADDR0 = P1^0; sbit ENLED = P1^4; sbit ADDR3 = P1^3; sbit LED2 = P0^0; sbit KEY4 = P2^7; void delay_ms(unsigned int x) { unsigned int i,j; if(x==1000) { for(i=0;i<19601;i++)//延時1s { for(j=5;j>0;j--); } } else while(x--)for(j=115;j>0;j--); } void main() { unsigned char key_up=1;//定義記錄按鍵狀態(tài)值的變量,初始值為1避免程序一開始就進(jìn)入了“if(key_up==0)” unsigned char i=1; ADDR3 = 1;//使能三八譯碼器 ENLED = 0;// ADDR2 = 1;//************************** ADDR1 = 1;//讓三八譯碼器的IO6輸出低電平 ADDR0 = 0;//************************** P2 = 0xF7;//讓K4能具備有被拉低的條件先 P0 = 0xFE;//先點亮LED2 while(1) { if(key_up==0) { if(KEY4==1)//只要不松手,KEY4就會等于0,只有在按鍵抬起之后才執(zhí)行功能代碼 { P0=~(0x01<<i); i++; if(i>=8)i=0; } } key_up=KEY4; //如果不松手,key_up就會等于0 delay_ms(2); //假設(shè)這部分是要執(zhí)行的其他程序 } }
大家可以照著代碼分析一下,我們是不是已經(jīng)解決了上一講代碼的兩處缺陷。
C語言網(wǎng)提供由在職研發(fā)工程師或ACM藍(lán)橋杯競賽優(yōu)秀選手錄制的視頻教程,并配有習(xí)題和答疑,點擊了解:
一點編程也不會寫的:零基礎(chǔ)C語言學(xué)練課程
解決困擾你多年的C語言疑難雜癥特性的C語言進(jìn)階課程
從零到寫出一個爬蟲的Python編程課程
只會語法寫不出代碼?手把手帶你寫100個編程真題的編程百練課程
信息學(xué)奧賽或C++選手的 必學(xué)C++課程
藍(lán)橋杯ACM、信息學(xué)奧賽的必學(xué)課程:算法競賽課入門課程
手把手講解近五年真題的藍(lán)橋杯輔導(dǎo)課程