单片机矩阵键盘行列扫描程序

合集下载

PIC单片机自学手记之矩阵键盘 行扫描法

PIC单片机自学手记之矩阵键盘 行扫描法

PIC单片机自学手记——PIC 单片机矩阵键盘+行扫描法/*采用行扫描法RAM占用空间较少(呵呵起码我写的程序是这样的,因为我刚开始学,还不是很懂各方面的程序优化)*/#include <pic.h>__CONFIG(0x3F32); //芯片配置字#define uchar unsigned char#define uint unsigned intvoid delay10ms(uchar x);void beep();void init();uchar key;uchar LED_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf};void keyscan(){uchar temp;PORTB=0x07;//将列线置0,行线作为输入状态检测。

temp=PORTB;//读回B端口状态值if((temp&0x07)!=0x07)//将读取的值跟0x07做与运算然后再判断是否不等于0x07,如果不等于说明有按键按下{delay10ms(1);//延时10毫秒,去抖动(去干扰)PORTB=0x07;//同上temp=PORTB;//同上if((temp&0x07)!=0x07)//延时消抖后再次判断是否真的有按键按下,如果有再判断是此行的哪个按键(这里我们用的是3x3矩阵键盘,则每行有3种情况){PORTB=0x37;//第一行状态temp=PORTB;//读回B端口状态值switch(temp)//判断第一行按键按下后可能产生的情况{case 0x33:key=7;break;//第一种情况:1号按键按下_0B0011 0011case 0x35:key=4;break;//第二种情况:2号按键按下_0B0011 0101case 0x36:key=1;break;//第三种情况:3号按键按下_0B0011 0110}PORTB=0x2F;//第二行状态temp=PORTB;//读回B端口状态值switch(temp)//判断第二行按键按下后可能产生的情况{case 0x2b:key=8;break;//第一种情况:4号按键按下_0B0010 1011case 0x2d:key=5;break;//第二种情况:5号按键按下_0B0010 1101case 0x2e:key=2;break;//第三种情况:6号按键按下_0B0011 1110 }PORTB=0x1F;//第三行状态temp=PORTB;//读回B端口状态值switch(temp)//判断第三行按键按下后可能产生的情况{case 0x1b:key=9;break;//第一种情况:7号按键按下_0B0001 1011 case 0x1d:key=6;break;//第二种情况:8号按键按下_0B0001 1101 case 0x1e:key=3;break;//第三种情况:9号按键按下_0B0001 1110 }}}}void main(){init();//系统初始化PORTD=LED_CODE[10];//上电数码管显示“—”while(1){PORTB=0x07;if(PORTB!=0x07)//判断有无按键按下有则执行按键处理程序{keyscan();//调用扫描子程序PORTD=LED_CODE[key];//显示对应键号PORTB=0x07;//重新赋值if(PORTB!=0x07)//再次判断有无按键按下按下蜂鸣器响一声{beep(); //调用蜂鸣器子函数}while(PORTB!=0x07)//按键松手检测,如果按键一直按下关闭蜂鸣器 {RE1=0;delay10ms(1);}}}}void init()//系统初始化程序{TRISB=0x07;//低三位,行作为输入TRISD=0;//D端口设置为输出TRISA=0;//A端口设置为输出TRISE=0;//E端口设置为输出PORTA=0;//A端口全部设置为低电平,位选开放PORTD=0xFF;//D端口全部设置为高电平,段选关闭数码管不亮。

51单片机矩阵键盘扫描程序

