当我们按下矩阵按键中不同的按键时,在LCD1602显示相应的内容,同时一个按键按下多次可以切换不同的字母或数字,并且LED灯会闪烁。最后当我们按下确认时,蜂鸣器会发出不同频率的声音。
蜂鸣器,AT89C51,若干按键,LCD1602,两支LED灯,排阻
如果使用独立按键与单片机连接, 每一个按键都需要单片机的一个 I/O 口, 若某单片机系统需较多按键, 用独立按键便会占用过多的 I/O 口资源。 单片机系统中 I/O 口资源往往比较宝贵, 当用到多个按键时为了减少 I/O 口引脚, 引入了矩阵按键。
按键检测一般通过扫描来实现,先使某一列变为低电平,其余几列为高电平,后检测每行是否出现低电平。若没有出现,则某行按键没有被按下,若出现则说明按键被按下,即可锁定位置。
①行列式法:
上图将第一列全部置0,其余位置均为1
将第一行全部置0,其余位全部置1。
因此我们可以得出按键按下的正是第一行第一列的
②线翻转法:
首先使所有行置为0,然后检测列是否含有低电平,如果有,则记录列的位置;之后再翻转,使所有列置为0,检测行是否有低电平,如果有,则记录行的位置(本文采用的是线翻转法)
#include
#include
void delay(unsigned char ms);
void delay2(int i);
void lcd_wcmd(unsigned char cmd);
void lcd_pos(unsigned char pos);
void lcd_wdat(unsigned char dat);
void lcd_init();
void xianshi();
void KeyDown();
void la_ba();
sbit rs= P2^6;
sbit rw = P2^5;
sbit ep = P2^7;
sbit d=P3^0;
sbit d1=P3^1;
sbit lb=P3^2;
int b,c,s=0,q=0,w=0;
#define GPIO_KEY P1
unsigned char dis1[32];
unsigned char dis2[9]={',','A','D','G','J','M','P','T','W'};
unsigned char dis3[9]={'1','2','3','4','5','6','7','8','9'};
unsigned int code laba[36][5]={
1,2,3,3,3,//A
2,1,1,1,3,//B
2,1,2,1,3,//C
2,1,1,3,3,//D
1,3,3,3,3,//E
1,1,2,1,3,//F
2,2,1,3,3,//G
1,1,1,1,3,//H
1,1,3,3,3,//I
1,2,2,2,3,//J
2,1,2,3,3,//K
1,2,1,1,3,//L
2,2,3,3,3,//M
2,1,3,3,3,//N
2,2,2,3,3,//0
1,2,2,1,3,//P
2,2,1,2,3,//Q
1,2,1,3,3,//R
1,1,1,3,3,//S
2,3,3,3,3,//T
1,1,2,3,3,//U
1,1,1,2,3,//V
1,2,2,3,3,//W
2,1,1,2,3,//X
2,1,2,2,3,//Y
2,2,1,1,3,//Z
2,2,2,2,2,//0
1,2,2,2,2,//1
1,1,2,2,2,//2
1,1,1,2,2,//3
1,1,1,1,2,//4
1,1,1,1,1,//5
2,1,1,1,1,//6
2,2,1,1,1,//7
2,2,2,1,1,//8
2,2,2,2,1,//9
};
// LCD1602代码开始
bit lcd_bz()
{
bit result;
rs = 0;
rw = 1;
ep = 1;
_nop_();
_nop_();
_nop_();
_nop_();
result = (bit)(P0 & 0x80);
ep = 0;
return result;
}
void lcd_wcmd(unsigned char cmd)
{
while(lcd_bz());//判断LCD是否忙碌
rs = 0;
rw = 0;
ep = 0;
_nop_();
_nop_();
P0 = cmd;
_nop_();
_nop_();
_nop_();
_nop_();
ep = 1;
_nop_();
_nop_();
_nop_();
_nop_();
ep = 0;
}
void lcd_pos(unsigned char pos)
{
lcd_wcmd(pos | 0x80);
}
void lcd_wdat(unsigned char dat)
{
while(lcd_bz());//判断LCD是否忙碌
rs = 1;
rw = 0;
ep = 0;
P0 = dat;
_nop_();
_nop_();
_nop_();
_nop_();
ep = 1;
_nop_();
_nop_();
_nop_();
_nop_();
ep = 0;
}
void lcd_init()
{
lcd_wcmd(0x38);
delay(1);
lcd_wcmd(0x0c);
delay(1);
lcd_wcmd(0x06);
delay(1);
lcd_wcmd(0x01);
delay(1);
}
void xianshi()
{
int i=0,j=1,n=0;
while(dis1[i] != '