51单片机入门 - 按键驱动程序设计实验

微信公众号【电子开发圈】,理论结合实践,开启你的学习新方案!

电子DIY、Arduino、51单片机、STM32、FPGA……
电子百科、趣味知识、职业经验、设备拆机、科技头条……

点击链接,免费下载100G+电子设计学习资料!

http://mp.weixin.qq.com/mp/homepage?__biz=MzU3OTczMzk5Mg==&hid=7&sn=ad5d5d0f15df84f4a92ebf72f88d4ee8&scene=18#wechat_redirect

独立按键原理是这样的:按键没按下的时候,相应端口是高电平状态,而当按键按下的时候,相应的端口则是低电平。所以可以根据这个现象,实现相应的功能。

还有一点应该注意的是:按键在闭合和断开时,触点会存在抖动现象。

                                                    

在实际情况下,我们需要的是稳定闭合的那部分状态。所以可以采用延时的方法来解决这个问题,具体的过程就是先看看有没有键按下,有键按下了,再延迟一段时间,再看看有没有键按下,

这时候如果还是有键按下的话那就真的是有键按下了。

而这个抖动的时间大概是10ms,所以只要用一个延时10ms的子函数就行。

上面代码的第66行那个判断按键是否松开也是必要的,虽然在这个程序中有和没有区别不大,但是在有的程序中加入要求按键松开之后才出现什么现象之类的东西的话,那这部分就显得必要了。

/*******************************************************************************
实验名称:       8个独立按键控制8盏LED灯(按下哪个键,那个键对应的LED亮)
实验时间:        
*******************************************************************************/
#include <reg51.h>

#define LED_KEY P0   //LED灯用P0口
#define IO_KEY  P1     //独立按键用P1口

void Delay();        //延时函数
unsigned char Key_Scan();     //获取按键值

void main()
{
    unsigned char Key_Value, LED_Value;
    
    while(1)
    {
        Key_Value = Key_Scan();
        switch(Key_Value)
        {
            case(0xFE):         //K1按下
                LED_Value = 0x01;
                break;
            case(0xFD):         //K2按下
                LED_Value = 0x02;
                break;
            case(0xFB):         //K3按下
                LED_Value = 0x04;
                break;
            case(0xF7):         //K4按下
                LED_Value = 0x08;
                break;
            case(0xEF):         //K5按下
                LED_Value = 0x10;
                break;
            case(0xDF):         //K6按下
                LED_Value = 0x20;
                break;
            case(0xBF):         //K7按下
                LED_Value = 0x40;
                break;
            case(0x7F):         //K8按下
                LED_Value = 0x80;
                break;
            default:
                break;
        }
        
        LED_KEY = LED_Value;  //点亮相应LED        
    }
}

unsigned char Key_Scan()
{
    unsigned char Key_Value,i;

    if(IO_KEY != 0)
    {
        Delay();            //消除抖动

        if(IO_KEY != 0xFF)
        {
            Key_Value = IO_KEY;
            i = 0;
            if((i<50)&&(IO_KEY != 0xFF)) //判断按键是否松开
            {
                Delay();
                i++;    
            }
        }
    }
    return Key_Value;
}

void Delay()              //延迟10ms
{
    unsigned char a,b,c;

    for(c=1;c>0;c--)
    {
        for(b=38;b>0;b--)
        {
            for(a=130;a>0;a--)
            {};
        }
    }
}
/*******************************************************************************
*实验名称       :按键控制LED左右移
*实验时间              
*******************************************************************************/
#include <reg51.h>
#include <intrins.h>

//--定义要使用的IO口--//
sbit      K1 = P1^0;       //对应按钮K1
sbit     K2 = P1^1;        //对应按钮K2
#define  LED_KEY P0    //LED使用P0口

//--定义全局函数--//
void Delay10ms(unsigned int c);   //延时10ms
unsigned char Key_Scan();

/*******************************************************************************
* 函 数 名         : main
* 函数功能           : 主函数
*******************************************************************************/
void main(void)
{
    unsigned char ledValue, keyNum;

    ledValue = 0x01;

    while (1)
    {    
        keyNum = Key_Scan();  //扫描键盘

        if (keyNum == 1)      //如果键值返回1
        {
            ledValue = _crol_(ledValue, 1);    //左循环
        }
        else if (keyNum == 2)
        {
            ledValue = _cror_(ledValue, 1);    //右循环
        }

        LED_KEY = ledValue;  //点亮LED灯
    }                
}

/*******************************************************************************
* 函 数 名                     : Key_Scan()
* 函数功能                       : 扫描键盘
*******************************************************************************/

unsigned char Key_Scan()
{
    unsigned char keyValue = 0 , i; //保存键值

    //--检测按键1--//
    if (K1==0)        //检测按键K1是否按下
    {
        Delay10ms(1);    //消除抖动

        if (K1==0)    //再次检测按键是否按下
        {
            keyValue = 1;
            i = 0;
            while ((i<50) && (K1==0))     //检测按键是否松开
            {
                Delay10ms(1);
                i++;
            }
        }
    }

    //--检测按键2--//
    if (K2==0)        //检测按键K1是否按下
    {
        Delay10ms(1);    //消除抖动

        if (K2==0)    //再次检测按键是否按下
        {
            keyValue = 2;
            i = 0;
            while ((i<50) && (K2==0))     //检测按键是否松开
            {
                Delay10ms(1);
                i++;
            }
        }
    }

    return keyValue;   //将读取到键值的值返回
}

/*******************************************************************************
* 函 数 名                     : Delay10ms
* 函数功能                     : 延时函数,延时10ms
*******************************************************************************/

void Delay10ms(unsigned int c)   //误差 0us
{
    unsigned char a, b;

    //--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
    for (;c>0;c--)
    {
        for (b=38;b>0;b--)
        {
            for (a=130;a>0;a--);
        }
           
    }       
}

猜你喜欢

转载自blog.csdn.net/weixin_42625444/article/details/93001333