您好,登錄后才能下訂單哦!
這篇文章主要介紹“如何使用單片機獨立按鍵輸入”,在日常操作中,相信很多人在如何使用單片機獨立按鍵輸入問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”如何使用單片機獨立按鍵輸入”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
在《 52單片機獨立按鍵輸入 》中,在主函數中通過循環掃描得到按鍵輸入,這種設計的缺點是整個過程CPU主進程一直被占用。為了改變這種情況,本次練習采用中斷機制改進獨立按鍵輸入的設計。使用中斷時,主函數不需要掃描按鍵輸入;當有按鍵按下時,通過與門首先向單片機發起中斷請求,通過中斷函數處理按鍵按下事件;當按鍵彈起時,外部電路向單片機發起另一個中斷請求,通過另一個中斷函數處理按鍵的彈起事件。
通過本練習,可以學習到:
與門電路的使用
中斷的使用
1. 電路設計
有按鍵按下時,對應引腳會被下拉為低電平。通過與門電路將這些電路連接起來,有任何一個引腳為低電平0時,與門都會輸出低電平0,該低電平正好用作按鍵按下事件的中斷源。按鍵按下和按鍵彈起是互斥事件,因此將按鍵按下的中斷源通過非門取非,即可用作按鍵彈起事件的中斷源。
細節:與門的檢索關鍵詞 AND,非門的檢索關鍵詞 NOT。
2. 程序設計
(1)中斷的啟用 主函數開始,設置啟用中外部斷。
// 啟用中斷 EA = 1; // 開中斷(總開關) EX0 = 1; // 允許外部中斷0中斷 IT0 = 1; // 下降沿觸發IT0=1。 // *下降沿觸發只觸發一次,低電平觸發則可能會反復觸發。 EX1 = 1; // 允許外部中斷1中斷 IT1 = 1; // 下降沿觸發IT1=1。 // 啟用中斷
(2)按鍵按下中斷函數 按鍵按下發起中斷后,臨時關閉中斷,檢測按鍵,檢測完成后重新開啟中斷。這種設計的目的是避免按鍵抖動引發多重中斷。
/** * @brief 按鍵按下時的中斷函數 * */ void onKeyDown() interrupt 0 { // 臨時關閉中斷 EA = 0; // 臨時關閉中斷 if (P1_0 == 0) { delayNms(10); // 消除抖動 if (P1_0 == 0) { displayNum(0); goto FUNCEND; } } if (P1_1 == 0) { delayNms(10); // 消除抖動 if (P1_1 == 0) { displayNum(1); goto FUNCEND; } } if (P1_2 == 0) { delayNms(10); // 消除抖動 if (P1_2 == 0) { displayNum(2); goto FUNCEND; } } if (P1_3 == 0) { delayNms(10); // 消除抖動 if (P1_3 == 0) { displayNum(3); goto FUNCEND; } } if (P1_4 == 0) { delayNms(10); // 消除抖動 if (P1_4 == 0) { displayNum(4); goto FUNCEND; } } if (P1_5 == 0) { delayNms(10); // 消除抖動 if (P1_5 == 0) { displayNum(5); goto FUNCEND; } } if (P1_6 == 0) { delayNms(10); // 消除抖動 if (P1_6 == 0) { displayNum(6); goto FUNCEND; } } if (P1_7 == 0) { delayNms(10); // 消除抖動 if (P1_7 == 0) { displayNum(7); goto FUNCEND; } } FUNCEND: // 重啟中斷 EA = 1; // 重啟中斷 }
(3)按鍵彈起中斷函數 按鍵彈起后,數碼管停止顯示。
/** * @brief 按鍵抬起時的中斷函數 * */ void onKeyUP() interrupt 2 { display4N(0x10, 0x10, 0x10, 0x10); }
1. 用到的全局變量的聲明。
// 全局變量 sbit P1_0 = P1 ^ 0; sbit P1_1 = P1 ^ 1; sbit P1_2 = P1 ^ 2; sbit P1_3 = P1 ^ 3; sbit P1_4 = P1 ^ 4; sbit P1_5 = P1 ^ 5; sbit P1_6 = P1 ^ 6; sbit P1_7 = P1 ^ 7; const unsigned char HexBCD[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E, 0x7F}; // 全局變量
2. 用到的其它函數。
/** * @brief 延時 ms 毫秒。 0 <= ms <= 65535 * **/ void delayNms(unsigned int ms) { unsigned int n = 124; while (ms) { while (n) n--; ms--; n = 124; } } /** * @brief 分別在4根數碼管上顯示數字。每個數字的范圍都是0-F。 * * @param n1 第一個數碼管上顯示的數字。 * @param n2 第二個數碼管上顯示的數字。 * @param n3 第三個數碼管上顯示的數字。 * @param n4 第四個數碼管上顯示的數字。 */ void display4N(UCHAR n1, UCHAR n2, UCHAR n3, UCHAR n4) { P2 = 0x01; // 選擇第一個數碼管 if (n1 >= 0 && n1 < 0x10) P0 = HexBCD[n1]; // 顯示n1 else P0 = 0xFF; delayNms(5); P2 = 0x02; // 選擇第二個數碼管 if (n2 >= 0 && n2 < 0x10) P0 = HexBCD[n2]; // 顯示n2 else P0 = 0xFF; delayNms(5); P2 = 0x04; // 選擇第三個數碼管 if (n3 >= 0 && n3 < 0x10) P0 = HexBCD[n3]; // 顯示n3 else P0 = 0xFF; delayNms(5); P2 = 0x08; // 選擇第四個數碼管 if (n4 >= 0 && n4 < 0x10) P0 = HexBCD[n4]; // 顯示n4 else P0 = 0xFF; delayNms(5); } /** * @brief 顯示給定的數n * * @param n 給定的數n */ void displayNum(int n) { UCHAR thousand; // 千位 UCHAR hundred; // 百位 UCHAR decade; // 十位 UCHAR ones; // 個位 thousand = n / 1000; hundred = (n % 1000) / 100; decade = (n % 100) / 10; ones = n % 10; if (n < 1000) // 若n小于1000, 則不顯示千位 thousand = 0xff; if (n < 100) // 若n小于100,, 則不顯示百位 hundred = 0xff; if (n < 10) // 若n小于10,, 則不顯示十位 decade = 0xff; display4N(thousand, hundred, decade, ones); }
到此,關于“如何使用單片機獨立按鍵輸入”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。