|
發布時間: 2017-10-29 21:05
正文摘要:本帖最后由 ll13536121668 于 2017-11-2 17:32 編輯 4只獨立按鍵控制4只LED亮和滅,按下按鍵,LED亮,再按下,LED滅。因為我們很多都是按完按鍵,松開手LED才亮。 我現在是想一按按鍵,LED就亮或滅,這個又怎 ... |
dzbj 發表于 2017-11-2 15:53 這個程序什樣改才精準運行呢 樓主能夠修改程序粘貼上傳看看嗎謝謝 |
| 不用while等待按鍵松開 直接寫個死延時 用for 死等20ms然后看按鍵狀態 如果還是按下 就認為有效 然后執行led亮或滅 這樣就和你是否松開按鍵沒關系了 |
| C語言不會,匯編的話是在判斷按鍵有沒有放開,沒有放開就去執行亮燈程序,然后在回來判斷按鍵有沒有放開,放開就執行下一條程序。 |
|
//這個程序是按你的電路圖和元件編號重新改的,簡潔明了,有詳細注釋。沒有讀懂前不要改變電路和程序。 #include <reg52.h> #define uchar unsigned char #define uint unsigned int #define key (P1 & 0x0f) //按鍵端口宏定義(P1的低4位) //sbit key1=P1^3; //按鍵1定義 //sbit key2=P1^2; //按鍵2定義 //sbit key3=P1^1; //按鍵3定義 //sbit key4=P1^0; //按鍵4定義 sbit led1=P1^4; //led1端口 sbit led2=P1^5; //led2端口 sbit led3=P1^6; //led3端口 sbit led4=P1^7; //led4端口 void keyscan() //按鍵掃描程序 { static bit sign=0; //按鍵有效標志 static uint count=0; //消抖計數變量 uchar num=0; //臨時變量 if(key!=0x0f) //檢測有鍵按下 { count++; //消抖計數 if(count>=1000) //100~1000,根據主循環周期調整約10~20ms { count=1000; //防止溢出 if(sign==0) //測試按鍵有效標志0 { sign=1; //按鍵有效標志置1 num=key; //保存P1低4位值0000 xxxx ,x為0或1 switch(num) { case 0x0e: led4=~led4; break; case 0x0d: led3=~led3; break; case 0x0b: led2=~led2; break; case 0x07: led1=~led1; break; default: break; } } } } else //鍵抬起 { sign=0; //按鍵有效標志清0 count=0; //消抖計數清0 } } void main() { while(1) //程序循環執行 { keyscan(); //按鍵掃描,子函數 } } |
|
| 樓主在學習的過程中過于死板了,應靈活的去變通,可以用流程圖去分析! |
| 去單片機的書上找 |
|
有此一問,說明樓主并未真正掌握防止鍵彈動的原理,或者是學習太死板。 建議樓主好好回顧并弄清這個原理,再出手,估計你自己就能解決了。 想不通,可以語音問我。 畫出框圖,再寫程序,試試。 |
|
不用寫那么多,給你改了一下,你試試。 #include <reg52.h> //定義一下,方便使用 #define uchar unsigned char #define uint unsigned int //sbit key1=P2^4; //按鍵1定義 //sbit key2=P2^5; //按鍵2定義 //sbit key3=P2^6; //按鍵3定義 //sbit key4=P2^7; //按鍵4定義 sbit led1=P3^0; //led1端口 sbit led2=P3^1; //led2端口 sbit led3=P3^2; //led3端口 sbit led4=P3^3; //led4端口 void keyscan() //按鍵掃描程序 { static bit sign=0; //按鍵有效標志 static uint count=0; //消抖計數變量 uchar num=0; //臨時變量 if((P2&0xf0)!=0xf0) //檢測按鍵有效 { count++; //消抖計數 if(count>=500) //100~1000,根據主循環周期調整約10~20ms { count=500; if(sign==0) //測試按鍵有效標志0 { sign=1; //按鍵有效標志置1 num=(P2&0xf0); //保存P2高4位值xxxx 0000,x為0或1 switch(num) { case 0xe0: led1=~led1; break; case 0xd0: led2=~led2; break; case 0xb0: led3=~led3; break; case 0x70: led4=~led4; break; default: break; } } } } else //鍵抬起 { sign=0; //按鍵有效標志清0 count=0; //消抖計數清0 } } void main() { while(1) //程序循環執行 { keyscan(); //按鍵掃描,子函數 } } |
gb302 發表于 2017-10-29 22:12 可以俢改后截圖看看嗎 |
|
學習了新思路。在這我也分享一下我通常處理這種問題的方法: 1、如果只有亮滅兩種情況的話,可以考慮使用LED = ~LED; 2、如果情況大于三種以上,可以考慮求余方法,key_count % 3 == 0;key_count % 3 == 1;key_count % 3 == 2; |
gb302 發表于 2017-10-29 22:12 要什樣取反執行lled1-4 呢 |
| 很好,很好,很好啊。 |
|
uchar keyflag_1=0; //按鍵標志位 uchar keyflag_2=0; //按鍵標志位 uchar keyflag_3=0; //按鍵標志位 uchar keyflag_4=0; //按鍵標志位 這些變量定義的類型也有問題,第三次key_flag==3怎么執行? |
| 每次按鍵被識別后,執行lled1-4取反不就可以了嗎? |