MCU 51-4 独立按键&编码按键

独立按键:

按键的按下与释放是通过机械触点的闭合与断开来实现的,因机械触点的弹性作用,在闭合与断开的瞬间均有一个抖动的过程,抖动必须清除。

按键按下一次,数码管数值加1:

#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit we = P2^7;    //数码管位选
sbit du = P2^6;    //数码管段选
sbit key_s2 = P3^0;//S2按键位定义
uchar code leddata[]={ 
 
                0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F,  //"9"
                0x77,  //"A"
                0x7C,  //"B"
                0x39,  //"C"
                0x5E,  //"D"
                0x79,  //"E"
                0x71,  //"F"
                0x76,  //"H"
                0x38,  //"L"
                0x37,  //"n"
                0x3E,  //"u"
                0x73,  //"P"
                0x5C,  //"o"
                0x40,  //"-"
                0x00,  //熄灭
                0x00  //自定义
 
                         };

void delay(uint z)
{
    uint x,y;
    for(x = z; x > 0; x--)
        for(y = 114; y > 0 ; y--);
}

void main()
{
    uchar num;
    we = 1;
    P0 = 0xfe; //选通第一个数码管
    we = 0;
    while(1)
    {
        du = 1;
        P0 = leddata[num]; //显示S2按下次数
        du = 0;
        if(key_s2 == 0)//判断S2是否按键
        {
            delay(5);//软件延时
            if(key_s2 == 0)
            {
                num++; //计数加1
            }
            while(!key_s2);    //松手检测
        }
        if(num == 10) //当数值为超过9时归零
        {
            num = 0;
        }    
    }
}

用定时器0定时间隔1秒数码管静态循环显示0 - 9。按独立键盘的S2按键时开始循环显示,按S3按键时暂停,按S4按键时点亮P1口所有LED灯,按S5按键时关闭P1口所有LED灯。

#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit we = P2^7;
sbit du = P2^6;

sbit key_s2 = P3^0;
sbit key_s3 = P3^1;
sbit key_s4 = P3^2;
sbit key_s5 = P3^3;

uchar code leddata[]={ 
 
                0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F,  //"9"
                0x77,  //"A"
                0x7C,  //"B"
                0x39,  //"C"
                0x5E,  //"D"
                0x79,  //"E"
                0x71,  //"F"
                0x76,  //"H"
                0x38,  //"L"
                0x37,  //"n"
                0x3E,  //"u"
                0x73,  //"P"
                0x5C,  //"o"
                0x40,  //"-"
                0x00,  //熄灭
                0x00  //自定义
 
                         };

void delay(uint z)
{
    uint x,y;
    for(x = z; x > 0; x--)
        for(y = 114; y > 0 ; y--);
}

void main()
{
    uchar i;//计数有多少个50毫秒产生
    uchar num;//计数
    TMOD = 0x01;//定时器0 做定时 模式1 16位计数器
    TH0 = (0xffff - 50000) / 0xff;
    TL0 = (0xffff - 50000) % 0xff;//定时50ms
    we = 1;
    P0 = 0xfe; //选通第一位数码管
    we = 0;
    while(1)
    {
        if(TF0 == 1) //判断50ms是否到
        {
            TH0 = (0xffff - 50000) / 0xff;
            TL0 = (0xffff - 50000) % 0xff;//定时50ms
            TF0 = 0;//清除溢出标志位
            i++;
        }
        if(i == 20)//判断是否到了1秒
        {
            i = 0;//清零秒计数
            num++;//计数值加1    
        }
        if(num == 10)//当计数值为10时归零
        {
            num = 0;
        }
        du = 1;
        P0 = leddata[num]; //数码管实时显示计数值
        du = 0;
        if(key_s2 == 0)    //判断是否按下S2
        {
            delay(5);  //软件消抖
            if(key_s2 == 0)//再次判断是否按下S2
            {
                TR0 = 1;//启动定时器0    
            }
            while(!key_s2);//松手检测
        }
        if(key_s3 == 0)    //判断S3是否被按下
        {
            delay(5);//软件消抖
            if(key_s3 == 0)//再次判断S3是否被按下
            {
                TR0 = 0;//停止定时器0
            }
            while(!key_s3);//松手检测
        }
        if(key_s4 == 0)    //判断S4是否被按下
        {
            delay(5); //软件消抖
            if(key_s4 == 0)    //再次判断S4是否被按下
            {
                P1 = 0;//点亮P1口所有LED灯
            }
            while(!key_s4);//松手检测
        }
        if(key_s5 == 0)//判断S5是否被按下
        {
            delay(5); //软件消抖
            if(key_s5 == 0)    //再次判断S5是否被按下
            {
                P1 = 0xff;//关闭P1口所有LED灯
            }
            while(!key_s5);    //松手检测
        }
    }
}

