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

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

成都创新互联成立与2013年,先为南涧等服务建站,南涧等地企业,进行企业商务咨询服务。为南涧企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。

一、原理

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

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


网站名称:如何使用单片机独立按键输入
本文URL:http://scyanting.com/article/ijeosh.html