单片机 矩阵式按键

2020-05-11来源: eefocus关键字:单片机  矩阵式  按键

一、简述

在单片机应用系统中,通过按键实现数据输入及功能控制是非常普遍的,通常在所需按键数量不多时,系统常采用独立式按键。需要按键数量比较多,为了减少I/O口的占用,通常将按键排列成矩阵。测试环境为Win7-32bit-2G运存,Proteus8.5,Keil4


工程文件等:链接: https://pan.baidu.com/s/1kCf8jGU26GR_Nv1P7xxngQ 密码: 8ax7


二、效果

三、工程结构


1、Keil工程

2、仿真电路

三、编程思路

没有按键按下时,X0~X3是低电平,Y0~Y3是高电平。


某一个按键按下,设置其所在的行低电平,列就会变为低电平。


1、判断有无键被按下


方法是:将全部行线X0~X3置低电平,然后检测列线的状态。只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平线与4根行线相交叉的4个按键之中。若所有列线均为高电平,则键盘中无键按下。


2、确定哪个键按下


方法是:在确认有键按下后,依次将行线置为低电平,即在置某根行线为低电平时,其他线为高电平(其实就是屏蔽其他行的按键状态,只有当前检测行的按键状态有效);在确定某根行线位置为低电平后,再逐行检测各列线的电平状态,若某列为低(说明当前检测行有按键按下),则该列线与置为低电平的行线交叉处的按钮就是闭合的按键。


四、代码


key.c文件


#include

#define uint unsigned int

#define uchar unsigned char

uint key,key_num;//键盘扫描值,键盘键值

/********************************************************************/

//函数名:delay_1ms(uint x)

//功能:利用定时器0精确定时1ms; 自加 time_t的值为后面时间调整函数服务

//调用函数:

//输入参数:x,1ms计数

//输出参数:

//说明:延时的时间为1ms乘以x

/********************************************************************/

void delay_1ms(uint x)

{

TMOD=0X01;//开定时器0,工作方式为1

TR0=1;//启动定时器0;

while(x--)

{

TH0=0Xfc;//定时1ms初值的高8位装入TH0

TL0=0X18;//定时1ms初值的低8位装入TL0

while(!TF0);//等待,直到TF0为1

TF0=0;

}

TR0=0;//停止定时器0;

}

 

/**********************************************************/

//函数名:keyscan()

//功能:得出4x4键盘的行列扫描值

//调用函数:delay_1ms(uint x)

//输入参数:

//输出参数:

//说明:通过P1口的扫描得出扫描值key,无键按下key为16

/**********************************************************/

uchar keyscan()

{

  uchar code_h; //行扫描值

uchar code_l; //列扫描值

P1=0XF0; //P1.0-P1.3全为0,(行状态全为低电平)

if((P1&0xF0)!=0XF0) //如果P1.4-P1.7不全为1,可能有键按下(为准确识别按键动作)

{

    delay_1ms(5); //廷时去抖动,为准确识别按键动作

    if((P1&0xF0)!=0XF0)//重读高4位(列状态),若还是不全为1,定有键按下

            {

        code_h=0xfe;  //开始行扫描 (0xfe:11111110)

        while((code_h&0x10)!=0x00)//判断是否扫描四行(X0~X3)完毕,若不是,继续扫描(0x10:00010000)  

               {

           P1=code_h; //第1次P1.0置为0,其余高电平;第2次P1.1置为0,其余高电平 ;第3次P1.2置为0,其余高电平;第4次P1.3置为0,其余高电平

           if((P1&0xF0)!=0XF0) //如果P1.4-P1.7不全为1,该行有键按下(0xF0:11110000)

                   {

        code_l=(P1&0xF0|0x0F);//保留P1口高4位,低4位变为1,作为列值

        return((~code_h)+(~code_l));//键盘编码=行扫描值+列扫描值 (取反后用,相当于改为按下按键对应的行、列标识为1,其它为0)  

           }

           else                           //左移后补0,但是我们需要将其他位置1,所以+1

        code_h=(code_h<<1)|0x01;  //若该行无键按下,行扫描值左移+1,扫描下一行 

         }

     }

}

return(16); //无键按下,返回16 

 }

 

/**********************************************************/

//函数名:keynum()

//功能:得出4x4按键的键值

//调用函数:keyscan()

//输入参数:

//输出参数:

//说明:通过key的值确定按键键值

/**********************************************************/

void keynum()

{

    uchar i,j;

    uchar code tab[4][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11},{12,13,14,15}}; 

    //4x4键盘各键值标注

    key=16;

    key = keyscan();//引入key值

    if((key&0x01)!=0) i=0; //判断出按下按键的行列号 (即找出低电平的行、列)

    if((key&0x02)!=0) i=1;

    if((key&0x04)!=0) i=2;

    if((key&0x08)!=0) i=3;

    if((key&0x10)!=0) j=0;

    if((key&0x20)!=0) j=1;

    if((key&0x40)!=0) j=2;

    if((key&0x80)!=0) j=3;

    if(key!=16) 

    {

    key_num = tab[i][j];//通过比较得出4x4键盘的键值

    }   

}

 

void main()

{

uint shi,ge;

shi = 0;

ge = 0;

P2 = 0x16;//初始值 为16

while(1)

{

keynum(); //获取到键值

if(key!=16)

{

shi = key_num/10;//获得十位  

ge = key_num%10;//获得个位

if(shi)

{

P2 = 0x10|ge;

}

else

{

    P2 = ge;

}

}

delay_1ms(10);//延时

}

}


五、总结


