91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用單片機獨立按鍵輸入

發布時間:2021-10-14 13:44:14 來源:億速云 閱讀:184 作者:iii 欄目:編程語言

這篇文章主要介紹“如何使用單片機獨立按鍵輸入”,在日常操作中,相信很多人在如何使用單片機獨立按鍵輸入問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”如何使用單片機獨立按鍵輸入”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

一、原理

在《 52單片機獨立按鍵輸入 》中,在主函數中通過循環掃描得到按鍵輸入,這種設計的缺點是整個過程CPU主進程一直被占用。為了改變這種情況,本次練習采用中斷機制改進獨立按鍵輸入的設計。使用中斷時,主函數不需要掃描按鍵輸入;當有按鍵按下時,通過與門首先向單片機發起中斷請求,通過中斷函數處理按鍵按下事件;當按鍵彈起時,外部電路向單片機發起另一個中斷請求,通過另一個中斷函數處理按鍵的彈起事件。

如何使用單片機獨立按鍵輸入

通過本練習,可以學習到:

  1. 與門電路的使用

  2. 中斷的使用

二、方法步驟

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);
}

到此,關于“如何使用單片機獨立按鍵輸入”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

杭锦后旗| 县级市| 孟村| 弥渡县| 渑池县| 宣威市| 金秀| 东城区| 砀山县| 兴文县| 长寿区| 衡山县| 左云县| 曲阳县| 塔城市| 乐山市| 漳州市| 盐津县| 长垣县| 临夏市| 白玉县| 兴隆县| 宿松县| 宜宾市| 大竹县| 大宁县| 陵川县| 芜湖市| 安阳县| 随州市| 黔南| 固阳县| 镇巴县| 广宗县| 尚志市| 罗江县| 江口县| 高青县| 虞城县| 十堰市| 乌兰察布市|