精华内容
下载资源
问答
  • 以金沙滩工作室的STC89C52单片机开发板为例,记录学习51单片机的笔记,本文章主要讲解了4×4矩阵按键扫描,教材是金沙滩工作室(www.kingst.org )宋雪松老师编著的《手把手教你学51单片机-C语言版》,所用的...

    以金沙滩工作室的STC89C52单片机开发板为例,记录学习51单片机的笔记,本文章主要讲解了4×4矩阵按键的扫描,教材是金沙滩工作室(www.kingst.org )宋雪松老师编著的《手把手教你学51单片机-C语言版》,所用的开发板是教材配套开发板。在这里推荐一下宋老师的这套教材,感觉还是蛮不错的。下面是该文章的目录:

    1.矩阵按键及其原理

    2.矩阵按键的消抖

    1.矩阵按键及其原理

    图1是单片机开发板上的矩阵按键的实物图,图2是矩阵按键的电路原理图。以4×4矩阵按键为例,总共包含了16个按键,包括数字0~9、四个方向键(上下左右)、ESC键和回车键,当然在使用过程中可以定义这些按键为其他功能,灵活多变。

    95b37785ca79cc1b611ecd9c06700567.png
    图2 4×4矩阵按键的电路图

    16个按键占用P2的8个IO口,见上图2,KeyOut1~KeyOut4为输出引脚,KeyIn1~KeyIn4为读取引脚。KeyOut1~KeyOut4均输出高电平时,由于全部KeyIn引脚最上面与+5V接通,故无论某个按键是否按下,KeyIn1~KeyIn4读取到的均为高电平(逻辑1),无法判断是否有按键按下/弹起,当其中的某个KeyOut引脚输出低电平(逻辑0)时,按下该行的某个按键,那么这个按键对应的keyIn引脚将读取到低电平,从而可以在程序中判断某个按键是否被按下。

    例如,现在使KeyOut3引脚为0,其余KeyOut引脚为1,那么当按键K12按下时,KeyIn4引脚直接与KeyOut3引脚连通,将其电平拉低,P2.7就可以读取到0,那么就可以判断K12(右键)被按下了。

    2.矩阵按键的消抖和扫描

    由于按键的机械特性,按键存在“抖动”的情况,比如,当按下某个键的瞬间,这个键可能还会来回抖动几次,当然这种抖动是手指感觉不出来的,但它确实会影响读取到的电平的高低,相反,按键弹起的瞬间,也会存在抖动的情况。如图3,按键抖动通常只持续不到10ms,按下到弹起的整个过程通常持续100ms以上,所以需要进行消抖处理。

    e34b2782648ccb545d2c5e107f315cdd.png
    图3 按键的抖动

    在这里,按键消抖的思路定义一个4X4的二维数组 keybuf[4][4]和keysta[4][4]

    unsigned char keybuff[4][4] = {
    	{0xFF, 0xFF, 0xFF, 0xFF}, 
    	{0xFF, 0xFF, 0xFF, 0xFF}, 
    	{0xFF, 0xFF, 0xFF, 0xFF}, 
    	{0xFF, 0xFF, 0xFF, 0xFF}
    }; //定义在中断函数内
    
    unsigned char KeySta[4][4] = {
    	{1, 1, 1, 1},
    	{1, 1, 1, 1},
    	{1, 1, 1, 1},
    	{1, 1, 1, 1},
    }; //定义为全局变量

    keybuf[4][4]中每一个元素代表了对应按键在某个瞬间的状态,初始化为0xFF(0b11111111),就意味着开始每个按键均为弹起状态。

    设置定时/计数器T0的定时时长为1ms,每次中断,就选中keybuff其中一行,依次将该行的四个元素左移一位,并将对应的KeyInx(x = 1, 2, 3, 4)的值写入数组元素的最低位,如此就需要4ms完成四行按键的扫描,但是,通常抖动的时间在10ms左右,那么干脆就在16ms内判断某个按键是否被稳定的按下或者弹起,若在16ms中读取到的某个按键的状态均为0或者1,那么就可以判断这个按键已经被稳定地按下或者弹起了,这时,就将存储按键状态的二维数组KeySta[4][4]中对应的按键的状态置为0或者1。

    下面是部分示例代码(定义KeyScan函数专门用于按键的扫描,它在T0的中断函数内被调用)。

    #include<reg52.h>
    
    sbit KeyOut4 = P2^0;
    sbit KeyOut3 = P2^1;
    sbit KeyOut2 = P2^2;
    sbit KeyOut1 = P2^3;
    sbit KeyIn1 = P2^4;
    sbit KeyIn2 = P2^5;
    sbit KeyIn3 = P2^6;
    sbit KeyIn4 = P2^7;
    
    unsigned char KeySta[4][4] = {
         {1, 1, 1, 1},
         {1, 1, 1, 1}, 
         {1, 1, 1, 1}, 
         {1, 1, 1, 1}
     };
    unsigned char code KeyCodeMap[4][4] = {
    	{ 0x31, 0x32, 0x33, 0x26 }, //数字键 1、数字键 2、数字键 3、向上键
        { 0x34, 0x35, 0x36, 0x25 }, //数字键 4、数字键 5、数字键 6、向左键
        { 0x37, 0x38, 0x39, 0x28 }, //数字键 7、数字键 8、数字键 9、向下键
        { 0x30, 0x1B, 0x0D, 0x27 } //数字键 0、ESC 键、 回车键、 向右键;
    };
    
    void KeyScan()
    {
    	static unsigned char KeyBuff[4][4] = {
    		{0xFF, 0xFF, 0xFF, 0xFF}, 
    	    {0xFF, 0xFF, 0xFF, 0xFF}, 
    	    {0xFF, 0xFF, 0xFF, 0xFF}, 
    	    {0xFF, 0xFF, 0xFF, 0xFF}
    	};
    	static unsigned char row = 0;
    	unsigned char col;
    	KeyBuff[row][0] = (KeyBuff[row][0] << 1) | KeyIn1;
    	KeyBuff[row][1] = (KeyBuff[row][1] << 1) | KeyIn2;
    	KeyBuff[row][2] = (KeyBuff[row][2] << 1) | KeyIn3;
    	KeyBuff[row][3] = (KeyBuff[row][3] << 1) | KeyIn4;
    	for (col = 0; col < 4; col++)
    	{
    		if ((KeyBuff[row][col]) & 0x0F == 0x0F)
    		{
    			KeySta[row][col] = 1;
    		}
    		else if ((KeyBuff[row][col] & 0x0F) == 0x00)
    		{
    			KeySta[row][col] = 0;
    		}
    	}
    	row++;
    	row  = row & 0x03;
    	switch (row)
    	{
    		case 0: KeyOut4 = 1; KeyOut1 = 0; break;
    		case 1: KeyOut1 = 1; KeyOut2 = 0; break;
    		case 2: KeyOut2 = 1; KeyOut3 = 0; break;
    		case 3: KeyOut3 = 1; KeyOut4 = 0; break;
    		default: break;
    	}
    }
    展开全文
  • 独立按键实验 按键是一种电子开关,使用时轻轻按开关按钮就可使开关接通,当松开手时, 开关断开。我们开发板上使用的按键及内部简易图如下图所示 管脚与管脚之间(注意是距离)距离长的是导通状态,短的是接通状态。...

    独立按键实验

    按键是一种电子开关,使用时轻轻按开关按钮就可使开关接通,当松开手时, 开关断开。我们开发板上使用的按键及内部简易图如下图所示

    17ef1c275ecdf95e43b946f1073d8caa.png

    管脚与管脚之间(注意是距离)距离长的是导通状态,短的是接通状态。 通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,电压信号 如下图所示:

    16cb70e59c954f8b27b1f48f7f4583ee.png

    如图所示,按键闭合式不会立刻稳定的接通,断开时也不会一下子断开,会伴随一些抖动。抖动的时间长短有按键特性决定,一般为5Ms到10ms.按键抖动会引起按键被误读多次。为了确保 CPU 对按键的一次闭合仅作一次处理,必须进行消抖

    • 消抖 消抖可分为硬件消抖和软件消抖。为了使电路更加简单,通常采用软件消抖。 一般来说一个简单的按键消抖就是先读取按键的状态, 如果得到按键按下之后, 延时 10ms, 再次读取按键的状态,如果按键还是按下状态,那么说明按键已经按下。 其中延时 10ms 就是软件消抖处理。 消抖过程(软件) 1,先设置 IO 口为高电平(由于开发板 IO 都有上拉电阻,所以默认 IO 为高电平)。 2,读取 IO 口电平确认是否有按键按下。 3,如有 IO 电平为低电平后,延时几个毫秒。 4,再读取该 IO 电平,如果任然为低电平,说明对应按键按下。 5,执行相应按键的程序。
    • 键盘 键盘分为编码键盘和非编码键盘。键盘上闭合键的识别由专用的硬件编码器实现,并产生键编码号或键值的称为编码键盘,如计算机键盘。而靠软件编程来识别的键盘称为非编码键盘,在单片机组成的各种系统中,用的较多的是非编码键盘。非编码键盘又分为独立键盘和行列式键盘(常说的矩阵键盘)。独立按键用的就是独立键盘。
    • 实现原理 原理图:

    12523516da8e4e5d7ebdb568b0980694.png

    独立按键电路构成是由各个按键的一个管脚连接在一起接地,按键其他引脚分别接到单片机 IO 口。 单片机的 IO 口既可作为输出也可作为输入使用,当检测按键时用的是它的输入功能,独立按键的一端接地,另一端与单片机的某个 I/O 口相连,开始时先给该 IO 口赋一高电平,然后让单片机不断地检测该 I/O 口是否变为低电平,当按键闭合时,即相当于该 I/O 口通过按键与地相连,变成低电平,程序一旦检测到 I/O 口变为低电平则说明按键被按下,然后执行相应的指令。

    e964b91172f5474946ce39f29549c7c9.png

    由图可以看出,单片机的管脚(p1,p3,等管脚)都接有上拉电阻,上拉电阻接高电平。因此我们在消抖检测时,若按键以已经按下,则管脚接地,变为低电平,若管脚为低电平,则说明按键已经按下,执行LED灯点亮的步骤。

    • 代码实现
    #include <reg52.h>
    #include <intrins.h>
    typedef unsigned char u8; //重定义全局字符型变量
    typedef unsigned int u16; //重定义全局整型变量
    sbit LED=P2^0 ;  //LED接P2口
    sbit K1=P3^1; //按键k1接p3口,也可以是其他管脚
    
    /*延时函数*/
    void dealy(u16 i)
    {
    while(i--);
    }
    
    /*独立按键执行函数
    */
    void KeyProcess()
    {  
       if(K1==0){
         dealy(1000);
             //一个int型的所占的时间大约为10微妙,所以乘1000大约为10ms.
             if(K1==0){  //消抖后仍为低电平,则执行点亮进程
              LED=~LED;    //为了让LED产生明暗变化
             }
             while(!K1);  //判断按键是否松开,假如松开,则K1为真,加!为假,则循环结束跳出循环
       }
       
    }
    
    void main()
    { 
      LED=0;  //初始时灯位熄灭状态(LED原理),
      while(1)
      {
            KeyProcess();
      }      
    }
     

    矩阵按键实验

    • 前面我们讲到独立按键,接下来我们引入独立按键。为什么引入矩阵按键?
      独立键盘与单片机连接时,每一个按键都需要单片机的一个 I/O 口,若某单片机系统需较多按键,如果用独立按键便会占用过多的 I/O 口资源。单片机系统中 I/O 口资源往往比较宝贵,多个按键时为了减少 I/O 口引脚。
    • 4 * 4键盘的工作原理
      矩阵按键原理图

    6c2cad51cfa3be07e9c9b70a1a9fa429.png

    开发板上将 16 个按
    键排成 4 行 4 列,第一行将每个按键的一端连接在一起构成行线,第一列将每
    个按键的另一端连接在一起构成列线,这样便一共有 4 行 4 列共 8 根线,我们将
    这 8 根线连接到单片机的 8 个 I/O 口上,通过程序扫描键盘就可检测 16 个
    键。

    • 矩阵按键的消抖
      1.检查按键是否按下

    e964b91172f5474946ce39f29549c7c9.png


    由原理图可知,独立按键和矩阵按键是有所不同的。独立按键的各个按键一端接引脚,一端并联在一起接地。所以检测按键是否按下只需要看单片机的管脚是否为低电平即可。而矩阵按键,他们的两端分别并联在一起,
    每一行(共4行)并联在一起接高位管脚上(7~4),每一列(共4列)并联在一起接到低位管脚上(3~0)。
    所以检测方法有所不同。
    一般情况下有两种方法。
    方法一:
    逐行扫描:我们可以通过高四位轮流输出低电平来对矩阵键盘进行逐行扫描,当低四位接收到的数据不全为1的时候,说明有按键按下,然后通过接收到的数据是哪一位为0来判断是哪一个按键被按下。逐行扫描的时间是非常快的,肉眼难以观察。
    举个例子,假设此时p7管脚为低电平,那么第一行按键的一段都为低电平,另一端分别连接低4位的管脚,只有当某一个开关按下,低4位的管脚与其中一个低电平的管脚连接变为低电平,所以只要查看低4位那个管脚为低电平就可以确定那个按键以按下。其他三行同理,每一行依次不断进行。
    方法二:
    行列扫描:我们可以通过高四位全部输出低电平,低四位输出高电平。当接收到的数据,低四位不全为高电平时,说明有按键按下,然后通过接收的数据值,判断是哪一列有按键按下,然后再反过来,高四位输出高电平,低四位输出低电平,然后根据接收到的高四位的值判断是那一行有按键按下,这样就能够确定是哪一个按键按下了。相当于第一次确定列,第二次确定行,行列交叉形成点,这个点就是我们要找的已经闭合的按键。

    • 静态数码管显示按键

    5051d5b9a0e709145baa61098b08728e.png


    如图,每一个按键可用一个键值来代替,让对应的键值号来作为静态数码管的段选,从而实现按下按键显示数字的效果。

    • 代码实现
      采用第二种行列扫描的检测方法
    #include <reg52.h>                         //此文件中定义了单片机的一些特殊功能寄存器
    
    typedef unsigned int u16;         //对数据类型进行声明定义
    typedef unsigned char u8;
    
    #define GPIO_DIG P0        //宏定义p0口(静态显示数码管对应的管脚)
    #define GPIO_KEY P1       //矩阵按键对应管脚
    
    
    u8 KeyValue;    //用来存放读取到的键值
    
    
    u8 code smgduan[17]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
                                            0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//显示0~F的值
    
    /*延时·函数*/
    void delay(u16 i)
    {
            while(i--);     
    }
    
    /*检测按键是否按下,消抖,读取键值*/
    void KeyDown(void)
    {
            char a=0;
            GPIO_KEY=0x0f;    
            //0x0f转化为为二进制为0000 1111,即矩阵按键的八个管脚,高位为低电平(0),低位为高电平(1)
            if(GPIO_KEY!=0x0f)//读取按键是否按下
            {
                    delay(1000);//延时10ms进行消抖
                    if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
                    {       
                            /*对列进行测试(高位低电平,低位高电平)*/
                            GPIO_KEY=0X0F;
                            switch(GPIO_KEY)
                            {
                                    case(0X07): KeyValue=0;break; //对应管脚高低电平0000 0111,第0列
                                    case(0X0b): KeyValue=1;break; //对应管脚高低电平0000 1011,第1列
                                    case(0X0d): KeyValue=2;break; //对应管脚高低电平0000 1101,第2列
                                    case(0X0e): KeyValue=3;break;//对应管脚高低电平0000 1110,第3列
                            }
                            /*对行进行测试(低位高电平,高位低电平)*/
                            GPIO_KEY=0XF0;
                            switch(GPIO_KEY)
                            {        /*上一行对应的列号加上相应有规律的字号就等于按键号,可由原理图查看*/
                                    case(0X70): KeyValue=KeyValue;break; //对应管脚高低电平0111 0000,第0行
                                    case(0Xb0): KeyValue=KeyValue+4;break; //对应管脚高低电平1011 0000,第1行
                                    case(0Xd0): KeyValue=KeyValue+8;break;//对应管脚高低电平1101 0000,第2行
                                    case(0Xe0): KeyValue=KeyValue+12;break;     //对应管脚高低电平1110 0000,第0行
                            }
                            
                    }
            }
            while((a<50)&&(GPIO_KEY!=0xf0))
        //检测按键松手检测(只有当按键松开时矩阵连接的管脚高位和低位才会互换继续检测行。否则进行循环延迟)
            {
                    delay(100);
                    a++;
            }
    }
    
    /*主函数*/
    void main()
    {	
    
    	while(1)
    	{	
    		KeyDown();		   //按键判断函数
    		GPIO_DIG=~smgduan[KeyValue];	  //
    	}		
    }
    展开全文
  • 以金沙滩工作室的STC89C52单片机开发板为例,记录学习51单片机的笔记,本文章主要讲解了4×4矩阵按键扫描,教材是金沙滩工作室(www.kingst.org )宋雪松老师编著的《手把手教你学51单片机-C语言版》,所用的...

    以金沙滩工作室的STC89C52单片机开发板为例,记录学习51单片机的笔记,本文章主要讲解了4×4矩阵按键的扫描,教材是金沙滩工作室(www.kingst.org )宋雪松老师编著的《手把手教你学51单片机-C语言版》,所用的开发板是教材配套开发板。在这里推荐一下宋老师的这套教材,感觉还是蛮不错的。下面是该文章的目录:

    1.矩阵按键及其原理

    2.矩阵按键的消抖

    1.矩阵按键及其原理

    图1是单片机开发板上的矩阵按键的实物图,图2是矩阵按键的电路原理图。以4×4矩阵按键为例,总共包含了16个按键,包括数字0~9、四个方向键(上下左右)、ESC键和回车键,当然在使用过程中可以定义这些按键为其他功能,灵活多变。

    b35ccbff66b8601528f310f611746e09.png
    图2 4×4矩阵按键的电路图

    16个按键占用P2的8个IO口,见上图2,KeyOut1~KeyOut4为输出引脚,KeyIn1~KeyIn4为读取引脚。KeyOut1~KeyOut4均输出高电平时,由于全部KeyIn引脚最上面与+5V接通,故无论某个按键是否按下,KeyIn1~KeyIn4读取到的均为高电平(逻辑1),无法判断是否有按键按下/弹起,当其中的某个KeyOut引脚输出低电平(逻辑0)时,按下该行的某个按键,那么这个按键对应的keyIn引脚将读取到低电平,从而可以在程序中判断某个按键是否被按下。

    例如,现在使KeyOut3引脚为0,其余KeyOut引脚为1,那么当按键K12按下时,KeyIn4引脚直接与KeyOut3引脚连通,将其电平拉低,P2.7就可以读取到0,那么就可以判断K12(右键)被按下了。

    2.矩阵按键的消抖和扫描

    由于按键的机械特性,按键存在“抖动”的情况,比如,当按下某个键的瞬间,这个键可能还会来回抖动几次,当然这种抖动是手指感觉不出来的,但它确实会影响读取到的电平的高低,相反,按键弹起的瞬间,也会存在抖动的情况。如图3,按键抖动通常只持续不到10ms,按下到弹起的整个过程通常持续100ms以上,所以需要进行消抖处理。

    1eb5f139e5241a2283097dc829eb19f3.png
    图3 按键的抖动

    在这里,按键消抖的思路定义一个4X4的二维数组 keybuf[4][4]和keysta[4][4]

    unsigned char keybuff[4][4] = {
    	{0xFF, 0xFF, 0xFF, 0xFF}, 
    	{0xFF, 0xFF, 0xFF, 0xFF}, 
    	{0xFF, 0xFF, 0xFF, 0xFF}, 
    	{0xFF, 0xFF, 0xFF, 0xFF}
    }; //定义在中断函数内
    
    unsigned char KeySta[4][4] = {
    	{1, 1, 1, 1},
    	{1, 1, 1, 1},
    	{1, 1, 1, 1},
    	{1, 1, 1, 1},
    }; //定义为全局变量

    keybuf[4][4]中每一个元素代表了对应按键在某个瞬间的状态,初始化为0xFF(0b11111111),就意味着开始每个按键均为弹起状态。

    设置定时/计数器T0的定时时长为1ms,每次中断,就选中keybuff其中一行,依次将该行的四个元素左移一位,并将对应的KeyInx(x = 1, 2, 3, 4)的值写入数组元素的最低位,如此就需要4ms完成四行按键的扫描,但是,通常抖动的时间在10ms左右,那么干脆就在16ms内判断某个按键是否被稳定的按下或者弹起,若在16ms中读取到的某个按键的状态均为0或者1,那么就可以判断这个按键已经被稳定地按下或者弹起了,这时,就将存储按键状态的二维数组KeySta[4][4]中对应的按键的状态置为0或者1。

    下面是部分示例代码(定义KeyScan函数专门用于按键的扫描,它在T0的中断函数内被调用)。

    #include<reg52.h>
    
    sbit KeyOut4 = P2^0;
    sbit KeyOut3 = P2^1;
    sbit KeyOut2 = P2^2;
    sbit KeyOut1 = P2^3;
    sbit KeyIn1 = P2^4;
    sbit KeyIn2 = P2^5;
    sbit KeyIn3 = P2^6;
    sbit KeyIn4 = P2^7;
    
    unsigned char KeySta[4][4] = {
         {1, 1, 1, 1},
         {1, 1, 1, 1}, 
         {1, 1, 1, 1}, 
         {1, 1, 1, 1}
     };
    unsigned char code KeyCodeMap[4][4] = {
    	{ 0x31, 0x32, 0x33, 0x26 }, //数字键 1、数字键 2、数字键 3、向上键
        { 0x34, 0x35, 0x36, 0x25 }, //数字键 4、数字键 5、数字键 6、向左键
        { 0x37, 0x38, 0x39, 0x28 }, //数字键 7、数字键 8、数字键 9、向下键
        { 0x30, 0x1B, 0x0D, 0x27 } //数字键 0、ESC 键、 回车键、 向右键;
    };
    
    void KeyScan()
    {
    	static unsigned char KeyBuff[4][4] = {
    		{0xFF, 0xFF, 0xFF, 0xFF}, 
    	    {0xFF, 0xFF, 0xFF, 0xFF}, 
    	    {0xFF, 0xFF, 0xFF, 0xFF}, 
    	    {0xFF, 0xFF, 0xFF, 0xFF}
    	};
    	static unsigned char row = 0;
    	unsigned char col;
    	KeyBuff[row][0] = (KeyBuff[row][0] << 1) | KeyIn1;
    	KeyBuff[row][1] = (KeyBuff[row][1] << 1) | KeyIn2;
    	KeyBuff[row][2] = (KeyBuff[row][2] << 1) | KeyIn3;
    	KeyBuff[row][3] = (KeyBuff[row][3] << 1) | KeyIn4;
    	for (col = 0; col < 4; col++)
    	{
    		if ((KeyBuff[row][col]) & 0x0F == 0x0F)
    		{
    			KeySta[row][col] = 1;
    		}
    		else if ((KeyBuff[row][col] & 0x0F) == 0x00)
    		{
    			KeySta[row][col] = 0;
    		}
    	}
    	row++;
    	row  = row & 0x03;
    	switch (row)
    	{
    		case 0: KeyOut4 = 1; KeyOut1 = 0; break;
    		case 1: KeyOut1 = 1; KeyOut2 = 0; break;
    		case 2: KeyOut2 = 1; KeyOut3 = 0; break;
    		case 3: KeyOut3 = 1; KeyOut4 = 0; break;
    		default: break;
    	}
    }
    展开全文
  • 本系列文章讲述了基于proteus仿真的51单片机学习,内容全面,不仅讲解电路原理,还讲解了单片机c语言,实例丰富,内容全面。
    1、本例实现用4个按键控制8位流水灯的不同显示效果。
    按下KEY1键时,接在P3口的8位流水灯从P0.0开始依次点亮;
    按下KEY2键时,接在P3口的8位流水灯从P0.7开始依次点亮;
    按下KEY3键时,接在P3口的8位流水灯全部点亮;
    按下KEY4键时,接在P3口的8位流水灯全部熄灭;
    2、本例中使用4个按键,分别对应4种功能,因此,给4个按键分别命名并设置键值,如下:
    KEY1键:键值为1;
    KEY2键:键值为2;
    KEY3键:键值为3;
    KEY4键:键值为4;
    3、4个按键分别接在P1口的P0.0--P0.3这4个引脚上,按键判别过程如下:
    1)首先判断是否有按键被按下。将P1口的低四位置为高电平,然后读取这4位的电平值(想一想,为什么要先置为高电平,然后再读取电平值),只要有一位不是高电平,则说明有按键被按下。读取方法如下:
    P1=0x0f;
    if((P1&&0x0f)!=0x0f);
    //低四位与“1”相与,如果结果不是1,则说明低四位中必然有一位是‘0’,说明有按键被按下。
    2)按键消抖。但判别到有按键被按下后,调用延时函数,延时一段时间后 ,再进行判断,若果仍然检测到有按键被按下,则进行键值判断,否则认为是干扰信号,不再进行按键识别处理;
    3)键值判断:当确认有按键被按下时,可采用逐位扫描的方法判断那个按键被按下。
     
    4、根据上述分析,编写程序代码。在keil c51中新建工程ex41,编写如下程序代码,编译并生成ex41.hex文件。
    #include <reg51.h>    //包含头文件
    sbit KEY1=P1^0;     //用位定义指令分别定义4个按键所对应的引脚
    sbit KEY2=P1^1;
    sbit KEY3=P1^2;
    sbit KEY4=P1^3;
    unsigned char keyval;  // 全局变量定义,定义键值变量
    //LED流水灯延时函数
    void led_delay(void)
    {
      unsigned char i,j;
     for(i = 0;i < 251;i++)
     {
       for(j = 0;j < 251;j++);
     }
    }
    //按键消抖延时函数
    void delay20ms(void)
    {
      unsigned char i,j;
     for(i = 0;i < 100;i++)
     {
       for(j = 0;j < 60;j++);
     }
    }
    //正向流水灯
    void forward(void)
    {
      P3 = 0xfe;     //点亮P3.0引脚的LED灯
     led_delay();
     P3 = 0xfd;
     led_delay();
     P3 = 0xfb;
     led_delay();
     P3 = 0xf7;
     led_delay();
     P3 = 0xef;
     led_delay();
     P3 = 0xdf;
     led_delay();
     P3 = 0xbf;
     led_delay();
     P3 = 0x7f;
     led_delay();
     P3 = 0xfe;
     led_delay();
    }
    //反向流水灯
    void backward(void)
    {
      P3 = 0x7f;    //点亮P3.7引脚的LED灯
     led_delay();
     P3 = 0xbf;
     led_delay();
     P3 = 0xdf;
     led_delay();
     P3 = 0xef;
     led_delay();
     P3 = 0xf7;
     led_delay();
     P3 = 0xfb;
     led_delay();
     P3 = 0xfd;
     led_delay();
     P3 = 0xfe;
     led_delay();
     P3 = 0x7f;
     led_delay();
    }
    //关闭所有LED灯
    void stop(void)
    {
      P3 = 0xff; 
    }
    //所有LED闪烁
    void flash(void)
    {
      P3 = 0xff;
     led_delay();
     P3 = 0x00;
     led_delay(); 
    }
    //键盘扫描函数
    void key_scan(void)
    {
      if((P1 & 0x0f)!=0x0f)    //检测是否有按键被按下
     {
       delay20ms();
      if((P1 & 0x0f)!=0x0f)    //延时后再次检测是否有按键被按下
      {
       if(KEY1 == 0)    //判断是那个按键被按下
       {
         keyval = 1;
       }
       if(KEY2 == 0)
       {
         keyval = 2;
       }
       if(KEY3 == 0)
       {
         keyval = 3;
       }
       if(KEY4 == 0)
       {
         keyval = 4;
       }
      }
     }
    }
    //主函数
    void main(void)
    {
     keyval = 0;      //
     while(1)
     {
       key_scan();    //调用键值检测函数
      switch(keyval)     //根据键值实现相应功能
      {
        case 1:forward();
              break;
       case 2:backward();
              break;
       case 3:stop();
              break;
       case 4:flash();
              break;
      }
     }
     
    5、在proteus中新建仿真文件ex41.dsn,电路原理图如下所示:

     
    6、将ex41.hex文件载入at89c51中,启动仿真,分别按下4个按键,观察程序运行结果。
    7、可以看到,当第一次按下KEY1键时,8位流水灯开始正向轮流点亮,但是当按下KEY2或其它按键时,流水灯并没有按照我们的设计初衷相应改变,这是为什么呢?大家仔细想一想!
     
    8、由此可见,使用这种方法,有时候程序运行效果并不如我们预料的那样,关于按键的更好的处理方法,我们将在后面的定时器的学习中进行进一步的阐述。在此先暂时不提。
     
    下一节开始,我们就要对51单片机的内部功能进行深入学习了,争取通过更多的实例,加深我们的理解。
    展开全文
  • 51单片机之矩阵按键

    千次阅读 2019-07-20 13:57:14
    区别:矩阵按键为4*4即16个按键,如果都采用独立按键的解法,那么需要占用16个I/O接口,对于单片机而言是极大的浪费。 工作原理: 先见下图: 他有两种识别方式:逐行扫描、行列扫描。 (1)逐行扫描: 通俗...
  • 这是一个基于普通51单片机和SIM800A模块的按键手机模拟的代码,附原理图,看完代码,你就可以掌握NOKIA5110屏幕的使用方法,矩阵按键在中断中扫描,检索字符串等等技能!
  • 51单片机入门教程(4)——按键控制

    万次阅读 多人点赞 2018-11-17 00:20:10
    按键输入一、独立按键1.1 独立按键的原理1.2 独立按键的仿真电路1.3 按键消抖二、矩阵键盘2.1 矩阵键盘原理2.2 矩阵键盘扫描原理矩阵键盘扫描程序 单片机与外界的信息交互主要有两大类,输入信息和输出信息。 之前的...
  • 矩阵按键,顾名思义,就是形成矩阵的按键,一般由多行多列组成,如下图是一个4*4的矩阵按键;如果是独立按键,需要占用16个MCU引脚,而使用矩阵按键只需要8个 其原理图如下: 矩阵按照是如何检测哪个按下的呢? ...
  • 矩阵按键扫描原理 方法一: 逐行扫描:我们可以通过高四位轮流输出低电平来对矩阵键盘进行逐行扫描,当低四位接收到的数据不全为1的时候,说明有按键按下,然后通过接收到的数据是哪一位为0来判断是哪一个按键被按...
  • 12.1 项目分析 矩阵键盘,是一种在节省端口的前提下控制大量按键的一种方法,对于传统的独立对地键盘,一个按键就需要占用一个单片机IO口,虽然有时候会加一些扩展芯片之类的用于一个端口控制多个按键,但是电路结构...
  • 51单片机LCD1602显示矩阵按键键值

    千次阅读 2019-02-11 18:24:16
    矩阵按键原理图 矩阵按键怎么变成独立按键 方法一: 逐行扫描:我们可以通过高四位轮流输出低电平来对矩阵键盘进行逐行扫描,当低四位接收到的数据不全为1的时候,说明有按键按下,然后通过接收到的数据是哪一...
  • 按结构原理分: 触点式开关按键 无触点开关按键 接入方式 独立式按键 矩阵式键盘 ———————————————————————————————————————————— 矩阵...
  • 51单片机学习记录(7) “矩阵按键” 首先还是让我们先看一下原理图 可以看的出来,矩阵按键的连接方式 矩阵按键是由P1口控制的 P1口的高四位(P17–P14)控制着矩阵按键的行 P1口的低四位(P13–P10)控制着矩阵按键的列...
  • 而现在介绍的按键扫描法是“快速识别”方法(以独立按键为例,因为矩阵键盘的扫描与独立按键类似)。 首先附上按键的原理图: 用跳帽连接排针 J5 的2脚与3脚,将键盘设置为独立按键(只有S4~S7有效)。此时,S4~S7...
  • 1. 基于proteus的51单片机开发实例24-矩阵键盘1.1. 实验目的图1 矩阵键盘电路本实例我们来学习矩阵键盘(行列式键盘)的电路设计、编程实现。目的是通过较少的I/O口来识别多个按键。1.2. 设计思路我们在前面已经学习过...
  • 先附上矩阵键盘的原理图: 在使用据矩阵键盘时,J5 排针处的跳帽连接 1 脚和 2 脚,使所有按键的有效端口全部连接至 I/O 口。 具体的扫描方式为: 先把P3^0~P3^7高四位和第四位赋不一样的电平值,当确定有键按下时...
  • 当接收到的数据,低四位不全为高电平时,说明有按键按下,然后通过接收的数据值,判断是哪一列有按键按下,然后再反过来,高四位输出高电平,低四位输出低电平,然后根据接收到的高四位的值判断是那一行有按键按下,...
  • 51单片机复习

    2018-08-05 12:03:00
    1.矩阵按键扫描原理:当按键按下时按键两个引脚为0;先给P1.3-P1.0为1,P1.7-P1.4为0(代码中GPIO_KEY=0x0f;),当有按键按下,它的两个引脚都应该为0,我们事先把列引脚设为了1,看哪一位为0了就能确定是哪一...
  • 基于51单片机的简易计算器

    万次阅读 多人点赞 2019-01-08 21:17:44
    本计算器是以MCS-51系列AT89C51单片机为核心构成的简易计算器系统。该系统通过单片机控制,实现对4*4键盘扫描进行实时的按键检测,并由LCD1602显示屏将过程与结果显示出来。 2.硬件原理图 硬件主要由四部分组成 ...
  • 51单片机 矩阵键盘

    2019-03-13 19:13:33
    逐行扫描:我们可以通过高四位轮流输出低电平来对矩阵键盘进行逐行扫描,当低四位接收到的数据不全为1的时候,说明有按键按下,然后通过接收到的数据是哪一位为0来判断是哪一个按键被按下。 2.行列扫描 行列扫描:...
  • 单片机原理图 矩阵键盘 原理图 使用:独立键盘 独立键盘模块是很简单的一部分,只需要了解按下开关之后,串口会被拉低到0即可判断。 简单的一个独立键盘代码,供参考 这里面还有一个可以学习的地方就是防止抖动 当...
  • 众所周知,51单片机一般的键盘检测原理为非编码键盘检测,没有专门用来产生键编码号或键值的电路芯片;而我们使用的电脑键盘为编码键盘,通过编码电路芯片为每个按键产生一个编码号,可以通过串行总线把键值传输给...
  • 根据电路原理图,键盘扫描方法是:行线P1O~P13为输出线,列线P14~P17为输入线...51单片机综合学习系统资源丰富,板内有:8位LED数码管、32路LED、4x4矩阵键盘、4个直控按键盘、蜂鸣器喇叭、继电器试验、I2C总线接口、S
  • C51 单片机矩阵键盘

    2015-12-28 00:45:44
    扫描原理:输入行值,读取列值;输入列值,读取行值。这是很常用的方法。代码如下: //======================================= // 矩阵键盘扫描,返回按键码 //======================================= ...
  • 本文通过在proteus上搭建51单片机的矩阵键盘电路并联合keil编程软件编写的源程序进行8*8矩阵键盘仿真,进而熟悉proteus仿真软件的仿真操作。 目录(一)4×4矩阵键盘原理1.逐行扫描2.行列扫描(二)8×8矩阵键盘...
  • 51单片机矩阵键盘编码方法

    千次阅读 多人点赞 2017-07-23 16:33:16
    众所周知,51单片机一般的键盘检测原理为非编码键盘检测,没有专门用来产生键编码号或键值的电路芯片;而我们使用的电脑键盘为编码键盘,通过编码电路芯片为每个按键产生一个编码号,可以通过串行总线把键值传输给...
  • 51单片机】LED点阵

    2020-09-10 10:08:22
    我们使用的是一个8×8的电子,需要操作16bit,实现对行和列的管理,这点其实和矩阵按键是有些类似,只不过一个是输入,一个是输出,都是通过逐行扫描实现的(矩阵按键由于每次只检查一个按键,也可以使用行列扫描)...

空空如也

空空如也

1 2 3 4
收藏数 74
精华内容 29
关键字:

51单片机按键扫描原理