千家信息网

如何使用单片机独立按键输入

发表于:2024-11-18 作者:千家信息网编辑
千家信息网最后更新 2024年11月18日,这篇文章主要介绍"如何使用单片机独立按键输入",在日常操作中,相信很多人在如何使用单片机独立按键输入问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"如何使用单片机独立按键
千家信息网最后更新 2024年11月18日如何使用单片机独立按键输入

这篇文章主要介绍"如何使用单片机独立按键输入",在日常操作中,相信很多人在如何使用单片机独立按键输入问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"如何使用单片机独立按键输入"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

一、原理

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

到此,关于"如何使用单片机独立按键输入"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

0