本帖最后由 淡然处世 于 2016-8-8 14:31 编辑
/*希望大神指点一下,问题比较多,我是单片机新手,不知道该怎样改动,搞了一周了,很乱*//*程序:功能要求:按下矩阵键盘按,键串口助手显示键值,P0口接的4*4键盘,P1口接的3*3,P1.7接的独立按键。*/
/*问题:键盘显示值不全,并且相同按键第二次按下后不再显示键值,去掉我加的flag判断语句后,串口就会一直刷新键值;没有按键按下时,也会发送。*/
/* P0.0--P0.0.3是行 0.4--0.7是列, P1.0--1.2行 1.3--1.5列*/ 现在注释了4*4程序后,3*3只显示一部分。/*硬件电路图已经附加,希望大家帮忙看看,能否发我一个程序,串口显示矩阵键盘按键值*/
#include <reg52.h >
#define uchar unsigned char //宏定义,后面所有的uchar,均为 unsigned char
#define uint unsigned int // 宏定义,后面所有的uint,均为 unsigned int
uchar i,j;
static uchar flag; //定义一个静态的全局变量,用来存储键值,进行比较相同不打印
uchar num; //定义的一个全局变量 num;
sbit key3 = P1^7; //将P1.7定义为key3
/*延时函数*/
void delay(uint z)
{
uint i,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
/* 独立按键P1.7 */
uchar keyscan3()
{
// while(1)
// {
if(key3 == 0)
{
while(key3 == 0);
delay(10);
SBUF = 0X25;
while(!TI);
TI = 0;
}
// }
}
/*4*4矩阵键盘P0口,扫描函数*/
/*
uchar keyscan1()
{
uchar temp;
P0 = 0xfe; //1111 1110 第一列线输出一个低电平
temp = P0;
temp = temp&0xf0; //1111 1110 & 1111 0000 = 1111 0000 =0xf0
while((temp&0xf0) != 0xf0) //当有按键按下,则P0值发生改变,
{
delay(5); //延时ms
temp = P0;
temp = temp & 0xf0;
while((temp&0xf0) != 0xf0) //
{
temp = P0;
delay(5);
switch(temp)
{
case 0xee:num = 0; break;
case 0xde:num = 1; break;
case 0xbe:num = 2; break;
case 0x7e:num = 3; break;
}
while(temp != 0xf0)
{
temp = P0;
temp = temp&0xf0;
}
}
}
P0 = 0xfd; // 1111 1101 第二列线输出一个低电平
temp = P0;
temp = temp&0xf0;
while((temp&0xf0) != 0xf0)
{
delay(5);
temp = P0;
temp = temp&0xf0;
while((temp&0xf0) != 0xf0)
{
temp = P0;
delay(5);
switch(temp)
{
case 0xed:num = 4; break;
case 0xdd:num = 5; break;
case 0xbd:num = 6; break;
case 0x7d:num = 7; break;
}
while(temp != 0xf0)
{
temp = P0;
temp = temp&0xf0;
}
}
}
P0 = 0xfb; // 1111 1011 第三列线输出一个低电平
temp = P0;
temp = temp&0xf0;
while((temp&0xf0) != 0xf0)
{
delay(5);
temp = P0;
temp = temp&0xf0;
while((temp&0xf0) != 0xf0)
{
temp = P0;
delay(5);
switch(temp)
{
case 0xeb:num = 8; break;
case 0xdb:num = 9; break;
case 0xbb:num = 10; break;
case 0x7b:num = 11; break;
}
while(temp != 0xf0)
{
temp = P0;
temp = temp&0xf0;
}
}
}
P0 = 0xf7; // 1111 0111 第四列输出一个低电平
temp = P0;
temp = temp&0xf0;
while((temp&0xf0) != 0xf0)
{
delay(5);
temp = P0;
temp = temp&0xf0;
while((temp&0xf0) != 0xf0)
{
temp = P0;
delay(5);
switch(temp)
{
case 0xe7:num = 12; break;
case 0xd7:num = 13; break;
case 0xb7:num = 14; break;
case 0x77:num = 15; break;
}
while(temp != 0xf0)
{
temp = P0;
temp = temp&0xf0;
}
}
}
return num;
}
*/
/*P1口接3*3键盘,扫描函数*/
uchar keyscan2()
{
uchar temp2; //局部变量temp
P1 = 0xfe; //矩阵键盘接在P1口
temp2 = P1;
temp2 = temp2 & 0xf0; //1111 1110 & 1111 0000 = 11110000 =0xf0
while(temp2 != 0xf0) //当有按键按下,则P1值发生改变,
{
delay(5);
temp2 = P1;
temp2 = temp2 & 0xf0;
while(temp2 != 0xf0) //二次判断
{
temp2 = P1;
delay(5);
switch(temp2)
{
case 0xee:num = 0x16; break;
case 0xde:num = 0x17; break;
case 0xbe:num = 0x18; break;
}
while(temp2 != 0xf0)
{
temp2 = P0;
temp2 = temp2 & 0xf0;
}
}
}
P1 = 0xfd;
temp2 = P1;
temp2 = temp2 & 0xf0;
while(temp2 != 0xf0)
{
delay(5);
temp2 = P1;
temp2 = temp2 & 0xf0;
while(temp2 != 0xf0)
{
temp2 = P1;
delay(5);
switch(temp2)
{
case 0xed:num = 0x19; break;
case 0xdd:num = 0x20; break;
case 0xbd:num = 0x21; break;
}
while(temp2 != 0xf0)
{
temp2 = P1;
temp2 = temp2 & 0xf0;
}
}
}
P1 = 0xfb;
temp2 = P1;
temp2 = temp2 & 0xf0;
while(temp2 != 0xf0)
{
delay(5);
temp2 = P1;
temp2 = temp2 & 0xf0;
while(temp2 != 0xf0)
{
temp2 = P1;
delay(5);
switch(temp2)
{
case 0xeb:num = 0x22; break;
case 0xdb:num = 0x23; break;
case 0xbb:num = 0x24; break;
}
while(temp2 != 0xf0)
{
temp2 = P1;
temp2 = temp2 & 0xf0;
}
}
}
return num;
}
/*串口初始化函数*/
void init()
{
TMOD = 0x20; //定时器工作方式一
SCON = 0x50; //允许接收数据
PCON = 0x00; //波特率不加倍
TH1 = 0xfd;
TL1 = 0xfd;
TR1 = 1;
}
/*更新SBUF寄存器*/
void send(uchar dat) //把dat里面的值送到SBUF寄存器,发送数据
{
static uchar flag =100;
if(dat != flag) //判断,按键相同不打印 //我把则条语句删了后,串口一直刷新,依旧有部分键值不显示
{
SBUF = dat;
flag = dat;
while(!TI);
TI = 0; //串口标志,软件清零
}
}
/*主函数*/
void main()
{
uchar temp; //定义P0口按键变量
uchar temp2; //定义P1口按键变量
init();
while (key3 != 0)
{
delay(10);
key3 = keyscan3();
}
while(1)
{
j = keyscan2(); i = keyscan1(); // 调用4*4键盘函数
delay(100);
send(i);
j = keyscan2(); // 调用3*3键盘函数
send(j);
send('*');
}
|