#include
#include
#define uchar unsigned char
#define uint unsigned int
uchar key_scan(); uchar key;
void SendOneByte(unsigned char c)
{
SBUF = c;
while(TI==0);
TI = 0;
}
void delay(uint k) //延时程序
{
uint i,j;
for(i=k;i>0;i--)
for(j=110;j>0;j--);
}
void main() //主程序
{ uchar b;
TMOD = 0x20; //定时器T1的工作方式2,8位数据自动重装
SCON = 0x50; //串行口的方式1,8位异步收发,波特率可变。
TH1 = 0xfd; // 装定时器1初值.
TL1 = 0xfd;
PCON = 0x00;
EA = 1; //开总中断
ES = 1; //串行口中断源允许
TR1 = 1; //开定时器1
while(1) //循环开始
{
b=key_scan();
switch(b)
{
case 1: SendOneByte('1'); break;
case 2: SendOneByte('2'); break;
case 3: SendOneByte('3'); break;
case 4: SendOneByte('4'); break;
case 5: SendOneByte('5'); break;
case 6: SendOneByte('6'); break;
case 7: SendOneByte('7'); break;
case 8: SendOneByte('8'); break;
case 9: SendOneByte('9'); break;
case 0: SendOneByte('0'); break;
case 11:SendOneByte('U'); break;
case 12:SendOneByte('Y'); break;
case 13:SendOneByte('N'); break;
case 14:SendOneByte('L'); break;
case 15:SendOneByte('D'); break;
case 16:SendOneByte('R'); break;
default :break;
}
}
}
uchar key_scan()
{
uchar cord_h,cord_l,x;//行列值
P1=0xf0; //行线输出全为0
cord_h=P1&0xf0; //读入列线值
if(cord_h!=0xf0) //先检测有无按键按下
{
delay(80); //去抖
if(cord_h!=0xf0)
{
cord_h=P1&0xf0; //读入列线值
P1=cord_h|0x0f; //输出当前列线值
cord_l=P1&0x0f; //读入行线值
x=cord_h+cord_l;//键盘最后组合码值
switch ( x )
{
case 0xee: key=1; break;
case 0xde: key=2; break;
case 0xbe: key=3; break;
case 0x7e: key=4; break;
case 0xed: key=5; break;
case 0xdd: key=6; break;
case 0xbd: key=7; break;
case 0x7d: key=8; break;
case 0xeb: key=9; break;
case 0xdb: key=0; break;
case 0xbb: key=11; break;
case 0x7b: key=12; break;
case 0xe7: key=13; break;
case 0xd7: key=14; break;
case 0xb7: key=15; break;
case 0x77: key=16; break;
}
}
}
return key;
}
我觉你的这个问题的原因是:b的值在上一次按键按下后就是一个固定的值了,比如你按下0xee之后,在按下第二个键之前,b的值就一直都是1,
所以while循环里会一直发送1.所以你需要在没有按键按下的时候,让keyscan()返回一个while的switch中没有的值,也就是执行default。
switch ( x )
{
case 0xee: key=1; break;
case 0xde: key=2; break;
case 0xbe: key=3; break;
case 0x7e: key=4; break;
case 0xed: key=5; break;
case 0xdd: key=6; break;
case 0xbd: key=7; break;
case 0x7d: key=8; break;
case 0xeb: key=9; break;
case 0xdb: key=0; break;
case 0xbb: key=11; break;
case 0x7b: key=12; break;
case 0xe7: key=13; break;
case 0xd7: key=14; break;
case 0xb7: key=15; break;
case 0x77: key=16; break;
}
在这个switch中加一个default:key=0;break;
switch ( x )
{
case 0xee: key=1; break;
case 0xde: key=2; break;
case 0xbe: key=3; break;
case 0x7e: key=4; break;
case 0xed: key=5; break;
case 0xdd: key=6; break;
case 0xbd: key=7; break;
case 0x7d: key=8; break;
case 0xeb: key=9; break;
case 0xdb: key=0; break;
case 0xbb: key=11; break;
case 0x7b: key=12; break;
case 0xe7: key=13; break;
case 0xd7: key=14; break;
case 0xb7: key=15; break;
case 0x77: key=16; break;
default:key=0;break;
}
https://zhidao.baidu.com/question/301276513.html
你想要实现的是不是当检测到按键值时 只通过串口发送一次而不是连续发送吗?
思路为: 在串口发送函数前 判定本次按键值是否和上次检测的按键值相同, 如不同则表示有按键按下,发送键盘指令。相同无按键按下,不发送
在main函数外 定义1全局变量
prekeystate = 0; 上次检测按键状态
nowkeystate = 0; 本次检测全局变量
while(1) //循环开始
{
nowkeystate =key_scan(); //读取本次按键值
if( nowkeystate != prekeystate ) //判定键值是否发生变化
{
switch(nowkeystate) //变化后 发送变化后的键值 只发送一次
{
……
}
prekeystate = nowkeystate; //更新前次按键值 确保只发送一次
}
希望可以帮助你
你的key定义成局部变量就可以了,我觉得不需要定义成全局变量。
每次按键按下后把b清零就可以了