1,查詢法延時模式
u8 key0=1;u8 x=0;KEY=1;while(1){if(KEY==0) //"按鍵按下"{delay(10); //延時10msif(KEY==0 && kdy0==1) //按下有10ms 且上狀態是1。即下降沿時{key0=0; //將上狀態置0.防止按住不放時,重復執行按下程序語句。x++; //按下執行語句}key0=KEY; //彈起按鍵時將上一狀態置1.否則保持為0.}P0=~smgduan[x];}
10ms延時時,程序是阻塞停止的,以下程序就不會停止主程序,
2,查詢法不需要延時
u8 keyx=0xFF;u8 x=0;KEY=1;while(1){keyx = keyx<<1 | KEY; //左移并將KEY狀態寫入第0位,下一次執行時會被繼續左移if(keyx !=0) //8位沒有全部為0,即沒有8次檢測全為"按鍵按下"{key0=1; //上一狀態}else if(key0==1) //8次全0且上狀態是1。即下降沿時{key0=0; //將上狀態置0.防止按住不放時,重復執行按下程序語句。x++; //按下執行語句}P0=~smgduan[x];}
key0的作用是備份上一狀態,使按下按鍵產生"下降沿"作用。
每一次循環檢測一次,8次皆為0時確定為“按下”;如果整個程序很長,一次循環占用時間超過幾十毫秒,8次就是上百幾百毫秒了,這樣按下時間略快時就被認為是沒按下了。所以程序總時長不超過10ms時好用,超過就要這樣:
將按鍵檢測程序放在 一個2ms的定時器中斷函數中,程序每2ms 就會檢測一下按鍵的狀態。雖然這個檢測程序占用CPU時間,但不到0.03ms而已,0.03ms vs? 2ms,不到2%占用。
3,中斷法 非阻塞程序
void Int0() interrupt 0 //外部中斷0 必須用P3.2口
{delay(10); //與1例中都是有按下信號時延時10ms;區別是這里不需要主程序查詢而已。if(KEY==0) {x++; //執行語句}
}
因為3.2中斷輸入已設置為"下降沿觸發方式了",一直按下也不會再有中斷發生的。
非阻塞也是相對的,中斷也是延時了10ms.
總結:
中斷法最好,但占用一個外部中斷資源。