首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

51单片机-按键

51单片机-按键

关键词: 51单片机 , 按键
矩阵按键:  
实现功能按一个键,相应的灯亮。  




  
左边的是普通二极管,右边的是发光二极管。左边的二极管如果想导通,则右边要比左边电平低。如果导通就是按键可以控制灯亮,那么按键左下的都为低电平,系统复位时默认I/O是高电平,所以给垂直方向的I/O拉低,这样如果按键按下,电路导通,那么垂直方向I/O的低电平会把水平方向的拉低。这样就可以通过检测水平方向哪个I/O为低电平来检测哪个键被按下。  

开始时对程序的错误想法:被按下的键两边肯定都是低电平,把它们存在一个数组里,然后检测。这样是不对的,用一个临时变量去存P0的值,不会有相同的,开始P0的值为oxff,这样即使按下按键,那么两边的引脚还是高电平,所以失败了。  
  


      #include <reg52.h>

sbit p2_0 = P2^0;
sbit p2_1 = P2^1;
sbit p2_2 = P2^2;
sbit p2_3 = P2^3;
sbit p2_4 = P2^4;
sbit p2_5 = P2^5;
sbit p2_6 = P2^6;
sbit p2_7 = P2^7;

sbit L0 = P0^0;
sbit L1 = P0^1;
sbit L2 = P0^2;
sbit L3 = P0^3;
sbit H0 = P0^4;
sbit H1 = P0^5;
sbit H2 = P0^6;
sbit H3 = P0^7;

void delay(){
        int i,j;
        for(i = 0; i < 0xff; i++)
                for(j = 0; j < 0xff; j++)
                        ;
}

void display(){
        P0 = 0xfe;                               //寻找按下的是哪个按键,先让垂直的为低电平,
        if(H0 == 0){p2_0 = 0; delay(); p2_0 = 1;} //然后通过检测水平的来确定,延时为了消抖
        if(H1 == 0){p2_1 = 0; delay(); p2_1 = 1;}
        if(H2 == 0){p2_2 = 0; delay(); p2_2 = 1;}
        if(H3 == 0){p2_3 = 0; delay(); p2_2 = 1;}
        P0 = 0xfd;
        if(H0 == 0){p2_4 = 0; delay(); p2_4 = 1;}
        if(H1 == 0){p2_5 = 0; delay(); p2_5 = 1;}
        if(H2 == 0){p2_6 = 0; delay(); p2_6 = 1;}
        if(H3 == 0){p2_7 = 0; delay(); p2_7 = 1;}
        P0 = 0xfb;
        if(H0 == 0){p2_0 = 0; delay(); p2_0 = 1;}
        if(H1 == 0){p2_1 = 0; delay(); p2_1 = 1;}
        if(H2 == 0){p2_2 = 0; delay(); p2_2 = 1;}
        if(H3 == 0){p2_3 = 0; delay(); p2_3 = 1;}
        P0 = 0xf7;
        if(H0 == 0){p2_4 = 0; delay(); p2_4 = 1;}
        if(H1 == 0){p2_5 = 0; delay(); p2_5 = 1;}
        if(H2 == 0){p2_6 = 0; delay(); p2_6 = 1;}
        if(H3 == 0){p2_7 = 0; delay(); p2_7 = 1;}

}

void main(){
        while(1){
                display();
        }        
}

  独立按键:

  实现功能,按一个独立按键时,一个灯亮,按另一个独立按键,另一个灯亮。图中的按键右下接地,

  左边通过跳线与P1.0和P1.1想接。如果按键按下,则P1.0和P1.1会被拉低。复位时默认I/O口都

  是高电平。这样可以通过检测P1.0和P1.1的电平,来检查按键是否被按下。单片机I/O口是准双向

  口,没有方法控制单片机的输入输出方向。相当于我们在每个口上都上拉了一个5V 10欧的电阻,这

  样单片机上电复位是高电平的。除了P0口都上拉了,P0内部没有上拉电阻,所以外部上拉。

  





  #include <reg52.h>

sbit key1 = P1^0;
sbit key2 = P1^1;
sbit led1 = P2^0;
sbit led2 = P2^1;

void delay(){
        int i,j;
        for(i = 0; i < 0xff; i++)
                for(j = 0; j < 0xff; j++)
                        ;        
}

void main(){
        while(1){
                if(key1 == 0){
                        delay();            //按键在闭合和断开时,触点处会出现抖动,消除抖动
                        if(key1 == 0)       //延时一段时间后如果还是低电平,说明不是抖动造成的,
                                led1 = "led1;  //确实是按键被按下了,实现灯亮灭
                }
                if(key2 == 0){
                        delay();
                        if(key2 == 0)
                                led2 = "led2;
                }
        }        
}


李万鹏


返回列表