51单片机矩阵键盘扫描程序
void Timer0_isr(void) interrupt 1
{
TH0=(65536-2000)/256;//重新赋值2ms
TL0=(65536-2000)%256;
Display(0,8); //调用数码管扫描
}
/*------------------------------------------------
unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71};//显示段码值0~F
unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码
case 0xd7:return 11;break;//b
case 0xee:return 12;break;//c
case 0xed:return 13;break;//d
case 0xeb:return 14;break;//e
case 0xe7:return 15;break;//f
default:return 0xff;break;
}
}
/*------------------------------------------------
uS延时函数,含有输入参数unsigned char t,无返回值
unsigned char是定义无符号字符变量,其值的范围是
0~255这里使用晶振12M,精确延时请使用汇编,大致延时
长度如下T=tx2+5 uS

51单片机矩阵键盘行扫描

51单片机矩阵键盘行扫描

51单⽚机矩阵键盘⾏扫描————————————————————————————————————————————分类:按结构原理分:触点式开关按键⽆触点开关按键接⼊⽅式独⽴式按键矩阵式键盘————————————————————————————————————————————矩阵式键盘识别⽅法(⾏扫描法)检测列线的状态:列线Y4~Y7置⾼电平,⾏线Y0~Y3置低电平。

只要有⼀列的电平为低,则表⽰键盘该列有⼀个或多个按键被按下。

若所有列线全为⾼电平,则键盘中⽆按键按下。

判断闭合按键所在的位置:⾏线置⾼电平,列线置低电平。

检测⾏线的状态。

举例:当按下第⼀⾏第⼀列的按键时⾏扫描,⾏线为低电平,列线为⾼电平,得到 1110 0000列扫描,⾏线为⾼电平,列线为低电平,得到 0000 1110将得到的结果进⾏或运算,得到 1110 1110,对应第⼀⾏第⼀列,⼗六进制为0xEE按键表⾏列bin hex111110 11100xEE121101 11100xDE131011 11100xBE140111 11100x7E211110 11010xED221101 11010xDD231011 11010xBD240111 11010x7D311110 10110xEB321101 10110xDB331011 10110xBB340111 10110x7B411110 01110xE7421101 01110xD7431011 01110xB7440111 01110x77————————————————————————————————————————————矩阵式键盘应⽤实例实现结果:通过4*4矩阵键盘对应数码管显⽰0~F设计思路:当检测到按键被按下时,将此时⾏扫描的结果存⼊临时变量,再进⾏列扫描,得到的结果和临时变量进⾏或运算。

通过数组存放按键和数码管编码,⾏列扫描得到结果后遍历数组,找到对应的编码位置并显⽰数码管编码实现代码:1 #include <reg52.h>2 typedef unsigned char uchar;3 typedef unsigned int uint;4 uchar code KEY_TABLE[] =5 {60xEE, 0xDE, 0xBE, 0x7E,70xED, 0xDD, 0xBD, 0x7D,80xEB, 0xDB, 0xBB, 0x7B,90xE7, 0xD7, 0xB7, 0x7710 };11 uchar code TABLE[] =12 {130x3F, 0x06, 0x5B, 0x4F,140x66, 0x6D, 0x7D, 0x07,150x7F, 0x6F, 0x77, 0x7C,160x39, 0x5E, 0x79, 0x71,17 };18void Delay(uchar m)19 {20 --m;21 }22void main()23 {24 uchar temp, key, i;25while(1)26 {27 P3 = 0xF0;28if (P3 != 0xF0)29 {30 Delay(2000);31if (P3 != 0xF0)32 {33 temp = P3;34 P3 = 0x0F;35 key = temp | P3;36for (i = 0; i < 16; ++i)37if (key == KEY_TABLE[i])38break;39 P2 = TABLE[i];40 }41 }42 }43 }。

单片机矩阵键盘行列扫描程序学习资料

单片机矩阵键盘行列扫描程序学习资料
switch(key)
{
case 0x7e:P0=dofly[0];break;//0按下相应的键显示相对应的码值
case 0x7d:P0=dofly[1];break;//1
case 0x7b:P0=dofly[2];break;//2
case 0x77:P0=dofly[3];break;//3
case 0xbe:P0=dofly[4];break;//4
case 0xbd:P0=dofly[5];break;//5
case 0xbb:P0=dofly[6];break;//6
case 0xb7:P0=dofly[7];break;//7
case 0xde:P0=dofly[8];break;//8
if(cord_h!=0x0f) //先检测有无按键按下
{
delay(100); //去抖
if(cord_h!=0x0f)
{
cord_h=P3&0x0f; //读入列线值
P3=cord_h|0xf0; //输出当前列线值
cord_l=P3&0xf0; //读入行线值
return(cord_h+cord_l);//键盘最后组合码值
0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F
uchar keyscan(void);
void delay(uint i);
void main()
{
uchar key;
P2=0x00;//1数码管亮按相应的按键,会显示按键上的字符
while(1)
{
key=keyscan();//调用键盘扫描,
//行列扫描程序,可以自己定义端口和扫描方式,这里做简单介绍

51单片机04矩阵按键逐行扫描行列扫描代码

51单片机04矩阵按键逐行扫描行列扫描代码

矩阵键盘扫描原理方法一:逐行扫描:我们可以通过高四位轮流输出低电平来对矩阵键盘进行逐行扫描,当低四位接收到的数据不全为1的时候,说明有按键按下,然后通过接收到的数据是哪一位为0来判断是哪一个按键被按下。

方法二:行列扫描:我们可以通过高四位全部输出低电平,低四位输出高电平。

当接收到的数据,低四位不全为高电平时,说明有按键按下,然后通过接收的数据值,判断是哪一列有按键按下,然后再反过来,高四位输出高电平,低四位输出低电平,然后根据接收到的高四位的值判断是那一行有按键按下,这样就能够确定是哪一个按键按下了。

//行列扫描#include<reg51.h>#define GPIO_KEY P0#define GPIO_LCD P2unsigned char code a[17]={~0xfc,~0x60,~0xda,~0xf2,~0x66,~0xb6,~0xbe,~0xe0,~0xfe,~0xf6,~0xee,~0x3e,~0x9c,~0x7a,~0xde,~0x8e,~0x00}; //按位取反的用法void delay10ms();void keydown();//要与下面的定义一致void main(){GPIO_LCD=a[16];//初始化数码管while(1){keydown();}}void delay10ms(){unsigned char a,b;for(a=38;a>0;a--)for(b=130;b>0;b--);}void keydown()//检测按下,按下时需要消抖,检测松开,返回按键值//没有按键时保持{unsigned char n=0,key;GPIO_KEY=0x0f;if(GPIO_KEY!=0x0f)//读取按键是否按下{delay10ms(); //延时10ms消抖if(GPIO_KEY!=0x0f)//再次检测按键是否按下{GPIO_KEY=0x0f;//测试列switch(GPIO_KEY){case 0x07: key=0;break;case 0x0b: key=1;break;case 0x0d: key=2;break;case 0x0e: key=3;break;default : GPIO_LCD=a[16];}GPIO_KEY=0xf0;//测试行switch(GPIO_KEY){case 0x70: key=key;break;case 0xb0: key=key+4;break;case 0xd0: key=key+8;break;case 0xe0: key=key+12;break;default : GPIO_LCD=a[16];}GPIO_LCD=a[key];while(++n<5&&GPIO_KEY!=0xf0)//检测按键是否松开 {delay10ms();}}}}//逐行扫描#include<reg51.h>#define GPIO_KEY P0#define GPIO_LED P2unsigned char code a[17]={~0xfc,~0x60,~0xda,~0xf2,~0x66,~0xb6,~0xbe,~0xe0,~0xfe,~0xf6,~0xee,~0x3e,~0x9c,~0x7a,~0xde,~0x8e,~0x00}; //按位取反的用法void delay10ms();void keydown1();//要与下面的定义一致void main(){GPIO_LED=a[16];//初始化数码管while(1){keydown1();}}void keydown1(){unsigned char n=0,key;GPIO_KEY=0x0f;if(GPIO_KEY!=0x0f)//检测按键是否按下{delay10ms();//延时10ms消抖if(GPIO_KEY!=0x0f)//再次检测{GPIO_KEY=0x7f;//高四位轮流输出低电平 if(GPIO_KEY!=0x7f){switch(GPIO_KEY){case 0x77: key=0;goto AA;case 0x7b: key=1;goto AA;case 0x7d: key=2;goto AA;case 0x7e: key=3;goto AA;}}GPIO_KEY=0xbf;if(GPIO_KEY!=0xbf)switch(GPIO_KEY){case 0xb7: key=4;goto AA; case 0xbb: key=5;goto AA; case 0xbd: key=6;goto AA; case 0xbe: key=7;goto AA; }}GPIO_KEY=0xdf;if(GPIO_KEY!=0xdf){switch(GPIO_KEY){case 0xd7: key=8;goto AA; case 0xdb: key=9;goto AA; case 0xdd: key=10;goto AA; case 0xde: key=11;goto AA; }}GPIO_KEY=0xef;if(GPIO_KEY!=0xef)switch(GPIO_KEY){case 0xe7: key=12;goto AA;case 0xeb: key=13;goto AA;case 0xed: key=14;goto AA;case 0xee: key=15;goto AA;}}GPIO_LED=a[16];goto BB;AA: GPIO_LED=a[key];BB: GPIO_KEY=0x0f;while(++n<5&&GPIO_KEY!=0x0f) delay10ms();//调用函数别忘记() }}}void delay10ms(){unsigned char a,b;for(a=38;a>0;a--)for(b=130;b>0;b--); }。

单片机控制的矩阵键盘扫描程序集

单片机控制的矩阵键盘扫描程序集

单片机控制的矩阵键盘扫描程序集各种各样的矩阵键盘扫描程序集矩阵键盘的扫描对初学者来说是不可避免的,然而也相对来说有点难度.鉴于此,我整理了一下,我所遇到的矩阵键盘扫描程序集,将相继贴上来,供大家参考! 说明:这些大多都是网上转贴来的,其所有权归原作者!谢谢合作.最简单矩阵键盘扫描程序key:MOV p0,#00001111b;上四位和下四位分别为行和列,所以送出高低电压检查有没有按键按下jmp k10;跳到K10处开始扫描,这里可以改成其它条件转移指令来决定本次扫描是否要继续,例如减1为0转移或者位为1或0才转移,这主要用来增加功能,确认上一按键功能是否完成?是否相当于经过了延时?是否要封锁键盘?goend:jmp kend;如果上面判断本次不执行键盘扫描程序,则立即转到程序尾部,不要浪费CPU的时间k10:jb p0.0,k20;扫描正式开始,先检查列1四个键是否有键按下,如果没有,则跳到K20检查列2k11:MOV p0,#11101111b;列1有键按下时,P0.0变低,到底是那一个键按下?现在分别输出各行低电平jb p0.0,k12;该行的键不按下时,p0.0为高电平,跳到到K12,检查其它的行MOV r1,#1;如果正好是这行的键按下,将寄存器R0写下1,表示1号键按下了k12:MOV p0,#11011111bjb p0.0,k13MOV r1,#2;如果正好是这行的键按下,将寄存器R0写下2,表示2号键按下了k13:MOV p0,#10111111bjb p0.0,k14MOV r1,#3;如果正好是这行的键按下,将寄存器R0写下3,表示3号键按下了k14:MOV p0,#01111111bjb p0.0,kend;如果现在四个键都没有按下,可能按键松开或干扰,退出扫描(以后相同)MOV r1,#4如果正好是这行的键按下,将寄存器R0写下4,表示4号键按下了jmp kend;已经找到按下的键,跳到结尾吧k20:jb p0.1,k30;列2检查为高电平再检查列3、4k21:MOV p0,#11101111b;列2有健按下时,P0.0会变低,到底是那一行的键按下呢?分别输出行的低电平jb p0.1,k22;该行的键不按下时p0.0为高电平,跳到到K22,检查另外三行MOV r1,#5;如果正好是这行的键按下,将寄存器R0写下5,表示5号键按下了(以后相同,不再重复了)k22:MOV p0,#11011111bjb p0.1,k23MOV r1,#6k23:MOV p0,#10111111bjb p0.1,k24MOV r1,#7k24:MOV p0,#01111111bjb p0.1,kendMOV r1,#8jmp kend;已经找到按下的键,跳到结尾吧(以后相同,不要重复了)k30:jb p0.2,k40k31:MOV p0,#11101111bjb p0.2,k32MOV r1,#9k32:MOV p0,#11011111bjb p0.2,k33MOV r1,#10k33:MOV p0,#10111111bjb p0.2,k34MOV r1,#11k34:MOV p0,#01111111bjb p0.2,kendMOV r1,#12jmp kendk40:jb p0.3,kendk41:MOV p0,#11101111bjb p0.3,k42MOV r1,#13k42:MOV p0,#11011111bjb p0.3,k43MOV r1,#14k43:MOV p0,#10111111bjb p0.3,k44MOV r1,#15k44:MOV p0,#01111111bjb p0.3,kendMOV r1,#16kend: ret行列扫描键盘可检测出双键按下#include <reg52.h>#define ulong unsigned long#define uint unsigned int#define uchar unsigned charextern void delay(unsigned int x);unsigned char Tab_key[]= //行列式键盘映射{0x00, //无键按下’’7’’,’’8’’,’’9’’,’’/’’,’’4’’,’’5’’,’’6’’,’’*’’,’’1’’,’’2’’,’’3’’,’’-’’,’’C’’,’’0’’,’’=’’,’’+’’,//下面为按’’C’’同时再按的键:’’7’’,’’8’’,’’9’’,’’/’’,’’4’’,’’5’’,’’6’’,’’*’’,’’1’’,’’2’’,’’3’’,’’-’’,’’0’’,’’=’’,’’+’’,};// P1口行列式键盘//#define KEYPIN_L P1 // 定义键扫描列端口为P1低四位输入//#define KEYPIN_H P1 // 定义键扫描行端口为P1高四位扫描输出//// P1口行列式键盘////公用函数unsigned char KeysCAN(void); // 键扫描函数// //内部私有函数unsigned char fnKeycode(unsigned char key); // 根据键盘映射表输出顺序键值///*// P1口行列式键盘//extern unsigned char KeysCAN(void); // 键扫描函数//*/// P1口行列式键盘////---------------------------------------------------------------------------//unsigned char KeysCAN(void) // 键扫描函数//{unsigned char sccode,recode,keytemp = 0;KEYPIN_L = KEYPIN_L|0x0f; // P1低四位为列线输入//KEYPIN_H = KEYPIN_H&0x0f; // P1高四位为行线发全零扫描码//if ((KEYPIN_L&0x0f) != 0x0f){delay(10); // 延时10 MS 消抖//if ((KEYPIN_L&0x0f) != 0x0f){sccode = 0xef; // 逐行扫描码初值(1110 1111) //while(sccode != 0xff) //将扫描4次,keytemp为每次键值相或的值//{KEYPIN_H = sccode; // 输出行扫描码//if ((KEYPIN_L&0x0f) != 0x0f) // 本行有键按下//{recode = (KEYPIN_L&0x0f)|0xf0; // 只要低位,高位置1 //keytemp |= (~sccode)+(~recode); //特征码(高位为列P3,低位为行KEYPIN_H) //}sccode = (sccode << 1)|0x01; // 扫描码0向高位移动//}}}KEYPIN_H = KEYPIN_H|0xf0;return(fnKeycode(keytemp));}//---------------------------------------------------------------------------//unsigned char fnKeycode(unsigned char key) // 根据键盘映射表输出顺序键值//{switch(key){case 0x11: // 1 键//key = 0x01;break;case 0x21: // 2 键// key = 0x02;break;case 0x41: // 3 键// key = 0x03;break;case 0x81: // 4 键// key = 0x04;break;case 0x12: // 5 键// key = 0x05;break;case 0x22: // 6 键// key = 0x06;break;case 0x42: // 7 键// key = 0x07;break;case 0x82: // 8 键// key = 0x08;break;case 0x14: // 9 键// key = 0x09;break;case 0x24: // 10 键// key = 0x0A;break;case 0x44: // 11 键// key = 0x0B;break;case 0x84: // 12 键// key = 0x0C;break;case 0x18: // 13 键// key = 0x0D;break;case 0x28: // 14 键// key = 0x0E;break;case 0x48: // 15 键// key = 0x0F;break;case 0x88: // 16 键// key = 0x10;break;//以下为功能键//case 0x19: // ’’C’’ +1 键//key = 0x11;break;ca se 0x29: // ’’C’’ +2 键//key = 0x12;break;case 0x49: // ’’C’’ +3 键//key = 0x13;break;case 0x89: // ’’C’’ +4 键//key = 0x14;break;case 0x1A: // ’’C’’ +5 键// key = 0x15;break;case 0x2A: // ’’C’’ +6 键// key = 0x16;break;case 0x4A: // ’’C’’ +7 键// key = 0x17;break;case 0x8A: // ’’C’’ +8 键// key = 0x18;break;case 0x1C: // ’’C’’ +9 键//key = 0x19;break;case 0x2C: // ’’C’’ +10 键// key = 0x1A;break;case 0x4C: // ’’C’’ +11 键// key = 0x1B;break;case 0x8C: // ’’C’’ +12 键// key = 0x1C;break;// case 0x18: // ’’C’’ +13 键// // key = 0x1D;// break;case 0x38: // ’’C’’ +14 键// key = 0x1D;break;case 0x58: // ’’C’’ +15 键// key = 0x1E;break;case 0x98: // ’’C’’ +16 键// key = 0x1F;break;default : // 无键//key = 0x00;break;}return(Tab_key[key]);}矩键查寻键值44程序与显示#include <reg52.h>//#include <math.h>#include <intrins.h>#define uchar unsigned char#define TURE 1#define FALSE 0int key;int del;void Tkey(void);void led(void);/************主程序*************/void main(void){void tkey(void);void led(void);void delay(int);SCON=0x00;TI=0;while(TURE){Tkey();led();delay(2000);}}/********矩键查寻键值4*4程序******/按键为P1.0---P1.7 void Tkey(void){uchar readkey;//rereadkey;uchar x_temp,y_temp;P1=0x0f;x_temp=P1&0x0f;if(x_temp==0x0f) goto keyout;P1=0xf0;y_temp=P1&0xf0;readkey=x_temp|y_temp;readkey=~readkey;switch(readkey){case 0x11:key=0; break;case 0x21:key=1; break;case 0x41:key=2; break;case 0x81:key=3; break;case 0x12:key=4; break;case 0x22:key=5; break;case 0x42:key=6; break;case 0x82:key=7; break;case 0x14:key=8; break;case 0x24:key=9; break;case 0x44:key=10;break;case 0x84:key=11;break;case 0x18:key=12;break;case 0x28:key=13;break;case 0x48:key=14;break;case 0x88:key=15;break;default: key=16;break;}keyout:_nop_();}/************显示程序*************/void led(void){uchar code LEDValue[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; //0-9 uchar data num[6];uchar k;num[0]=0;num[1]=0;num[2]=0;num[3]=0;num[4]=key/10;num[5]=key-(key/10)*10;for(k=0;k<=5;k++){SBUF=LEDValue[num[5-k]];while(TI==0);TI=0;}}/************延时程序*************/void delay(del){for(del;del>0;del--);;伪定义KEYBUF EQU 30H ;键值暂存单元,查表时用;*************************************;* *;* 主程序和中断程序入口*;* *;*************************************ORG 0000H ;程序执行开始地址AJMP MAIN ;跳至MAIN执行;*************************************;* *;* 主程序*;* *;*************************************ORG 0040HMAIN: MOV P1,#0FFHMOV P3,#0FFHLCALL KEYSCAN ;主体程序。