矩形按键模块:

 矩形键盘:

#include <reg52.h>
#define uchar unsigned char
#define uint  unsigned int
sbit we = P2^7;
sbit du = P2^6;
uchar code leddata[]={ 
 
                0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F,  //"9"
                0x77,  //"A"
                0x7C,  //"B"
                0x39,  //"C"
                0x5E,  //"D"
                0x79,  //"E"
                0x71,  //"F"
                0x76,  //"H"
                0x38,  //"L"
                0x37,  //"n"
                0x3E,  //"u"
                0x73,  //"P"
                0x5C,  //"o"
                0x40,  //"-"
                0x00,  //熄灭
                0x00  //自定义
 
                         };
void delay(uint z)
{
    uint x,y;
    for(x = z; x > 0; x--)
        for(y = 114; y > 0 ; y--);
}


uchar KeyScan()    //带返回值的子函数
{
    uchar cord_l,cord_h;//声明列线和行线的值的储存变量
    P3 = 0xf0;//1111 0000  p3.7 ... p3.0
    if( (P3 & 0xf0) != 0xf0)//判断是否有按键按下
    {
        delay(5);//软件消抖
        if( (P3 & 0xf0) != 0xf0)//判断是否有按键按下
        {
              cord_l = P3 & 0xf0;// 储存列线值
              P3 = cord_l | 0x0f; //将行输出变为1111,此时按键仍处于按下,所以行值会变化,下一步进行存储行值
              cord_h = P3 & 0x0f;// 储存行线值
              while( (P3 & 0x0f) != 0x0f );//松手检测
              return (cord_l + cord_h);//返回键值码
        }    
    }
        
}

void KeyPro()
{
    switch( KeyScan() )
    {
         //第一行键值码
        case 0xee: P0 = leddata[0];        break;
        case 0xde: P0 = leddata[1];        break;
        case 0xbe: P0 = leddata[2];        break;
        case 0x7e: P0 = leddata[3];        break;
        
        //第二行键值码
        case 0xed: P0 = leddata[4];        break;
        case 0xdd: P0 = leddata[5];        break;
        case 0xbd: P0 = leddata[6];        break;
        case 0x7d: P0 = leddata[7];        break;

        //第三行键值码
        case 0xeb: P0 = leddata[8];        break;
        case 0xdb: P0 = leddata[9];        break;
        case 0xbb: P0 = leddata[10];    break;
        case 0x7b: P0 = leddata[11];    break;

        //第四行键值码
        case 0xe7: P0 = leddata[12];    break;
        case 0xd7: P0 = leddata[13];    break;
        case 0xb7: P0 = leddata[14];    break;
        case 0x77: P0 = leddata[15];    break;
    }    
}

void main()
{
    we = 1;//打开位选
    P0 = 0;//八位数码管全显示
    we = 0;//锁存位选

    du = 1;//打开段选端
    P0 = leddata[22];
    while(1)
    {
         KeyPro();//提取键值码并且送不同数值给数码管显示
    }
}
原文地址:https://www.cnblogs.com/darren-pty/p/13284233.html