经典的矩阵键盘扫描程序查找哪个按键被按下的方法为:一个一个地查找。
先第一行输出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左移一位}}}} //结束这是一种比较经典的矩阵键盘识别方法,实现起来较为简单,程序短小精炼。
4*4矩阵键盘扫描程序/*设置行线为输入线,列线为输出线*/uchar KeyScan(); //按键扫描子程序void delay10ms(); //延时程序uchar key_free(); //等待按键释放程序void key_deal(); //键处理程序//主程序void main(){while(1){KeyScan();key_free();key_deal();}}//按键扫描子程序uchar KyeScan(){unsigned char key,temp;P1=0xF0;if(P1&0xF0!=0xF0){delay10ms(); //延时去抖动if(P1&0xF0!=0xF0){P1=0xFE; //扫描第一列temp=P1;temp=temp&0xF0;if(temp!=0xF0) //如果本列有键按下{switch(temp){case 0xE0: //第一行有键按下key=1;break;case 0xD0: //第二行有键按下key=4;break;case 0xB0: //第三行有键按下key=8;break;case 0x70: //第四行有键按下key=12;break;}}P1=0xFD; //扫描第二列temp=P1;temp&=0xF0;if(temp!=0xF0){switch(temp){case 0xE0: //第一行有键按下key=1;break;case 0xD0: //第二行有键按下key=5;break;case 0xB0: //第三行有键按下key=9;break;case 0x70: //第四行有键按下key=13;break;}}P1=0xFb; //扫描第三列temp=P1;temp&=0xF0;if(temp!=0xF0){switch(temp){case 0xE0: //第一行有键按下key=2;break;case 0xD0: //第二行有键按下key=6;break;case 0xB0: //第三行有键按下key=10;break;case 0x70: //第四行有键按下key=14;break;}}P1=0xF7; //扫描第四列temp=P1;temp&=0xF0;if(temp!=0xF0){switch(temp){case 0xE0: //第一行有键按下key=3;break;case 0xD0: //第二行有键按下key=7;break;case 0xB0: //第三行有键按下key=11;break;case 0x70: //第四行有键按下key=15;break;}}}return(key);}}//延时程序void delay10ms(){unsigned char i,j;for(i=0;i<10;b++)for(j=0;j<120;j++)//延时1ms{}}//等待按键释放程序uchar key_free(){key=key_scan(); //取扫描到的键值P1=0xF0;//置行线全为高电平,列线全为低电平wheile(P1&0xF0!=0xF0) //如果仍有键按下{}return(key);//返回键值}51单片机矩阵键盘扫描、数码管显示键值实验/***********************************************程序名称:矩阵键盘扫描显示键值简要说明:P1口接矩阵键盘:低四位列,高四位行使用共阳型数码管:P0口输出数码管段码,P2口输出数码管位码编写:***********************************************/#include <AT89x52.h>#define uchar unsigned char;uchar key_val=0; //定义键值,初始默认为0uchar code TAB[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xC6,0xa1,0x86,0x8e}; //0~F 共阳数码管显示段码/*****按键扫描*****/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 = row*4 +col; // 获取键值,识别按键return; // 退出循环}tmp2*=2; // tmp2左移一位}}}}/*****主函数,显示键值*****/void main(){P2=0x00; //位码,这里全部置低,点亮8位数码管(见视频效果)while(1){Check_Key();P0=TAB[key_val]; //显示}}实验7 矩阵按键识别技术矩阵按键部分由16个轻触按键按照4行4列排列,连接到JP50端口。
将行线所接的单片机的I/O口作为输出端,而列线所接的I/O口则作为输入。
这样,当按键没有按下时,所有的输出端都是高电平,代表无键按下。
行线输出是低电平,一旦有键按下,则输入线就会被拉低,这样,通过读入输入线的状态就可得知是否有键按下了。
确定矩阵式键盘上何键被按下,介绍一种“行扫描法”。
行扫描法行扫描法又称为逐行(或列)扫描查询法,是一种最常用的按键识别方法.判断键盘中有无键按下:将全部行线置低电平,然后检测列线的状态。
只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平线与4根行线相交叉的4个按键之中。
若所有列线均为高电平,则键盘中无键按下。
判断闭合键所在的位置:在确认有键按下后,即可进入确定具体闭合键的过程。
其方法是:依次将行线置为低电平,即在置某根行线为低电平时,其它线为高电平。
在确定某根行线位置为低电平后,再逐行检测各列线的电平状态。
若某列为低,则该列线与置为低电平的行线交叉处的按键就是闭合的按键。
下面给出一个具体的例子:8031单片机的P1口用作键盘I/O口,键盘的列线接到P1口的低4位,键盘的行线接到P1口的高4位。
列线P1.0-P1.3设置为输入线,行线P1.4-P.17设置为输出线。
4根行线和4根列线形成16个相交点。
1,检测当前是否有键被按下。
检测的方法是P1.4-P1.7输出全“0”,读取P1.0-P1.3的状态,若P1.0-P1.3为全“1”,则无键闭合,否则有键合。
2,去除键抖动。
当检测到有键按下后,延时一段时间再做下一步的检测判断。
3.若有键被按下,应识别出是哪一个键闭合。
方法是对键盘的行线进行扫描。
P1.4-P1.7按下述4种组合依次输出:在每组行输出时读取P1.0-P1.3,若全为“1”,则表示为“0”这一行没有键闭合,否则有键闭合。
由此得到闭合键的行值和列值,然后可采用计算法或查表法将闭合键的行值和列值转换成所定义的键值。
4,为了保证键每闭合一次CPU仅作一次处理,必须去除键释放时的抖动。
实验目的:通过XL2000的16位矩阵按键,在数码管上分别显示0---9,A,B,C,D,E,F。
接线方法:1,用一条8PIN数据排线,把矩阵按键部份的JP50,接到CPU部份的P1口JP44.2,接8位数码管的数据线。
将数码管部份的数据口 JP5接到CPU部份的P0口JP51.3,接8位数码管的显示位线。
将数码管部份的显示位口 JP8接到CPU部份的P2口JP52.参考程序:;本程序实现扫描按键显示功能.;分别按16个键盘显示分别显示数字123A456B789C*0#D ;键盘口P1,数码管显示第二位p21, 数码管段位p0口org 0000h矩阵按键与数码管显示的运行照片3x4矩阵键盘的扫描程序(C语言)3x4矩阵键盘的扫描程序(C语言)按相应的按键,数码管显示相应的数字,星号键和井号键分别显示为E和F #include<AT89X51.h>unsigned char code table[]={0xC0,0xF9,0xA4,0xB0,0x99, //0~40x92,0x82,0xF8,0x80,0x90, //5~90x88,0x83,0xA7,0xA1,0x86,0x8E}; //A~Fvoid KeyScan();void delay10ms(unsigned char time); void Dispaly(unsigned char k);unsigned char key,temp;void main() //主程序{while(1){KeyScan();}}void KeyScan() //按键扫描子程序{P1=0xFF;P1_3=0;temp=P1;temp&=0xF0;if(temp !=0xF0){delay10ms(1);temp=P1;temp&=0xF0;if(temp !=0xF0){temp=P1;temp&=0xF0;switch(temp){case 0x70:key=1;break;case 0xB0:key=2;break;case 0xD0:key=3;break;}Dispaly(key);}}P1=0xFF;P1_2=0;temp=P1;temp&=0xF0;if(temp !=0xF0) {delay10ms(1); temp=P1;temp&=0xF0;if(temp !=0xF0) {temp=P1;temp&=0xF0;switch(temp){case 0x70:key=4;break; case 0xB0:key=5;break; case 0xD0:key=6;break; }Dispaly(key); }}P1=0xFF;P1_1=0;temp=P1;temp&=0xF0;if(temp !=0xF0) {delay10ms(1); temp=P1;temp&=0xF0;if(temp !=0xF0) {temp=P1;temp&=0xF0;switch(temp){case 0x70:key=7;break;case 0xB0:key=8;break;case 0xD0:key=9;break;}Dispaly(key);}}P1=0xFF;P1_0=0;temp=P1;temp&=0xF0;if(temp !=0xF0){delay10ms(1);temp=P1;temp&=0xF0;if(temp !=0xF0){temp=P1;temp&=0xF0;switch(temp){case 0x70:key=14;break;case 0xB0:key=0;break;case 0xD0:key=15;break;}Dispaly(key);}}}//延时程序void delay10ms(unsigned char time) {unsigned char a,b,c;for(a=0;a<time;a++)for(b=0;b<10;b++)for(c=0;c<120;c++);}void Dispaly(unsigned char k) //显示程序{P0=table[k];P2_1=0;}C51矩阵键盘扫描程序代码实例/************************************************************************** * p1.3 p1.2 p1.1 p1.0* -----|----|----|----|-------p1.4* -----|----|----|----|-------p1.5* -----|----|----|----|-------p1.6* -----|----|----|----|-------p1.7* | | | |** 键值排列:* 15 14 13 12* 11 10 9 8* 7 6 5 4* 3 2 1 0****************************************************************************/ #define uchar unsigned char#include <intrins.h>uchar KeyScan(){uchar row = 0; //将行号置0uchar col = 0; //将列号置0uchar mask = 0x7f;uchar pic = 0;uchar key0 = 255;uchar Shift_Count = 0;uchar code Key_value[]={ 0,1,2,3,5,6,7,8,9,10,11,12,13,14,15,16};/* 抖动返回200,无键按下返回255 */P1 &= 0x0f;if (( P1 & 0x0f ) == 0x0f ) {key0 = 255; return (key0);}Delay(50); //延时25mS去抖动if (( P1 & 0x0f ) == 0x0f ) {key0 = 200; return (key0);}/* 有键按下,则分析键所在的列号*/P1 = mask;while (( P1 & 0x0f ) == 0x0f && Shift_Count<3 ){++col; ++Shift_Count;mask = _cror_(mask,1); //右移动一位P1 = mask;}/* 有键按下,则分析键所在的行号*/pic = P1 &0x0f;mask = 0x01;while ( pic & mask ){++row;mask = _crol_(mask,1); //左移一位}/* 得到键值*/pic = row * 4 + col;key0 = Key_value[pic];return (key0);}/************************************************************ * 函数功能:延时程序0.5mS* input: i* output: NULL* mcu: p89c51* frequency: 11.0592M Hz* period: f/6************************************************************/ void Delay(uint i){uchar j;while(i--){for(j=0;j<125;j++);}}/************************************************************************** * p1.3 p1.2 p1.1 p1.0* -----|----|----|----|-------p1.4* -----|----|----|----|-------p1.5* -----|----|----|----|-------p1.6* -----|----|----|----|-------p1.7* | | | |** 键值排列:* 15 14 13 12* 11 10 9 8* 7 6 5 4* 3 2 1 0****************************************************************************/ #define uchar unsigned char#include <intrins.h>uchar KeyScan(){uchar row = 0; //将行号置0uchar col = 0; //将列号置0uchar mask = 0x7f;uchar pic = 0;uchar key0 = 255;uchar Shift_Count = 0;uchar code Key_value[]={ 0,1,2,3,5,6,7,8,9,10,11,12,13,14,15,16};/* 抖动返回200,无键按下返回255 */P1 &= 0x0f;if (( P1 & 0x0f ) == 0x0f ) {key0 = 255; return (key0);}Delay(50); //延时25mS去抖动if (( P1 & 0x0f ) == 0x0f ) {key0 = 200; return (key0);}/* 有键按下,则分析键所在的列号*/P1 = mask;while (( P1 & 0x0f ) == 0x0f && Shift_Count<3 ){++col; ++Shift_Count;mask = _cror_(mask,1); //右移动一位P1 = mask;}/* 有键按下,则分析键所在的行号*/pic = P1 &0x0f;mask = 0x01;while ( pic & mask ){++row;mask = _crol_(mask,1); //左移一位}/* 得到键值*/pic = row * 4 + col;key0 = Key_value[pic];return (key0);}/************************************************************ * 函数功能:延时程序0.5mS* input: i* output: NULL* mcu: p89c51* frequency: 11.0592M Hz* period: f/6************************************************************/ void Delay(uint i){uchar j;while(i--){for(j=0;j<125;j++);}}。