单片机矩阵键盘扫描的两种方式

单片机矩阵键盘扫描的两种方式

单片机矩阵键盘扫描的两种方式单片机矩阵键盘扫描的两种方式矩阵键盘扫描方式:第一种:逐行扫描法,就是一行一行的扫描。

实现代码如下(键盘连接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; }。

51单片机4×4矩阵按键扫描方法

51单片机4×4矩阵按键扫描方法
{
key=0xf0;//低四位为0
if(key==0xf0)//若无变化,证明按键松开
return 0;//返回0
else//否则,按键未松开
return 1;//返回1
}
//*********主函数*********//
int main()
{
key=0xff;//按键初始化
led=0xff;//关闭LED灯
//送至led显示
/*
eg:如果是第三行第二列按键按下
则第3个、第6(2列+4)个LED灯亮
如下图所示(Proteus仿真电路图)
*/
}
}
led_arry[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//数组定义,便于显示
//******检测是否有按键按下*****//
uchar Check_Button()
{
key=0x0f;//高四位为0
if(key==0x0f)//若无变化,证明无按键按下
return 0;//返回0
else//否则
return 1;//返回1
}
//********行检测********//
uchar Line[]={0x0e,0x0d,0x0b,0x07}; //那个按键按下,检测出的状态则对应数组中的第几个数
void Check_Line()
{
uchar i;
key=0x0f;//高四位为0
/*****4×4按键扫描******/
/***编程要点
1.首先检测是否有按键按下
2.若有按键按下,即进行行检测,列检测
3.行检测:高4位设为0,低4位为1,进行检测0x0f

矩阵键盘过程及扫描程序

矩阵键盘过程及扫描程序

键盘是单片机常用输入设备,在按键数量较多时,为了节省I/O口等单片机资源,一般采取扫描的方式来识别到底是哪一个键被按下。

即通过确定被按下的键处在哪一行哪一列来确定该键的位置,获取键值以启动相应的功能程序。

矩阵键盘的四列依次接到单片机的P1.0~P1.3,四行依次接到单片机的P1.4~P1.7;同时,将列线上拉,通过10K电阻接电源。

查找哪个按键被按下的方法为:一个一个地查找。

先第一行输出0,检查列线是否非全高;否则第二行输出0,检查列线是否非全高;否则第三行输出0,检查列线是否非全高;如果某行输出0时,查到列线非全高,则该行有按键按下;根据第几行线输出0与第几列线读入为0,即可判断在具体什么位置的按键按下。

下面是具体程序:void Check_Key(void){unsigned char row,col,tmp1,tmp2;tmp1 = 0x10;//tmp1用来设置P1口的输出,取反后使P1.4~P1.7中有一个为0for(row=0;row<4;row++) // 行检测{P1 = 0x0f; // 先将p1.4~P1.7置高P1 =~tmp1; // 使P1.4~p1.7中有一个为0tmp1*=2; // tmp1左移一位if ((P1 & 0x0f) < 0x0f)// 检测P1.0~P1.3中是否有一位为0,只要有,则说明此行有键按下,进入列检测{tmp2 = 0x01; // tmp2用于检测出哪一列为0for(col =0;col<4;col++) // 列检测{if((P1 & tmp2)==0x00)// 该列如果为低电平则可以判定为该列{key_val =key_Map[ row*4 +col ];// 获取键值,识别按键;key_Map为按键的定义表return; // 退出循环}tmp2*=2; // tmp2左移一位}}}} //结束。

单片机矩阵键盘行列扫描程序

单片机矩阵键盘行列扫描程序

//行列扫描程序,可以自己定义端口和扫描方式,这里做简单介绍#include <>//包含头文件#define uchar unsigned char#define uint unsigned intunsigned char const dofly[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//0-Fuchar keyscan(void);void delay(uint i);void main(){uchar key;P2=0x00;//1数码管亮按相应的按键,会显示按键上的字符while(1){key=keyscan();//调用键盘扫描,switch(key){case 0x7e:P0=dofly[0];break;//0 按下相应的键显示相对应的码值case 0x7d:P0=dofly[1];break;//1case 0x7b:P0=dofly[2];break;//2case 0x77:P0=dofly[3];break;//3case 0xbe:P0=dofly[4];break;//4case 0xbd:P0=dofly[5];break;//5case 0xbb:P0=dofly[6];break;//6case 0xb7:P0=dofly[7];break;//7case 0xde:P0=dofly[8];break;//8case 0xdd:P0=dofly[9];break;//9case 0xdb:P0=dofly[10];break;//acase 0xd7:P0=dofly[11];break;//bcase 0xee:P0=dofly[12];break;//ccase 0xed:P0=dofly[13];break;//dcase 0xeb:P0=dofly[14];break;//ecase 0xe7:P0=dofly[15];break;//f}}}uchar keyscan(void)//键盘扫描函数,使用行列反转扫描法{uchar cord_h,cord_l;//行列值P3=0x0f; //行线输出全为0cord_h=P3&0x0f; //读入列线值if(cord_h!=0x0f) //先检测有无按键按下{delay(100); //去抖if(cord_h!=0x0f){cord_h=P3&0x0f; //读入列线值P3=cord_h|0xf0; //输出当前列线值cord_l=P3&0xf0; //读入行线值return(cord_h+cord_l);//键盘最后组合码值 }}return(0xff); //返回该值}void delay(uint i)//延时函数{while(i--);}。

矩阵键盘的三种扫描方法

矩阵键盘的三种扫描方法

矩阵键盘的三种扫描方法矩阵键盘是一种常见的输入设备,它由多个按键组成,并通过矩阵扫描的方式来检测用户的按键输入。

矩阵键盘的扫描方法可以分为三种:行扫描、列扫描和交错扫描。

下面将详细介绍这三种扫描方法。

1.行扫描行扫描是最简单的一种扫描方法。

它的原理是将矩阵键盘的每一行连接到一个IO口,通过轮询检测每一行的电平变化来获取用户的按键输入。

行扫描的工作流程如下:1)将矩阵键盘的每一行连接到一个IO口,并设置为输入模式。

2)逐个地将每一行的IO口设置为高电平,并检测列的电平状态。

3)如果其中一列的电平为低电平,说明该列有按键按下。

此时,记录下这个按键的位置(行号和列号)以及按键的值(键码或字符),然后将这个按键的位置和值传递给上层应用或处理器。

4)将当前行的IO口设置为低电平,然后继续下一行的检测,重复2)~3)步骤,直到所有行都被检测完毕。

行扫描的优点是实现简单,只需要一个IO口来检测按键的状态。

但是它的缺点是扫描速度较慢,因为需要逐个地检测每一行。

2.列扫描列扫描是一种比较常用的扫描方法。

它的原理是将矩阵键盘的每一列连接到一个IO口,通过轮询检测每一列的电平变化来获取用户的按键输入。

列扫描的工作流程如下:1)将矩阵键盘的每一列连接到一个IO口,并设置为输入模式。

2)逐个地将每一列的IO口设置为高电平,并检测行的电平状态。

3)如果其中一行的电平为低电平,说明该行有按键按下。

此时,记录下这个按键的位置(行号和列号)以及按键的值(键码或字符),然后将这个按键的位置和值传递给上层应用或处理器。

4)将当前列的IO口设置为低电平,然后继续下一列的检测,重复2)~3)步骤,直到所有列都被检测完毕。

列扫描的优点是速度较快,因为只需要逐个地检测每一列。

但是它的缺点是需要多个IO口来检测按键的状态。

3.交错扫描交错扫描是一种综合了行扫描和列扫描的扫描方法,它可以有效地减少扫描的时间。

交错扫描的原理是将矩阵键盘的行和列交错地连接到多个IO口,通过并行检测行和列的电平变化来获取用户的按键输入。

经典的矩阵键盘扫描程序

经典的矩阵键盘扫描程序

经典的矩阵键盘扫描程序矩阵键盘是一种常见的输入设备,广泛应用于电子产品中。

为了实现对矩阵键盘的扫描和输入响应,需要编写一个矩阵键盘扫描程序。

本文将详细介绍如何编写一个经典的矩阵键盘扫描程序。

1. 程序功能描述矩阵键盘扫描程序的主要功能是实现对矩阵键盘的扫描,并根据按键的状态进行相应的处理。

程序需要实现以下功能:- 扫描矩阵键盘的按键状态;- 根据按键状态进行相应的处理;- 输出按键的值或执行相应的操作。

2. 程序设计思路矩阵键盘通常由多行多列的按键组成,每个按键都有一个唯一的行列地址。

程序的设计思路如下:- 初始化矩阵键盘的引脚和状态变量;- 循环扫描矩阵键盘的按键状态;- 检测按键状态变化,并根据变化进行相应的处理;- 输出按键的值或执行相应的操作。

3. 程序代码示例下面是一个简单的矩阵键盘扫描程序的代码示例:```#include <stdio.h>#include <stdbool.h>// 定义矩阵键盘的行列数#define ROWS 4#define COLS 4// 定义矩阵键盘的引脚int rowPins[ROWS] = {2, 3, 4, 5}; int colPins[COLS] = {6, 7, 8, 9}; // 定义矩阵键盘的按键值char keys[ROWS][COLS] = {{'1', '2', '3', 'A'},{'4', '5', '6', 'B'},{'7', '8', '9', 'C'},{'*', '0', '#', 'D'}};// 初始化矩阵键盘void setup() {// 设置引脚模式为输入for (int i = 0; i < ROWS; i++) { pinMode(rowPins[i], INPUT); }// 设置引脚模式为输出for (int i = 0; i < COLS; i++) {pinMode(colPins[i], OUTPUT);}}// 扫描矩阵键盘void scanKeypad() {for (int i = 0; i < COLS; i++) {// 将当前列引脚设置为高电平digitalWrite(colPins[i], HIGH);for (int j = 0; j < ROWS; j++) {// 检测当前行引脚的状态bool state = digitalRead(rowPins[j]); // 如果按键状态发生变化if (state != lastState[i][j]) {// 更新按键状态lastState[i][j] = state;// 如果按键被按下if (state == LOW) {// 输出按键的值Serial.println(keys[j][i]);// 执行相应的操作switch (keys[j][i]) {case '1':// 执行操作1break;case '2':// 执行操作2break;// 其他按键的操作}}}}// 将当前列引脚设置为低电平 digitalWrite(colPins[i], LOW); }}void loop() {// 扫描矩阵键盘scanKeypad();// 延时一段时间,避免频繁扫描delay(10);}```4. 程序运行结果编写完成矩阵键盘扫描程序后,可以将程序上传到相应的开发板或单片机上进行测试。

51单片机的矩阵按键扫描的设计C语言程序

51单片机的矩阵按键扫描的设计C语言程序

51单片机的矩阵按键扫描的设计C语言程序以下为一个基于51单片机的矩阵按键扫描的设计C语言程序:```c#include <reg51.h>//定义端口连接到矩阵键盘sbit col1 = P2^0;sbit col2 = P2^1;sbit col3 = P2^2;sbit row1 = P2^3;sbit row2 = P2^4;sbit row3 = P2^5;sbit row4 = P2^6;//声明按键函数char read_keypad(;void maiwhile (1)char key = read_keypad(; // 读取按键值//根据按键值进行相应操作switch(key)case '1'://第一行第一列按键逻辑//在此处添加相应的代码break;case '2'://第一行第二列按键逻辑//在此处添加相应的代码break;//继续处理其他按键//...default://未识别到按键break;}}//按键扫描函数char read_keypacol1 = 0; col2 = 1; col3 = 1; // 激活第一列if (row1 == 0) { // 第一行第一列按键被按下while (row1 == 0); //等待按键释放return '1'; // 返回按键值}if (row2 == 0) { // 第二行第一列按键被按下while (row2 == 0); //等待按键释放return '4'; // 返回按键值}if (row3 == 0) { // 第三行第一列按键被按下while (row3 == 0); //等待按键释放return '7'; // 返回按键值}if (row4 == 0) { // 第四行第一列按键被按下while (row4 == 0); //等待按键释放return '*'; // 返回按键值}col1 = 1; col2 = 0; col3 = 1; // 激活第二列//处理第二列的按键逻辑//...col1 = 1; col2 = 1; col3 = 0; // 激活第三列//处理第三列的按键逻辑//...return '\0'; // 返回空字符表示未检测到按键```以上代码中,我们使用51单片机的P2端口连接到矩阵键盘的列和行,通过扫描不同的列和检测行的状态来判断按键是否被按下。

概述矩阵式按键行列扫描过程

概述矩阵式按键行列扫描过程

1111
矩阵式按键行列扫描的过程是这样的:
1. 把属于列的IO口设置为输入状态,由于上拉电阻的作用,当按键没有动作时,程序就会读到高电平。

2. 开始按行进行扫描,先把行1的IO设置为输出状态,然后设置输出为低电平,接着依次读取列IO口的状态。

3. 如果有按键被按下,那么列IO口的读入电平就变成低电平,这时就可以根据行和列判断出动作按键的位置。

4. 行1的扫描完成后,把行1的IO置高,然后按照上面步骤依次进行行2和行3的扫描,确认有动作按键的位置即可。

在实际应用中,为避免按键抖动影响,需要在程序中加入去抖动处理。

矩阵按键扫描广泛应用于各种设备的按键输入控制中,如电子琴、钢琴、智能家居等。

单片机89C52行列式键盘扫描程序(汇编)

单片机89C52行列式键盘扫描程序(汇编)

实验八键盘扫描显示实验所需软硬件:KeilSTC-ISPMCS-51 89C52实验箱程序清单:基于汇编语言//连线P0接8列(同时也是数码管的位选线)高电平选中某位。

P3低两位接行P1接数码管(段选线)低电平选中某段亮。

ORG 0000HLJMP MAINMAIN:MOV 30H,#00HMOV 31H,#00HMOV 32H,#00HMOV 33H,#00HMOV 34H,#00HMOV 35H,#00HBEGIN:ACALL SCANACALL CHECKACALL DISPSJMP BEGIN//子程序SCAN 全扫描2次扫描去抖SCAN: ;全扫描MOV R0,#00H ;去抖,扫描2次计数标志MOV A,#00HMOV P0,A ;送列扫描码LOOP:MOV A,P3 ;回读行信号ANL A,#03H ;只取低两位INC R0CJNE A,#03H,K1CLR F0 ;无键,置标志位为0K1:NOPNOPCJNE R0,#02H,LOOP;去抖,扫描2次SETB F0 ;有键,置标志位为1RET//子程序CHECK 逐列扫描确定键码CHECK:MOV R1,#0FEH ;开始逐列扫描,从第0列开始MOV R4,#00H ;记录列号MOV R5,#00H ;记录行号MOV A,R1PUSH ACC ;压栈保留第0列扫描码LOOP1:MOV P0,A ;送列扫描码MOV A,P3ANL A,#03HCJNE A,#03H,K2 ;有键转K2确定为哪一行POP ACC ;无键扫描下一列RL AINC R4CJNE R4,#08H,LOOP1 ; 是否扫描进行到最后一列RETK2:DEC SP ;为保证堆栈平衡CJNE A,#02H,K3 ;分支判断,看是否为第一行SJMP OVERK3:INC R5 ;不是第一行,就是第二行,行码加1 OVER:MOV A,R4ADD A,R5 ;行码+列码=键码PUSH ACC ;键码入栈保护NOPNOPLCALL SCAN ;扫描看手是否松开CJNE A,#03H,OVER ;A=03H,表示手未松开,继续扫描POP ACC ;手松开,键码出栈RET//子程序DISP 键码分离送数码管显示DISP:JNB F0,LOOP3 ;无键不分离键码MOV B,#10 ;有键,要进行十位和个位的分离DIV ABMOV 34H,A ;A为十位MOV 35H,B ;B为个位MOV R0,#30H ;送显示缓冲首地址MOV R2,#01H ;送位选信号,从最低位开始亮LOOP3:MOV A,#0FFHMOV P1,A ;段选:送灭码MOV A,R2MOV P0,A ;送位选信号MOV A,@R0 ;送显示缓冲数据MOV DPTR,#TAB ;查表求字形码MOVC A,@A+DPTRMOV P0,A ;送段选ACALL DELAY1MS ;延时以保持稳定INC R0 ;取下一个数MOV A,R2JB ACC.5,EXIT ;判断位选是否送到最高位RL A ;左移选下一个位。

89c52单片机矩阵键盘扫描法

89c52单片机矩阵键盘扫描法
case(0xdd):display(5);break;
case(0xbd):display(6);break;
case(0x7d):display(7);break;
}
P1=0xfb;//第3行为0,检测是否有键按下
temp=P1;
switch(temp)
{
case(0xeb):display(8);break;
//共阳数码管显示字型码数组1011 1111 "-"
void delay(uint i);
void display(uint k);
void beep();
void delay1();
void main()
{
uchar temp,tt;
display(16); //初始显示"-"
while(1)
{
{
;
}
}
void beep()
{
P3=0xbf;//P3.6
delay1();
P3=0xff;
delay1();
}
P1=0xff; //先向P1口写1;端口读状态
P1=0xf0; //行全为0
temp=P1; //检测是否有键按下
if(temp!=0xf0)
{
delay(15); //消抖
if(temp!=0xf0)
{
P1=0xfe;//第一行为0,检测是否有键按下
temp=P1;
switch(temp)
{
case(0xee):display(0);break;
break;
case(0xd7):display(13);break;
case(0xb7):display(14);break;

单片机矩阵键盘扫描步骤

单片机矩阵键盘扫描步骤
1.在判断是否有键按下及扫描前清空按键位置;//因为获取到的键位置是一次性的,在发挥完其功效后就没用了,应当立即清空,至少要在下次扫描前清空,一可作为无按键按下的标志(因为只有按键按下才会赋予其非空值),二可防止无按键按下时继承原按键位置,使程序出错。
2.判断是否有键按下//而不是直接进行逐行扫描可节省无按键按下时键盘扫描所占机时
3.若有键按下,为断按下的是哪个键,进行逐行扫描,获取P1口状态并转化为按键位置,一旦得到按键位置立即停止扫描
4.若没有键按下,则按键位置保持空状态

单片机典型矩阵键盘扫描程序

单片机典型矩阵键盘扫描程序

单片机典型矩阵键盘扫描程序#include "Key.h"static uchar GetKeyStatus();////$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$bit KeyProcess() // 为程序方便而设的返回值{uchar i,j;void (*pFunction)(); // 定义函数指针void (*code Tab[mHorizontalNumber][mVerticalNumber])()= // 定义函数表{ { ZeroKey, OneKey, FourKey, SevenKey },{ DotKey, TwoKey, FiveKey, EightKey },{ NegativeKey, ThreeKey, SixKey, NineKey },{ EnterOrShiftKey, CancelKey, OptionKey, PauseKey }}; // 二维数组,对对应16个按键NOP(); NOP();if(!bScanKey)return 0; // 扫描时间未到,返回(时间值在定时器中设定)bScanKey=0;NOP(); NOP();j=GetKeyStatus(); // 取键值,0xff为无效键,即无按键NOP(); NOP();if(bKeyDown||bKeyPress||bKeyUp){i=j>>4; j=j&0x0f; // 高半字节为行,低半字节为列if((i<mHorizontalNumber)&&(j<mVerticalNumber)){pFunction=Tab[j]; // 指向函数入口地址(*pFunction)(); // 调用函数}}}//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ // 判断按键状态:KeyFree,KeyDown,KeyPress,KeyUp,并返回键值//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ static uchar ucKey1,ucKey2,ucKeyBak;static uchar GetKeyCode();static uchar GetKeyStatus(){uchar c;NOP(); NOP();mHorizontalAllLow; // 行输入全为0mJugeVertical(c); // 判断是否有按键NOP(); NOP();if((ucKey1==0xff)&&(ucKey2==0xff)&&(c==0xff)){ // 三个值均为0xff,无按键bKeyDown=bKeyPress=bKeyUp=0;bKeyFree=TRUE; return 0xff; // 没按键}else{bKeyFree=0;if(c!=0xff)c=GetKeyCode(); // 扫描键值if((ucKey1==0xff)&&(ucKey2==c)){ucKey1=ucKey2; ucKey2=c;bKeyDown=TRUE; return c; // 键被按下}if((ucKey1==ucKey2)&&(ucKey2==c)){NOP();if(bKeyDown){bKeyPress=TRUE; // 键被按住bKeyDown=0;}return c;}if((ucKey1!=0xff)&&(ucKey2==0xff)&&(c==0xff)){ucKeyBak=ucKey1; ucKey1=ucKey2; ucKey2=c;if(bKeyPress){bKeyUp=TRUE; // 键弹起bKeyPress=0;}return ucKeyBak;}ucKey1=ucKey2; ucKey2=c;}return 0xff;}//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$// 本程序读按键的行列号值,将行列号组合成一个字节后返回, //// 若读键错误,或没按键均返回0xff。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F
uchar keyscan(void);
void delay(uint i);
void main()
{
uchar key;
P2=0x00;//1数码管亮按相应的按键,会显示按键上的字符
while(1)
{
key=keyscan();//调用键盘扫描,
switch(key)
{
case 0x7e:P0=dofly[0];break;//0按下相应的键显示相对应的码值
case 0x7d:P0=dofly[1];break;//1
case 0x7b:P0=dofly[2];break;//2
case 0x77:P0=dofly[3];break;//3
//行列扫描程序,可以自己定义端口和扫描方式,这里做简单介绍
#include <reg52.h>//包含头文件
#define uchar unsigned char
#define uint unsigned int
unsigned char const dofly[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
case 0xdd:P0=dofly[9];break;//9
case 0xdb:P0=dofly[10];break;//a
case 0xd7:P0=dofly[11];break;//b
case 0xee:P0=dofly[12];break;//c
case 0xed:P0=dofly[13];break;//d
if(cord_h!=0x0f) //先检测有无按键按下
{
delay(100); //去抖
if(cord_h!=0x0f)
{
cord_h=P3&0x0f; //读入列线值
P3=cord_h|0xf0; //输出当前列线值
cord_l=P3&0xf0; //读入行线值
return(cord_h+cord_l);//键盘最后组合码值
case 0xbe:P0=dofly[4];break;//4
case 0xbd:P0=doP0=dofly[6];break;//6
case 0xb7:P0=dofly[7];break;//7
case 0xde:P0=dofly[8];break;//8
}
}return(0xff); //返回该值
}
void delay(uint i)//延时函数
{
while(i--);
}
case 0xeb:P0=dofly[14];break;//e
case 0xe7:P0=dofly[15];break;//f
}
}
}
uchar keyscan(void)//键盘扫描函数,使用行列反转扫描法
{
uchar cord_h,cord_l;//行列值
P3=0x0f; //行线输出全为0
cord_h=P3&0x0f; //读入列线值
相关文档
最新文档