大家好,今天我来为大家揭开“4x4矩阵键盘驱动程”的神秘面纱。为了让大家更好地理解这个问题,我将相关资料进行了整合,现在就让我们一起来探索吧。
1.单片机中的4×4矩阵键盘的键值怎么求?
2.请帮忙看一下单片机C语言设计4x4矩阵键盘扫描按键的程序
3.51单片机 如何4*4矩阵键盘输入按键 继电器输出信号
4.这是单片机4X4的键盘识别程序,请帮我解释,最好每句执行操作和原理都有,特别是case 0X0e; key=7的原因
5.STC89c52单片机c语言编程。想用4*4矩阵键盘输入一个数(包括两位数),在1602LCD上显示。急求
单片机中的4×4矩阵键盘的键值怎么求?
单片机书上应该有讲的哦,多查资料。
既然是4x4,即4行4列了,共需要8个I/O口,有8bit数据(如高四位为行4bit,低四位为列4bit)位:xxxx xxxx。还要结合你的程序来编码键值,如果有键按下了,查询所有按键的所连接的I/O口电平状态,每个按键需要两个I/O口,一端连接行(行4bit之一),一端连接列(列4bit之一);若此时按键的电平状态为0010 0001,即十六进制数据0x21,按下的按键所对应的键值编码即为0x21。当然为了使用方便,在确定了按下按键的编码后,可对其赋值,我要将它赋值为数字键8,方便后续编程使用。例:
//获取键值编码,由于确定哪个按键按下
uchar keyscan(void)//键盘扫描函数,使用行列反转扫描法
{
uchar cord_h,cord_l;//行列值
P3=0x0f; //行线输出全为0
cord_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); //返回该值
}
while(1)
{
key=keyscan();//调用键盘扫描,
//keyVal=0~15表示按键对应的功能
switch(key)
{
case 0x7e:keyVal=0;break;//0 按下相应的键显示相对应的码值
case 0x7d:keyVal=1;break;//1
case 0x7b:keyVal=2;break;//2
case 0x77:keyVal=3;break;//3
case 0xbe:keyVal=4;break;//4
case 0xbd:keyVal=5;break;//5
case 0xbb:keyVal=6;break;//6
case 0xb7:keyVal=7;break;//7
case 0xde:keyVal=8;break;//8
case 0xdd:keyVal=9;break;//9
case 0xdb:keyVal=10;break;//a
case 0xd7:keyVal=11;break;//b
case 0xee:keyVal=12;break;//c
case 0xed:keyVal=13;break;//d
case 0xeb:keyVal=14;break;//e
case 0xe7:keyVal=15;break;//f
}
请帮忙看一下单片机C语言设计4x4矩阵键盘扫描按键的程序
C51 P1端口 4X4键盘说明
这是一个用C51单片机P1端口制作的4X4键盘,p1端口低4位是键盘列扫描线,高4位是键盘行扫描线,
列扫描线是输出,行扫描线是输入。
下面就程序作一个说明
(***)表示注意点
1、首先判断整个键盘有无按下键,只要行扫描线输入不为全1,(1111)即有键按下;
P1 = 0xf0;if((P1&0xf0)!=0xf0) 如果无按键按下,全1,则返回return -1;
如果有键按下则延时,再次判断有无按键按下,Delay();if((P1&0xf0)!=0xf0)如果无按键按下则返回return -1。
有键按下则继续,这个过程就是判键消抖,避免多次读键值,***或者因为按键抖动到读键值的时候无键按下,发生错误,***列扫描线是输出全0,P1 = 0xf0。
2、进入读键值了,与上面不同,每一次判断,***列扫描线只有一根输出为0,即P1=0xfe,0xfd,0xfb,0xf7;
首先列扫描线P1.0,sCode = 0xfe;如果行扫描线全1,则本列无键按下,扫描下一列
sCode = _crol_(sCode,1); ***sCode左移一位,即0xfd,如此扫描4次,行扫描线都全0,则无键按下,
返回return -1;
如果行扫描线不全0,就是有键按下,现在可以读键值了
kCode = ~P1; //P1=EE,ED...
for(i=0;i<16;i++)
{
if(kCode == KeyCodeTable[i])
return i;
}
1.首先kCode = ~P1;***p1值取反行扫描线可能的是1,2,4,8;同样列扫描线对应值1,2,4,8
合起p1有16个值,就是KeyCodeTable[i]表的x11,0x12,0x14,0x18,0x21,0x22,0x24,0x28,
0x41,0x42,0x44,0x48,0x81,0x82,0x84,0x88
如果 if(kCode == KeyCodeTable[i]) 成立,对应的 i 值就是键号。
2.返回i值就是键号,return i;。
uchar Keys_Scan()
{
uchar sCode,kCode,i,k;
P1 = 0xf0;
if((P1&0xf0)!=0xf0) //扫描列
{
Delay();
if((P1&0xf0)!=0xf0)//消抖
{
sCode = 0xfe;
for(k=0;k<4;k++)
{
P1 = sCode;//查找低位
if((P1&0xf0)!=0xf0)//只有等于才执行else P1和0xf0作与为0xf0 与 同真为真,一假为假
{
kCode = ~P1; //P1=EE,ED...
for(i=0;i<16;i++)
{
if(kCode == KeyCodeTable[i])
return i;
}
}
else
sCode = _crol_(sCode,1);
}
}
}
return -1;
}
51单片机 如何4*4矩阵键盘输入按键 继电器输出信号
void keyscan()//矩阵键盘扫描程序
{
P0=0x0f;
if(P0!=0x0f) //这里条件0,不会执行后面的程序吧
{delay (10);
if(P0!=0x0f)
{
a=P0;
P0=0xf0;
b=P0;
a= a|b;
};
};
}
这是单片机4X4的键盘识别程序,请帮我解释,最好每句执行操作和原理都有,特别是case 0X0e; key=7的原因
........... Inter0_process()?interrupt?2//外部中断1 { Key_scan();//你的键盘扫描程序(中断服务程序),一旦触发中断,将运行至本段。 }//主程序?
main(){?
........... ......................
EX1=1;//开中断一?P3.3 IT1=1;//下降沿触发 ET1=1; EA=1;? ........... ...........}
注:图中的键盘接法都是独立按键接发,
矩阵键盘没有见过能直接触发中断的。
STC89c52单片机c语言编程。想用4*4矩阵键盘输入一个数(包括两位数),在1602LCD上显示。急求
temp等于0x0e时,键值key等于7 : 这个键值是你自己定义的,就是起一个标志位的作用,然后用程序判断键值,当键值等于7时,该进行什么动作,这就相当于当你那个按键按下时执行什么动作
写单片机C程序 一定要活用标志位
还有你好像都大四了,怎么这样普通的矩阵键盘程序还看不懂,该好好学习呀 兄弟
I和J 只是一个变量 用来决定延时时间的长短 延时是为了消除按键的抖动
毕竟机械按键存在抖动(按下去并不是电平直接就跳变并稳定下来了)
延时是软件消抖 增强系统的稳定性
以下程序除了你所提出的要求外,多了个把按的数发送到串口的功能。
#include <reg51.h>
#include <stdio.h>
/*******************************************/
#define uchar unsigned char
#define uint unsigned int
/*******************************************/
#define KEYPORT P1
#define DATAPORT P2
sbit e=P3^5;
sbit rs=P3^6;
sbit rw=P3^7;
/*******************************************/
//4X4键盘
/****************4X4按键******************/
//两个延时
//delay(uint x)
void delay(uint x)
{
uint i, j;
for(i = x; i > 0; i--)
{
for (j = 110; j > 0; j--);
}
}
//delay1(uint x)
void delay1(uint x)
{
uint i, j;
for(i = x; i > 0; i--)
{
for (j = 19; j > 0; j--);
}
}
uchar getkey()
{
uchar PP1=0XFF;
uchar key=0xFF;
KEYPORT=0XF0;
PP1=KEYPORT;
key=(PP1&0XF0);
KEYPORT=0X0F;
PP1 = KEYPORT;
key=(key|(PP1&0X0F));
return key;
}
uchar GETKEY_QUDOU()
{
uchar key=0xff;
while((key=getkey())==0xff);
delay(20);
if(key==getkey())
{
while(getkey()!=0xff);
return key;
}
else
return 0xff;
}
uchar yima(uchar key)
{
uchar ktemp=key;
uchar kval=0xff;
switch (ktemp)
{
case 0xee: kval = 1; break;
case 0xed: kval = 2; break;
case 0xeb: kval = 3; break;
case 0xe7: kval = 4; break;
case 0xde: kval = 5; break;
case 0xdd: kval = 6; break;
case 0xdb: kval = 7; break;
case 0xd7: kval = 8; break;
case 0xbe: kval = 15; break;
case 0xbd: kval = 9; break;
case 0xbb: kval = 0; break;
case 0xb7: kval = 14; break;
case 0x7e: kval = 10; break;
case 0x7d: kval = 11; break;
case 0x7b: kval = 12; break;
case 0x77: kval = 13; break;
default: kval=0xff;break;
}
return kval;
}
uchar keyscan()
{
return yima(GETKEY_QUDOU());
}
uchar wkey()
{
uchar kv=0xff;
while((kv=keyscan())==0xff);
return kv;
}
/*******************************************/
//串口
void s_init()
{
SCON = 0X52;//工作方式1,11.0592M.9600 可接收
TMOD=0X20;
TH1=0XFD;
TL1=0XFD;
TR1=1;
}
/*******************************************/
//LCD1602
/**********************************************/
/**********************************************/
//写命令
void Write_Cmd(uchar com)
{
e=0;
rs=0;
rw=0;
DATAPORT=com;
delay1(10);
e=1;
delay1(25);
e=0;
}
/**********************************************/
//写数据
void Write_Data(uchar dat)
{
e=0;
rs=1;
rw=0;
DATAPORT=dat;
delay1(10);
e=1;
delay1(25);
e=0;
}
/**********************************************/
//lcd1602初始化
void lcd_init()
{
delay(15);
Write_Cmd(0x38);
delay(5);
Write_Cmd(0x38);
delay(5);
Write_Cmd(0x38);
Write_Cmd(0x38);
Write_Cmd(0x01);
Write_Cmd(0x0f);
Write_Cmd(0x06);
//Write_Cmd(0x80+0x042);//写入显示缓冲区起始地址为1行2列
}
void lcd_play(uchar kv)
{
static uchar i=3;
i++;
if(i>=10)
{ i=4;
Write_Cmd(0x01);
}
Write_Cmd(0x80+0x40+i);
Write_Data(kv);
}
/*************************主程序****************************************/
void main()
{
uchar kv=0xff;
s_init();
lcd_init();
printf(" WELCOM TO USE: \n");
while(1)
{
kv=wkey();
if(kv<10)
kv=0x30+kv;
else
kv=kv-10+'A';
printf("CURRENT KEY : %c\n",kv);
lcd_play(kv);
}
}
好了,今天关于“4x4矩阵键盘驱动程”的话题就到这里了。希望大家能够通过我的讲解对“4x4矩阵键盘驱动程”有更全面、深入的了解,并且能够在今后的生活中更好地运用所学知识。