线反转法键盘扫描算法
实验五 键盘扫描实验 实验报告
键盘扫描实验实验报告一、实验目的1. 掌握线反转法键盘扫描原理。
2. 了解单片机的输入和输出过程,理解单片机的数据采集过程。
二、实验内容单片机外接4x4键盘,通过线反转法判断按下的键,并在数码管上显示按键对应的数字。
第一行从左到右分别是开关K0, K1, K2, K3,第二行从左到右分别是K4, K5, K6, K7以此类推。
当按下Kn时,在数码管上显示数字n。
三、实验原理线翻转法:先对行(R0-R3)置0,对列(R4-R7)置1。
当有键被按下时,会把按键所在的列的电位从1变0,记录下位置;然后再将行列翻转,记录下按下键的所在行,两数进行或运算,就可以得到一个唯一表示按下键的数字。
例如:假定R0-R7分别与单片机的P2.0-P2.7相连。
先把R4-R7置1,R0-R3置0(通过指令MOV P2, #0F0H实现)。
当键K5被按下时,R5电位被拉低为低电平。
此时,P2口表示的数为:1101 0000(0xD0);然后再置R4-R7为0,R0-R3为1,此时,R1电位被拉低为低电平,此时,P2口表示的数为:0000 1101(0x0D)。
将两数相与取反,得到:0010 0010。
四、实验过程1. 连接好单片机及其外围设备电路2. 编写汇编程序ORG LJMP KeyLJMP K7: CJNE R2, #82H, K8ORG 0100H MOV P0, #0F8H Init: CLR P1.3 LJMP KeyMOV P0, #0C0H K8: CJNE R2, #14H, K9 Key: MOV P2, #0F0H MOV P0, #080HMOV A, P2 LJMP KeyMOV R1, A K9: CJNE R2, #24H, K10MOV P2, #0FH MOV P0, #090HMOV A, P2 LJMP KeyORL A, R1 K10: CJNE R2, #44H, K11CPL A MOV P0, #088HMOV R2, A LJMP KeyJNZ KeyPro K11: CJNE R2, #84H, K12LJMP Key MOV P0, #083H KeyPro: CJNE R2, #11H, K1 LJMP KeyMOV P0, #0C0H K12: CJNE R2, #18H, K13LJMP Key MOV P0, #0C6H K1: CJNE R2, #21H, K2 LJMP KeyMOV P0, #0F9H K13: CJNE R2, #28H, K14LJMP Key MOV P0, #0A1H K2: CJNE R2, #41H, K3 LJMP KeyMOV P0, #0A4H K14: CJNE R2, #48H, K15LJMP Key MOV P0, #086H K3: CJNE R2, #81H, K4 LJMP KeyMOV P0, #0B0H K15: CJNE R2, #88H, K16LJMP Key MOV P0, #08EH K4: CJNE R2, #12H, K5 LJMP KeyMOV P0, #099H K16: LJMP KeyLJMP Key ENDK5: CJNE R2, #22H, K6MOV P0, #092HLJMP KeyK6: CJNE R2, #42H, K7MOV P0, #082H五、实验结果1. 当按下开关Kn时,数码管能够显示对应的数字。
键盘扫描原理
键盘扫描原理
键盘是计算机输入设备中最常用的一种,它通过将人们的按键操作转换成计算机可以识别的信号,从而实现了人机交互。
而键盘的核心部分就是键盘扫描原理,它是如何实现的呢?
首先,我们需要了解键盘的工作原理。
当我们按下键盘上的某一个按键时,就会产生一个按键信号,这个信号会通过键盘的电路传输到计算机主机上。
而键盘扫描原理就是指计算机是如何检测到这个按键信号的。
键盘扫描原理的核心就是矩阵扫描。
键盘上的每一个按键都对应着一个电路,这些电路会以矩阵的形式排列在键盘的背后。
当我们按下某一个按键时,对应的电路就会闭合,从而产生一个按键信号。
计算机会通过扫描这个矩阵来检测到按键信号的产生。
具体来说,计算机会以一定的频率扫描键盘上的每一个按键,检测它们是否产生了按键信号。
这个扫描的频率通常很高,所以我们按下按键时几乎可以立即得到响应。
一旦计算机检测到有按键信号产生,它就会将这个信号转换成相应的键值,从而实现了按键的输入。
除了矩阵扫描,现代键盘还采用了一些其他技术来提高性能和稳定性。
比如采用了多种防抖动技术,防止因按键抖动而产生误操作;采用了多种按键轮询技术,提高了按键的灵敏度和反应速度;还采用了多种按键编码技术,提高了按键的识别准确性和稳定性。
总的来说,键盘扫描原理是键盘工作的核心,它通过矩阵扫描等技术实现了对按键信号的检测和转换,从而实现了人机交互。
随着技术的不断发展,键盘的性能和稳定性会不断提高,为人们的使用体验带来更多的便利和舒适。
线反转法
“线反转法”键盘扫描以前见到线反转法的文章,当时觉得挺好的,现在记不得了,以为网上很多,可到网上一搜,也不方便找,费了好大劲在EDN上找到了一篇相对详细的介绍,现在转帖下来,如果需要的,就方便了。
不用说大家都知道最经典的键盘扫描程序是查询式的扫描法,或者更高级一点的再加个中断。
但是,有一种叫“线反转法”的键盘扫描程序,比一般的查询式的要高级一点,或许在实际应用中也几乎感觉不到快多少ms,但是了解一下总是有好处的吧!设有如下的键盘电路图:Step 1:将列线作为输出线,行线作为输入线。
置输出线全部为0,此时行线中呈低电平0的为按键所在行,如果全部都不是0,则没有按键按下。
Step 2:将第一步反过来,即将行线作为输出线,列线作为输入线。
置输出线全部为0,此时列线呈低电平的为按键所在的列。
这样,就可以确定了按键的位置(X,Y)。
当然还要注意软件去抖动啦~参考C代码(部分):while(1){P0=0x0F;if((P0&0x0F)!=0x0F){switch(P0){case 0x07: i=3; break;case 0x0b: i=2; break;case 0x0d: i=1; break;case 0x0e: i=0; break;default: break;}}delay10ms();//软件去抖动P0=0xF0;//反转行和列上的电平if((P0&0xF0)!=0xF0){switch(P0){case 0x70: j=3; break;case 0xb0: j=2; break;case 0xd0: j=1; break;case 0xe0: j=0; break;default: break;}P1=num[j][i];//P1输出对应的按键值}}。
单片机矩阵键盘扫描的两种方式
单片机矩阵键盘扫描的两种方式单片机矩阵键盘扫描的两种方式矩阵键盘扫描方式:第一种:逐行扫描法,就是一行一行的扫描。
实现代码如下(键盘连接P2口):#define NO_KEY 0XFF#define KEY_LO() P2 &= 0XF0#define KEY_HI() P2 |= 0X0F#define KEY_L(i) P2 &= ~(1<<i)#define KEY_RD() ((P2>>4) & 0x0f)UINT8 OnceKey(void){UINT8 line = 0;UINT8 key = NO_KEY;//key valueKEY_LO();if (KEY_RD() == 0X0F){KEY_HI();return NO_KEY;}for (line=0; line<4; line ++){KEY_HI();KEY_L(line);key = KEY_RD();switch (key){case ROW_FIRST:key = 4*line + 0;break;case ROW_SECOND:key = 4*line + 1;break;case ROW_THIRD:key = 4*line + 2;break;case ROW_FOURTH:key = 4*line +3;break;default :key = 0x0f;break;}if (key < 0x10){return key;}}return NO_KEY;}第二种,线性反转法。
就是行和列分别读出。
实现代码如下:#define CVT(i) ((i)==(~1)&0x0f)? 0: ((i)==(~2)&0x0f)? 1: ((i)==(~4)&0x0f)? 2: ((i)==(~8)&0x0f)? 3: 4;#define KEY0_3HI() P2 |= 0X0F#define KEY0_3LO() P2 &= 0XF0#define KEY4_7HI() P2 |= 0XF0#define KEY4_7LO() P2 &= 0X0F#define KEY0_3RD() (P2 & 0X0F)#define KEY4_7RF() ((P2>>4) & 0X0F)UINT8 OnceKey(void){UINT8 line = NO_KEY;UINT8 row = NO_KEY;UINT8 key;KEY0_3HI();KEY4_7LO();line = KEY0_3RD();//读入行的值if (0x0f == line){key = NO_KEY;}else{KEY0_3LO();KEY4_7HI();row = KEY4_7RD();//读入列的值if (0x0f == row){key = NO_KEY;}else{key = CVT(line)*4 + CVT(row);}}KEY0_3HI();KEY4_7HI();return key; }。
MSP430F149线反转法4x4键盘扫描
//MSP430F149线反转法4x4键盘扫描,控制数码管输出,IAR编译通过#include "msp430x14x.h"unsigned char smg_code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf}; //显示"0-f" 和"-" unsigned char key_code[]={0x7e,0x7d,0x7b,0x77,0xbe,0xbd,0xbb,0xb7,0xde,0xdd,0xdb,0xd7,0xee,0xed,0xeb,0xe7};void delayms() //延时函数,大约20ms 左右{unsigned int i;for (i=0;i<12000;i++){;}}unsigned char scan(void) //键盘扫描子程序(线反转法){unsigned char READ1,READ2,keycode;unsigned int key,j;P1DIR=0XFF; //设置P1口为输出状态P1OUT=0XF0; //P1.7-P1.4为高电平,其余为低电平P1DIR=0X0F; //设置P1口的P1.7-P1.4为输入状态,其余为输出状态READ1=P1IN; //读取P1口的值if ((READ1&0XF0)!=0XF0) //检测是否有键按下,并且消抖{delayms();if ((READ1&0XF0)!=0XF0){ P1DIR=0XFF; //设置P1口为输出状态P1OUT=0X0F; //P1.7-P1.4为低电平,其余为高电平(反转)P1DIR=0XF0; //设置P1口的P1.7-P1.4为输入状态,其余为输出状态READ2=P1IN; //再次读取P1口的值keycode=READ1|READ2; //行列合并,形成键码for(j=0;j<16;j++) //查键码,返回显示{if(keycode==key_code[j]){key=j;return(key);}}}}elsekey=16;return(key);}int main( void ){ unsigned char state;unsigned int k; // Stop watchdog timer to prevent time out resetWDTCTL = WDTPW + WDTHOLD;P5DIR=0XFF;P4DIR=0XFF; //设置数码管段选跟位选为输出状态P5OUT=smg_code[16]; //初始化显示为“-”P4OUT=0XFE; //最后一个数码管显示while(1){P1DIR=0XFF;P1OUT=0XF0;P1DIR=0X0F;state=P1IN; //读取端口值k=scan(); //扫描键盘if((state&0XF0)!=0XF0){P5OUT=smg_code[k]; //有键按下,显示}}}。
键盘扫描
case 0xef: managekey4();break;
case 0xdf: managekey5();break;
case 0xbf: managekey6();break;
* P1.0-P1.3为列线,P1.4-P1.7为行线 *
* 喇叭接P3.7口 矩阵键盘P1口, 数码管数据P0口,数码管控制P2口 *
* *
}
//--------------------------------------------------
main()
{
P0=0xFF; //置P0口
P2=0xFF; //置P2口
dis_buf=0xBF;
while(1)
temp=temp&0x0F;
temp=~(temp|0xF0);
if(temp==1)
key=0;
else if(temp==2)
key=1;
else if(temp==4)
key=2;
else if(temp==8)
else
{ for(a=0;a<4;a++)
P1=0xF0;
if(P1!=0xF0)
{
keyscan();
beep();
// while(P1!=0xF0); //等待键释放
}
}
//--------------------------------------------------
void beep()
}
//--------------------------------------------------
单片机实验--键盘扫描
实验4 键盘实验一、实验目的:1.掌握8255A编程原理。
2.了解键盘电路的工作原理。
3.掌握键盘接口电路的编程方法。
二、实验设备:CPU挂箱、8031CPU模块三、实验原理:1.识别键的闭合,通常采用行扫描法和行反转法。
行扫描法是使键盘上某一行线为低电平,而其余行接高电平,然后读取列值,如所读列值中某位为低电平,表明有键按下,否则扫描下一行,直到扫完所有行。
本实验例程采用的是行反转法。
行反转法识别键闭合时,要将行线接一并行口,先让它工作于输出方式,将列线也接到一个并行口,先让它工作于输入方式,程序使CPU通过输出端口往各行线上全部送低电平,然后读入列线值,如此时有某键被按下,则必定会使某一列线值为0。
然后,程序对两个并行端口进行方式设置,使行线工作于输入方式,列线工作于输出方式,并将刚才读得的列线值从列线所接的并行端口输出,再读取行线上的输入值,那么,在闭合键所在的行线上的值必定为0。
这样,当一个键被按下时,必定可以读得一对唯一的行线值和列线值。
2.程序设计时,要学会灵活地对8255A的各端口进行方式设置。
3.程序设计时,可将各键对应的键值(行线值、列线值)放在一个表中,将要显示的0~F字符放在另一个表中,通过查表来确定按下的是哪一个键并正确显示出来。
实验题目利用实验箱上的8255A可编程并行接口芯片和矩阵键盘,编写程序,做到在键盘上每按一个数字键(0~F),用发光二极管将该代码显示出来。
四、实验步骤:将键盘RL10~RL17接8255A的PB0~PB7;KA10~KA12接8255A的PA0~PA2;PC0~PC7接发光二极管的L1~L8;8255A芯片的片选信号8255CS接CS0。
五、实验电路:六、程序框图7.程序清单八、附:8251/8255扩展模块该模块由8251可编程串行口电路和8255可编程并行口电路两部分组成,其电源、数据总线、地址总线和片选信号均由接口挂箱上的接口插座提供。
一、8251可编程串行口电路(1)8251可编程串行接口芯片引脚及功能8251A是通用同步/异步收发器USART,适合作异步起止式数据格式和同步面向字符数据格式的接口,其功能很强。
按键扫描参考子程序
按键扫描----线反转法说明矩阵键盘分行线、列线2组线,如下图,P23~P20为行线,P27~P24为列线。
程序原理:第1步:列线P2.7~P2.4 全输出0,读输入线P2.3~P2.0;如果某行有键按下,由于4条列线全输出0,这时此行电平肯定为0,程序中是逐条读取、判断P2.3~P2.0,判到某条为0,就说明按下键在此行上,这时可确定按下键的行值。
[通常:P20所在行的行值为0,P21所在行的行值为4,P22所在行的行值为8,P23所在行的行值为12]第2步:行线P2.3~P2.0 全输出0,读输入线P2.7~P2.4,(注意这时行、列2组线的输入输出方向反了,所以叫线反转法)如果某列有键按下,由于4条行线全输出0,这时此列电平肯定为0,程序中是逐条读取、判断P2.7~P2.4,判到某条为0,就说明按下键在此列上,这时可确定按下键的列值。
[通常:P24所在列的列值为0,P25所在列的列值为1,P26所在列的列值为2,P27所在列的列值为3]最后,按下键键号=行值+列值比如:10号键按下了,按上面2步:[1] 列线P2.7~P2.4 全输出0,读输入线P2.3~P2.0,显然P2.2=0,这时就可确定按下键在P2.2行上,确定其行值=8;[2] 行线P2.3~P2.0 全输出0,读输入线P2.7~P2.4,显然P2.6=0,这时就可确定按下键在P2.6列上,确定其列值=2;最后,按下键的键号=行值+列值=8+2=10。
;================================================================= ;按键扫描、获取按下键键号子程序,线反转法;最终按下键的键号值在30H单元中(正常值0~F[或0~15],否则为非正常值),至于这个键做什么功能用,随题目不同而不同。
KEY_SCAN:MOV R4,#16 ;按下键行值,故意置为此值MOV R5,#16 ;按下键列值,故意置为此值;键号=行值+列值,正常时键号=0~15,异常时R4或R5不会刷新,得到的键号值就会大于等于16,此时按异常处理;-----列线P2.7~P2.4 全输出0,读输入线P2.3~P2.0 ------------------------MOV P2,#0FHROW0:JB P2.0,ROW1MOV R4,#0 ;按下键在P2.0行上,行值=0LJMP COL_SCANROW1:JB P2.1,ROW2MOV R4,#4 ;按下键在P2.1行上,行值=4LJMP COL_SCANROW2:JB P2.2,ROW3MOV R4,#8 ;按下键在P2.2行上,行值=8LJMP COL_SCANROW3:JB P2.3,COL_SCANMOV R4,#12 ;按下键在P2.3行上,行值=12;-----行线P2.3~P2.0 全输出0,读输入线P2.7~P2.4 ------------------------COL_SCAN:MOV P2,#0F0HCOL0:JB P2.4,COL1MOV R5,#0 ;按下键在P2.4列上,列值=0LJMP CAL_KEY_NOCOL1:JB P2.5,COL2MOV R5,#1 ;按下键在P2.5列上,列值=1LJMP CAL_KEY_NOCOL2:JB P2.6,COL3MOV R5,#2 ;按下键在P2.6列上,列值=2LJMP CAL_KEY_NOCOL3:JB P2.7,CAL_KEY_NOMOV R5,#3 ;按下键在P2.7列上,列值=3;-----计算键号=行值+列值[A=R4+R5]------------------------ CAL_KEY_NO:MOV A,R4ADD A,R5MOV 30H,A ;键号=行值+列值,放入30H单元;---------------------------------------------------------MOV P2,#0FH ;恢复列线P2.7~P2.4 全输出0状态RET。
51单片机矩阵键盘线反转法体会
51单片机矩阵键盘线反转法体会独立式键盘扫描只需读取IO口状态,而矩阵式键盘描通常有两种实现方法:逐行扫描法和线反转法。
(1)逐行扫描法依次从第一至最末行线上发出低电平信号,如果该行线所连接的键没有按下的话,则列线所接的端口得到的是全“1”信号,如果有键按下的话,则得到非全“1”信号。
(2)线反转法线反转法比行扫描速度快,原理是先将行线作为输出线,列线作为输入线,行线输出全“0”信号,读入列线的值,那么在闭合键所在的列线上的值必为0;然后从列线输出全“0”信号,再读取行线的输入值,闭合键所在的行线值必为0。
这样,当一个键被按下时,必定可读到一对唯一的行列值。
再由这一对行列值可以求出闭合键所在的位置。
/*在TX-1C实验板上实现如下描述:实验板上电时,数码管不显示,顺序按下矩阵键盘后,在数码管上依次显示0~F,6个数码管同时显示。
这里用“线反转”的方法写,可以代替郭天祥书上例【4.2.1】该书上使用逐行扫描的方式。
*/#include<reg52.h>#define uchar unsigned char#define uintunsigned intsbit duan=P2^6;//打开位选和段选sbit wei=P2^7;uchar code table[]={//数码管显示数值表0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};void delay(uint x){uint i,j;for(i=x;i>0;i--)for(j=110;j>0;j--);}void xianshi(uchar num){P0=table[num]; duan=1;duan=0;}uchar keyscan(void){uchar h,l;P3=0x0f;h=P3&0x0f;if(h!=0x0f){delay(10);if(h!=0x0f){h=P3&0x0f;P3=0xf0;l=P3&0xf0;return (h+l);}}return 0xff;}void main(){uchar key;P0=0;示duan=1;duan=0;//毫秒级延时函数//段选显示函数//矩阵键盘扫描函数//定义行、列值中间变量//列线输出全为0//读入行线//检测有无按键按下//延时去抖//如果确实按下//再次读入行线//输出当前列线值,行线反转//读入列线值//键盘最后组合编码值,也就是键值//其余情况返回该值//关闭所有数码管段选,实验板上电数码管不显P0=0xc0;//选中6位数码管wei=1;wei=0;while(1){key=keyscan();//用key读取keyscan()的值switch(key){case 0xee:key=0;while(keyscan()!=0xff); xianshi(key); break;//while(keyscan()!=0xff)是松手检测语句,松手时检测case0xde:key=1;while(keyscan()!=0xff);xianshi(key);//keyscan()函数会得到返回值0xff,!=oxff时表示按下去了case 0xbe:key=2;while(keyscan()!=0xff); xianshi(key); break;case 0x7e:key=3;while(keyscan()!=0xff); xianshi(key); break;case 0xed:key=4;while(keyscan()!=0xff); xianshi(key); break;case 0xdd:key=5;while(keyscan()!=0xff); xianshi(key); break;case 0xbd:key=6;while(keyscan()!=0xff); xianshi(key); break;case 0x7d:key=7;while(keyscan()!=0xff); xianshi(key); break;case 0xeb:key=8;while(keyscan()!=0xff); xianshi(key); break;case 0xdb:key=9;while(keyscan()!=0xff); xianshi(key); break;case 0xbb:key=10; while(keyscan()!=0xff); xianshi(key); break;case 0x7b:key=11; while(keyscan()!=0xff); xianshi(key); break;case 0xe7: key=12; while(keyscan()!=0xff); xianshi(key); break;case 0xd7: key=13; while(keyscan()!=0xff); xianshi(key); break;case 0xb7: key=14; while(keyscan()!=0xff); xianshi(key); break;case 0x77: key=15; while(keyscan()!=0xff); xianshi(key); break;default:break;}}}/*后记*//*刚开始写这个程序时我把主函数里面的switch—case语句这样写的,while(1){key=keyscan();//用key读取keyscan()的值switch(key){case 0xee:key=0;break;case 0xde:key=1;break;case 0xbe:key=2;break;break;}case 0x7e:key=3;break;case 0xed:key=4;break;case 0xdd:key=5;break;case 0xbd:key=6;break;case 0x7d:key=7;break;case 0xeb:key=8;break;case 0xdb:key=9;break;case 0xbb:key=10; break;case 0x7b:key=11; break;case 0xe7: key=12; break; case 0xd7: key=13; break; case 0xb7: key=14; break; case 0x77: key=15; break; default:break;}xianshi(key);运行程序后发现当手按下按键时会有数码的显示,但是一旦放开按键数码管就什么都不显示了。
键盘扫描显示实验报告
实验六键盘扫描显示实验一、实验目的1 、掌握键盘和显示器的接口方法和编程方法。
2 、掌握键盘扫描和LED八段码显示器的工作原理。
二、实验连线将JP4和JP8通过8PIN排线连接,JP10和JP3通过8PIN排线连接三、实验内容把矩阵键盘上的按键输入的键码在静态数码管上显示出来。
四、实验步骤实验采用线反转法①打开keil软件---新建工程---新建文件②编写程序:#include<reg51.h>#define uint unsigned int#define uchar unsigned charucharshuzu[3][4]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83} ; uint i;uint j;void delay(uint n){while(--n);}void keyscan(){uchar temp;P3=0x0f;delay(1000);temp=P3^0x0f;switch(temp){case 0x02 : i=0;break;case 0x04 : i=1;break;case 0x08 : i=2;break;default :break;}P3=0xf0;delay(1000);temp=P3^0xf0;switch(temp){case 0x10 : j=0;break;case 0x20 : j=1;break;case 0x40 : j=2;break;case 0x80 : j=3;break;default : break;}}main(){P2=0x00;while(1){ P3=0x00;if(P3!=0xf0)keyscan();P2=shuzu[i][j];delay(1000);}}保存、编译---生成hex文件③连接线,使用下载软件将编好程序载入单片机中。
4x4键盘的程序有扫描法与线反法
4x4键盘的程序有扫描法与线反法,但我个人认为用线反法较好,用扫描法得依次扫描所有行或列,如果用线反法就简单多了。
先使键盘的行置为低、列置为高(或列置为高、行置为低),接着读回端口的值。
比如:如果使用P0为键盘接口就先使低四位为低、高四位为高即P0=0xf0然后就读回P0口的值赋给一个变量,a=P0;紧接就给行列赋相反的值行置为高、列置为低(或列置为低、行置为高)即P0=0x0f然后就读回再与a运算就能得到唯一的识别码下面的程序就是用线反写一个4x4键盘识别程序:#include<AT89X52.H>#include<delay.h>#define KEY_SCAN P1#define uchar unsigned char//char num;/********************************//*函数名称:KEY_DOWN() *//*函数功能:延时子函数 *//*参数:无 *//*返回:返回1或0 *//*备注:1表示有键按下,0则无*//********************************/bit KEY_DOWN(){KEY_SCAN=0x0f; //先给键盘口赋个初值if(KEY_SCAN!=0x0f) //判断是有按键按下,即KEY_SCAN不等于初值时有键按下{delayms(10); //消抖if(KEY_SCAN!=0x0f) //再次判断是否真有键按下return 1; //真有就返回1没有返回零elsereturn 0;}elsereturn 0;}/********************************//*函数名称:SCAN_GET() *//*函数功能:键盘值函数 *//*参数:无 *//*返回:返回1或0 *//*备注:无 *//********************************/uchar SCAN_GET(){char button;uchar key_code;button=KEY_SCAN;KEY_SCAN=0xf0;button=(button|KEY_SCAN);while(KEY_SCAN!=0xf0);delayms(10);switch(button){case 0xd7: key_code='1';break;case 0xdb: key_code='2';break;case 0xdd: key_code='3';break;case 0xb7: key_code='4';break;case 0xbb: key_code='5';break;case 0xbd: key_code='6';break;case 0x77: key_code='7';break;case 0x7b: key_code='8';break;case 0x7d: key_code='9';break;case 0xeb: key_code='0';break;case 0xee: key_code=0xee;break;default : break;}return key_code;}////////////////////////////////////////////////////////////// //此程序是上两个程序结合的/********************************//*函数名称:Key_Get() *//*函数功能:键盘扫描函数 *//*参数:无 *//*返回:无 *//*备注:无 *//********************************/void Key_Get(){char button;KEY_SCAN=0x0f;if(KEY_SCAN!=0x0f){delayms(5);if(KEY_SCAN!=0x0f)button=KEY_SCAN;KEY_SCAN=0xf0;button=(button|KEY_SCAN);while(KEY_SCAN!=0xf0);switch(button){case 0xd7: num='1';P0=0x00;break; case 0xdb: num='2';P0=0x0f;break; case 0xdd: num='3';break;case 0xb7: num='4';break;case 0xbb: num='5';break;case 0xbd: num='6';break;case 0x77: num='7';break;case 0x7b: num='8';break;case 0x7d: num='9';break;case 0xeb: num='0';break;case 0xe7: num='a';break;case 0xed: num='b';break;case 0xee: num='c';break;case 0xde: num='d';break;case 0xbe: num='e';break;case 0x7e: num='f';break;default : break;}}}}qinglei120713的分享分享矩阵键盘C51程序(4*4)(来自互联网) 1111111111111111111111111111111111111111111111 11111111111111111111111111111111111111#include <reg51.h>#include <intrins.h>#define key_port P0 //键盘接口定义sbit key_port_0=key_port^0;sbit key_port_1=key_port^1;sbit key_port_2=key_port^2;sbit key_port_3=key_port^3;/*******************************STC89C59 单片机一毫秒延时函数*******************************/void delay_ms(unsigned int ms){unsigned int i,j;for( i=0;i<ms;i++)for(j=0;j<332;j++); //1947是STC89C58在22.1184MHz晶振下,通过软件仿真反复实验得到的数值}/**************************串口发送一个字符**************************/void com_send_dat( unsigned char dat){SBUF=dat;while (TI== 0);TI= 0 ;}/**************************串口初始化**************************/void init_com( void ){SCON=0x50 ; //SCON: serail mode 1, 8-bit UART, enable ucvr //UART为模式1,8位数据,允许接收TMOD|=0x20 ; //TMOD: timer 1, mode 2, 8-bit reload //定时器1为模式2,8位自动重装TH1=0xfa ; //Baud:19200 fosc="22.1184MHzTL1=0xfa;PCON|=0x80; //SMOD=1;波特率加倍;ES=1; //Enable Serial InterruptTR1 = 1 ; // timer 1 run}/**************************键盘扫描函数**************************/unsigned char keyscan(void){unsigned char key,i;unsigned char co de key_table[16]={0xee,0xed,0xeb,0xe7,0xde,0xdd,0xdb,0xd7,0xbe,0xbd,0x bb,0xb7,0x7e,0x7d,0x7b,0x77};key_port=0x0f; //确定行列位置if(key_port==0x0f)return(0);//无键按下返回0delay_ms(10); //调用延时函数,目的是去前沿键抖。
线反转法识别矩阵键盘的原理
线反转法识别矩阵键盘的原理线反转法识别矩阵键盘的原理一、引言随着科技的不断发展,矩阵键盘已经成为了人们日常生活中不可或缺的一部分。
在现代社会中,矩阵键盘被广泛应用于各种设备中,如电脑、手机、ATM机等。
然而,在使用矩阵键盘时,我们往往需要对其进行输入操作。
如何对矩阵键盘进行输入操作以及如何识别用户的输入操作就成为了一个重要的问题。
二、矩阵键盘的基本结构矩阵键盘是由多个按键组成的,每个按键都有一个唯一的编号。
这些按键通常被排列成一个矩形网格,并被连接到一个控制器上。
控制器通过扫描每个按键来检测用户输入。
三、线反转法识别矩阵键盘原理1. 线反转法简介线反转法是一种常用于检测电路中是否有故障的方法。
它利用了电路中两条线之间相互影响的特性。
2. 线反转法在识别矩阵键盘中的应用在使用线反转法识别矩阵键盘时,我们需要将每个按键与一个独立的输入线连接起来。
这些输入线被分成两组:行线和列线。
行线连接到矩阵键盘的行端口,列线连接到矩阵键盘的列端口。
当用户按下某个按键时,该按键所在的行和列之间会形成一条电路。
此时,电路中的电流会通过该按键并流回控制器。
控制器会检测到这条电路并确定用户按下了哪个按键。
3. 矩阵键盘的扫描过程在使用线反转法识别矩阵键盘时,控制器会通过扫描每个按键来检测用户输入。
具体流程如下:(1)将所有列设置为输出模式,并将它们置为高电平;(2)将所有行设置为输入模式,并启动一个循环;(3)在循环中,逐一扫描每一行;(4)当扫描到某一行时,将该行置为低电平,并读取每一列的状态;(5)如果有某一列被检测到有低电平,则说明该列与当前扫描的行之间形成了一条电路,即有某个按键被按下了;(6)记录下被按下的按键的编号,并将该行恢复为高电平状态;(7)继续扫描下一行,直到所有行都被扫描完毕。
四、总结线反转法识别矩阵键盘的原理是基于电路中两条线之间相互影响的特性。
在使用线反转法识别矩阵键盘时,我们需要将每个按键与一个独立的输入线连接起来,并将这些输入线分成两组:行线和列线。
键盘扫描原理
笔记本键盘的总类:美式、英式、日本各个键盘的区别:键盘的扫描方式:逐行扫描法与线反转法现在的笔记本键盘一般都是16+8的方式,即16个pin输出,对应列;8个输入pin脚,对应行。
键盘输入与输出的结构如下:在Idel状态下,EC把16条输出线全部拉低,使能键盘扫描中断,这样当任意一个按键按下时,就会触发中断(ICU的INT11h),然后EC就开始逐列扫面,比如OUT(0,1,……,15)输出(1,1,……,1,0),(1,1,……,0,1)……(0,1,……,1,1),当数一个列扫描码,得到的行如输入信号为有一个为0的时候,这是得到的列扫描码与行扫描码就是这个键的扫面码。
比如上图按下S6的时候,列与行扫描码就分别为1101,1011。
然后通过扫描码在Scan table里面找对应的键码,传给OS,确定是哪个键。
在上面的图中,我们看到,在输入信号每个上面都有上拉电阻,这个电阻必须有除非EC的输入pin脚上面的有足够的上拉能力,否则扫描就会出现错误。
下图中,是一个正常的键盘矩阵图。
键盘上面的数字就与下面矩阵里面相同的数字对应。
普通键盘结构及工作原理键盘一般有独立式和行列式(矩阵式)两种。
当然还有其它的结构,比如交互式结构等等,不过其它的结构比较少用,在这里就不介绍了。
在中颖的单片机中,有些单片机的LCD 驱动引脚的SEGMENT 口可以共享按键扫描口,当选择为按键扫描口时,可以使用这些口来扫描按键,所以在外部电路可以连接LCD 和按键矩阵,采用分时扫描进行处理,下面也将介绍这个特殊应用的方法和注意的地方。
1、独立式键盘结构独立式键盘是指各个按键相互独立地连接到各自的单片机的I/O 口,I/O口只需要做输入口就能读到所有的按键。
独立式键盘可以使用上拉电阻也可以使用下拉电阻,基本原理是一样的。
使用上拉电阻的独立式键盘结构如图1-3 所示。
(上面这个图是有问题的,应该是行列式的键盘)图1-3 所示的是利用PB 口和PC 口共8 个I/O 口独自连接8 个按键,使用外部上拉电阻构成的独立式键盘。
反转法键盘扫描原理
反转法键盘扫描原理
标题:反转法键盘扫描原理
引言概述:
反转法键盘扫描原理是一种常用的键盘输入检测方法,通过利用键盘矩阵的特性,实现对按键的扫描和识别。
本文将从五个大点来详细阐述反转法键盘扫描原理,包括键盘矩阵的构成、按键扫描的流程、按键状态的判断、消除按键冲突的方法以及常见的应用场景。
正文内容:
1. 键盘矩阵的构成
1.1 键盘矩阵的基本概念
1.2 键盘矩阵的物理结构
1.3 键盘矩阵的电气结构
2. 按键扫描的流程
2.1 初始化键盘矩阵
2.2 逐行扫描键盘矩阵
2.3 判断按键状态
2.4 输出按键值
3. 按键状态的判断
3.1 按键按下的检测
3.2 按键释放的检测
3.3 按键状态的保存与更新
4. 消除按键冲突的方法
4.1 基于时间分片的消除方法
4.2 基于硬件编码的消除方法
4.3 基于软件算法的消除方法
5. 常见的应用场景
5.1 电脑键盘
5.2 手机触摸屏键盘
5.3 数字键盘
5.4 游戏手柄
总结:
通过本文的阐述,我们了解了反转法键盘扫描原理的基本概念和工作原理。
键盘矩阵的构成、按键扫描的流程、按键状态的判断、消除按键冲突的方法以及常见的应用场景都被详细介绍。
反转法键盘扫描原理在各种输入设备中得到广泛应用,为我们提供了高效、准确的输入方式。
在今后的技术发展中,我们可以进一步优化反转法键盘扫描原理,提升输入设备的性能和用户体验。
线反转法
C 语言例程:
/*-------------------------------------------
项目名:
C 语言函数库
程序名:
4*4 扫描键盘
编写人:
杜洋
初写时间: 2005 年 11 月 18 日
程序功能: 调用后得出键盘数据返回值
实现方法: 占 CPU
CPU 说明: MCS-51 (实验:AT89S52 12MHZ)
movkey装入键盘首次的扫描值mov读出键盘值放入累加器acjne无键按下跳回主循环go1毫秒去抖mov将键值给累加器cjne是抖动则跳回主循环go2确定有键按下则movkey确定有键按下之后装入二次的扫描值dydi键值对比处理ne1cjneeehne2中的数据与键值表对比不同则跳到下一个对比movr2mpkeyend
接口说明: P3 口接 16 位行列键盘
信息说明: 将此函数放到工程文件夹中,在主程序中调用即可
函数声明: 调用延时函数 void Delay (uchar)
修改日志:
NO.1- 2005-11-18 返回 P1 显示数据
-------------------------------------------*/ //函数声明 #include <REG51.h>/////////////////MCS-51 头文件声明 #define uchar unsigned char///////定义无符号变量简写式 #define uint unsigned int//////// sfr KEY = 0xb0;////////////////////定义 P3 口为键盘接口 void Delay (uchar);///////////////延时程序声明(单位为毫秒)
线反转法的应用
行列键盘的学习是单片机学习的必经之路,可是对于初学者来说学习起来并不容易。
书上的资料不多,或是说明不细,亦或太复杂不易理解。
而线反转法行列键盘扫描简单易懂,非常适合初学者学习,也可作为程序开发之用。
了解行列键盘扫描得从硬件开始学习,我们得知道行列扫描是什么意思。
在单片机系统中为了扩大同一个 I/O 口的键盘个数,则采用了行列式键盘接法,就是交叉相接。
所谓的“行”、“列”是我们人为规定的,如果试着把列看成行,将行看成列是一样的。
这里我们规定 P1.0~P1.3为列,P1.7~P1.4 为行。
如图所示:1、51例子举一个例子吧。
第一步:行线IO P1.7~P1.4置低电平,列线IO P1.0~P1.3置高电平假设K1按下,那么P1.0=0 读P1口 P1=00001110第二步:行线IO P1.7~P1.4置高电平,列线IO P1.0~P1.3置低电平假设K1按下,那么P1.7=0 读P1口 P1=01110000两个字节相加,得到新数据:01111110(第一行第一列)每按一个键我们都得到不同的字节,比对我们的字节是什么就可以知道键值是什么了。
2、MSP430例子前面我们已经讲述了51的例子,51有其特性,IO口送出去的数据,如果不改变的话,还可以读回来,类似于一个锁存器。
但是MSP430或AVR之类的单片机,是不行的。
因此,对于IO内部无上拉电阻的MSP430单片机,比如MSP430F149,不仅行线需要加上拉电阻,列线也需要加上拉电阻,以便维持高电平。
而MSP430F21X1等系列则不必了,因为其IO可以通过配置寄存器得到上拉电阻或下拉电阻。
除了这些不同外,按键扫描流程也略有不同。
同样行列线的定义如上图。
第一步:设置行线为输入态,列线为输出态第二步:列线输出低电平第三步:读行线P1.7~P1.4的电平,读回来的数据抛弃低四位第四步:设置列线为输入态,行线为输出态第五步:行线输出低电平第六步:读列线P1.0~P1.3的电平,读回来的数据抛弃高四位两个字节相加,得到一个新数据。
71 键盘工作原理
图7-10为采用BCD或十六进制——七段锁存译码驱 动器MC14495构成的多位数码管静态显示器与8031的接 口电路。
9
P1.0 P1.1 P1.2 P1.3
8031
P1.4 P1.5 P1.6 P1.7
AB C D LE
MC14 4 9 5
abcd efg
AB C D
LE
MC14 4 9 5
abcd efg
序流程图见图7-3(b)。见书上192页
3
7.2 LED(Light Emitting Diode)数码管 显示器的工作原理
7.2.1 LED的工作原理 常用的LED器2 件:七段数码管和“米3 ”字数码管,如下图所4 示。
它们是由若干只发光二极管做在一起构成的。
D
N
G
g f ab
10 9 8 7 6
R7,LOOP
CLR P1.7
RET
2、动态显示方式 在动态显示方式中,被显示的数据直接由P1口的低4位输出, P1.4~P1.6用来选择数码管,经译码后产生输入锁存选通信 号,由P1.7来控制多位显示器数据字符的改写和锁存。当 P1.7为高电平时,允许改写各位的显示字符;当P1.7输出低 电平时,0~7=1。各位显示字符不变。下面是将显示器缓冲 区78H~7FH中的BCD码送数码管显示器的程序。
行列反转扫描法在矩阵键盘中的应用及编程思想
行列反转扫描法在矩阵键盘中的应用及编程思想我现在正在学习51单片机,学到矩阵键盘时,遇到了一些小问题,感觉行列扫描法原理简单,但编程较啰嗦,而且没有固定的编程模式,一个人一个编法,代码复杂,一会儿就能把人绕晕。
于是我就想寻找有没有一种编程思想灵巧,代码简便的程序,通过苦苦在网上寻觅,终于找到了反转法。
行列反转扫描法法可能有些教材资料里都有,但是介绍都不够详细,我找到一个资料,代码非常简单,但是并不好理解,我苦苦思索了一个晚上才弄明白。
于是根据反转法的思想,我写了一个代码不是最少,但却是非常容易理解的程序,在此拿来与大家共享。
此程序已在开发板及Proteus软件中仿真成功。
电路原理图:P1口接矩阵键盘,其中P1.0~P1.3接行线,P1.4~P.7接列线,P0口接共阴极7段数码管。
反转法的原理:反转法就是通过给单片机的端口赋值两次,最后得出所按键的值的一种算法。
for example:如图1所示,取P1口的低四位为行线,高四位为列线。
1.我们给P1口赋值0x0f,即00001111,假设0键按下了,则这时P1口的实际值为00001110;2.我们给P1口再赋值0xf0,即11110000,如果0键按下了,则这时P1口的实际值为11100000;3.我们把两次P1口的实际值相加得11101110,即0xee。
由此我们便得到了按下0键时所对应的数值0xee,以此类推可得出其他15个按键对应的数值,有了这种对应关系,矩阵键盘编程问题也就解决了,也就是程序的算法已经有了。
对应关系见图2.以下为程序:/*反转法矩阵键盘的应用,我认为这是一个编程简便又容易理解的矩阵键盘编程应用*/#include<reg52.h> //头文件#define uchar unsigned char //宏定义#define uint unsigned intuchar key,n; //定义变量uchar code table[]={0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,0xe7,0xd7 ,0xb7,0x77}; //反转法矩阵键盘的各个按键的计算值uchar code yin[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //共阴极数码管显示0~Fvoid delay(uint i) //延时函数{while(i--);}void keyscan(){uchar l,h,i; //定义局部变量,用l得出低4位的值,用h得出高4位的值P1=0x0f; //给P1赋值00001111l=P1&0x0f;if(l!=0x0f){delay(100);if(l!=0x0f)l=P1&0x0f; //若有键按下,得出低四位的值}P1=0xf0; //给P1赋值11110000h=P1&0xf0;if(h!=0xf0){delay(100);if(h!=0xf0)h=P1&0xf0; //若有键按下,得出高4位的值}key=l+h; //高4位的值与低4位的值相加for(i=0;i<16;i++){if(key==table[i]) //通过查表得出n的值n=i;}}void main(){while(1){keyscan();P0=yin[n]; //在数码管上显示相应的键值}}temp_key=P2; //0键按下时P2=0000 1110;temp1=temp_key|0xf0;//确定了在哪一行temp1=1111 1110 P2=temp1;//temp_key=P2;确定了在哪一列//temp_key=1110 1110 P3=0xf0;temp=P3;if(temp!=0xf0){delay(5);P3=0xf0;temp=P3;if(temp!=0xf0){P3=0x0f;temp2=P3;if(temp2!=0x0f){temp3=temp|temp2; }。