方式二:当无按键按下时,4行均为低电平,4列电平均为高电平;按键按下时,按键所在行为高电平,所在列为低电平。这样子的情况可以使用以下方式扫描按键。

(此方式没有处理同时按下多个按键的问题)

key2。c文件 按键扫描代码


/**********************************************************/

//函数名:keyscan()

//功能:得出4x4键盘的行列扫描值

//调用函数:delay_1ms(uint x)

//输入参数:

//输出参数:

//说明:通过P1口的扫描得出扫描值key,无键按下key为16

/**********************************************************/

uchar keyscan()

{

P1=0XF0; //P1.0-P1.3全为0,(行状态全为低电平)

if((P1&0xF0)!=0XF0) //如果P1.4-P1.7不全为1,可能有键按下(为准确识别按键动作)

{

    delay_1ms(5); //廷时去抖动,为准确识别按键动作

    if((P1&0xF0)!=0XF0)//重读高4位(列状态),若还是不全为1,定有键按下

        {

        return(~P1);//键盘编码 (取反后用)

    }

}

return(16); //无键按下,返回0 

 }


六、补充


1、多个按键同时按下,可采取索引值较大者

 

关键字:单片机  矩阵式  按键 编辑:什么鱼 引用地址:http://news.nvwayi.com/mcu/ic496694.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:单片机 数字电压表(ADC0809)
下一篇:单片机 软件延时时间控制

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

MSP430单片机写Info Memory
MSP430F5438A单片机在写Info Memory时,需要先把整页数据擦除,才能写进去。否则写失败。而且还得设置下载程序时不要擦除 Info memory, 否则存储数据失败。因为没此下载时都给你擦除了。
发表于 2020-05-08
MSP430单片机写Info Memory
51单片机实验8:led点阵(1):点亮一个点
开发板led点阵模块电路图如下:74HC595:74HC595是一个8位串行输入、并行输出的位移缓存器。芯片第11角为数据输入时钟线,上升沿有效。芯片第12脚为输出存储器锁存时钟线,上升沿有效。芯片第13脚为输出有效(低电平)。芯片第14脚为串行数据输入。为表示出输入74HC595的8位二进制数,开发板加入了led模块(图一中绿色所示)。若要使led发光,则需将JP595接vcc。OE为输出有效控制端,低电平有效,所以务必将JOE短接片短接到GND端。_nop_();函数为延时一个机器周期,所对应头文件为intrins.h#include<reg52.h>#include<intrins.h>#define
发表于 2020-05-08
51单片机实验8:led点阵(1):点亮一个点
51 单片机:在 P0 口接上 8 个 LED,实现每次亮两个灯的流水灯
要求:每次亮相邻两个灯,分别闪烁五次后,移动一位,汇编。做而论道编程如下:;------------------------    ORG   0000H    LJMP  MAIN    ORG   0100HMAIN:    MOV   R2, #0FCH    MOV   A, #1;------------------------LOOP:    MOV   P0, R2   ;
发表于 2020-05-08
51单片机 4个独立按键控制LED灯 (protues仿真)(C语言版)
一、思路及相关问题1、逻辑思路:当按下key1时 led1亮起来 因为按下去具有瞬时性不用while,用if语句,当松开时,用while(!key1) ,函数调用。先在脑海里想象它的大致运行过程,其次在仿真软件protues上摆好元器件并连接,最后用keil4写对应代码。需注意keil4软件上的设置如波特率,添加文件,勾选等等。至少要了解C语言程序设计的基本功。2、关于消抖:通常的按键所用开关为机械性开关,当机械触电断开、闭合时、由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定的接通,在断开时也不会一下子断开、因而在闭合及断开的瞬间均伴随有一连串的抖动,为了不产生这种现象而作的措施就是按键消抖按键消抖有两种,一种是 软件消
发表于 2020-05-08
51单片机 4个独立按键控制LED灯 (protues仿真)(C语言版)
单片机实例---定时器控制点阵显示0~9
显示状态:点阵上每隔1s显示一个数字,显示到9又重头显示不断循环#include<reg52.h>#include<intrins.h> typedef unsigned int u16;typedef unsigned char u8; u8 flag=0;   //时间标志位 #define lie_io P0    //定义P0端口 sbit RCLKK = P3^5;    sbit SRCLK = P3^6;sbit SER = P3^4;   //串行输入 u
发表于 2020-05-08
51单片机课程设计——led点阵广告牌程序设计
上学期期末的课设题目是led点阵广告牌,当时的要求如下:(1)能够显示不同字符的LED点阵广告牌;(2)按键切换不同的显示效果(如闪烁,静止,平移等);(3)按键切换不同的显示内容;(4)能够显示图形或自定义字符;(5)其他功能(创新部分);(6)系统调试、分析、总结与功能实现。当时用的是我用是的普中科技的STC90C51RD+的单片机,不过只要是51单片机,换哪个51内核的芯片都可以,只要电路和程序匹配就可以。我用的那款普中科技的51单片机可以直接连线决定线路的布置,不需要自己去重新焊一个电路板。然后我根据任务要求连接了电路,写了对应的程序,还有proteus仿真。另外,觉得有趣可以点个赞;有什么有趣的想法可以评论一下,我感兴趣
发表于 2020-05-08
51单片机课程设计——led点阵广告牌程序设计
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2020 EEWORLD。com。cn, Inc。 All rights reserved
澳客彩票 澳客彩票 澳客彩票投注 彩票大赢家 那个棋牌平台送彩金最多 免费送彩金棋牌游戏 2019百家乐18元送彩金 真人娱乐平台送彩金 pk10机器人 白菜送彩金59网站大全