1、大家好,这是一个简易的加法计算器,为什么按键没有反应呢?只有按第一个键是管用的,之后再按其他的键就不管用了,请问是哪里出现了错误呢。数码管是共阴数码管。
#include
typedef unsigned char u8;
typedef unsigned int u16;
#define GPIO_LED P0
#define GPIO_KRY P1
sbit LSA = P2^4;
sbit LSB = P2^5;
sbit LSC = P2^6;//38译码器
sbit KEY_OUT_0 = P1^0;
sbit KEY_OUT_1 = P1^1;
sbit KEY_OUT_2 = P1^2;
sbit KEY_OUT_3 = P1^3;
sbit KEY_IN_0 = P1^4;
sbit KEY_IN_1 = P1^5;
sbit KEY_IN_2 = P1^6;
sbit KEY_IN_3 = P1^7;//矩阵按键的输入和输出
u8 code smgduan[16]=
{0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71};//显示0~F的值
u8 LEDbuff[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };//用于接受数码管的真正显示值
u8 keysta[4][4] = {{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};//用于判断按键的最后状态
u8 code keycodemap[4][4] =
{
{ 0x31, 0x32, 0x33, 0x26 },//数字键1, 数字键2, 数字键3, 向上键
{ 0x34, 0x35, 0x36, 0x25 },//数字键4, 数字键5, 数字键6, 向左键
{ 0x37, 0x38, 0x39, 0x24 },//数字键7, 数字键8, 数字键9, 向下键
{ 0x30, 0x1B, 0x0D, 0x17 } //数字键0, 数字键ESC, 回车键, 向右键
};//矩阵按键的键值设定
void IniTimer0()
{
TMOD |= 0x01;
TH0 = 0xFC;
TL0 = 0x18;//定时1ms
EA = 1;
ET0 = 1;
TR0 = 1;
}//定时器0中断函数
void ShowNumber(u8 num)
{
u8 i;
u8 buff[8];
for(i=0; i<8; i++)
{
buff[i] = num % 10;
num = num / 10;
}
for(i=7; i>=0; i--)
{
if(buff[i] == 0)
LEDbuff[i] = 0x00;
else
break;
}
for(; i>=0; i--)
{
LEDbuff[i] = smgduan[buff[i]];
}
}//将数字分解为单个数字,并消去高位的0
void KeyAction(u8 keycode)
{
static u16 result = 0;
static u16 add = 0;
if((keycode >= 0x30) && (keycode <= 0x39))
{
add = (add * 10) + (keycode - 0x30);
ShowNumber(add);
}
else if(keycode == 0x26 || keycode == 0x0D)
{
result += add;
add = 0;
ShowNumber(result);
}
else if(keycode == 0x1B)
{
add = 0;
result = 0;
ShowNumber(result);
}
}//为键值赋予动作指令
void Keypros()
{
u8 i = 0;
u8 j = 0;
for(i=0; i<4; i++)
{
for(j=0; j<4; j++)
{
if(keysta[i][j] == 0)
{
KeyAction(keycodemap[i][j]);
}
while(!keysta[i][j]);
}
}
}//判断消抖后按键确实按下之后
void main()
{
IniTimer0();
LEDbuff[0] = smgduan[0];
while(1)
{
Keypros();
}
}
void KeyScan()
{
static u8 keyout = 0;
u8 i = 0;
static u8 keybuf[4][4] =
{
{0xFF, 0xFF, 0xFF,0xFF},
{0xFF, 0xFF, 0xFF,0xFF},
{0xFF, 0xFF, 0xFF,0xFF},
{0xFF, 0xFF, 0xFF,0xFF},
};
keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KEY_IN_0;
keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KEY_IN_1;
keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KEY_IN_2;
keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KEY_IN_3;
for(i=0; i<4; i++)
{
if((keybuf[keyout][i] & 0x0F) == 0x00)
{
keysta[keyout][i] = 0;
}
else if((keybuf[keyout][i] & 0x0F) == 0x0F)
{
keysta[keyout][i] = 1;
}
else
{
}
}
keyout++;
keyout = keyout & 0x03;//这样处理可以实现4变为0,例如0000 0100&0000 0011 = 0000 0000
switch(keyout)
{
case 0: KEY_OUT_3 = 1;KEY_OUT_0 = 0;break;
case 1: KEY_OUT_0 = 1;KEY_OUT_1 = 0;break;
case 2: KEY_OUT_1 = 1;KEY_OUT_2 = 0;break;
case 3: KEY_OUT_2 = 1;KEY_OUT_3 = 0;break;
default:break;
}
}//扫描按键,判断按键的情况并小区抖动
void SmgScan()
{
u8 i = 0;
GPIO_LED = 0x00;
switch(i)
{
case(0): LSA=0; LSB=0; LSC=0; i++; GPIO_LED = LEDbuff[0];break;
case(1): LSA=1; LSB=0; LSC=0; i++; GPIO_LED = LEDbuff[1];break;
case(2): LSA=0; LSB=1; LSC=0; i++; GPIO_LED = LEDbuff[2];break;
case(3): LSA=1; LSB=1; LSC=0; i++; GPIO_LED = LEDbuff[3];break;
case(4): LSA=0; LSB=0; LSC=1; i++; GPIO_LED = LEDbuff[4];break;
case(5): LSA=1; LSB=0; LSC=1; i++; GPIO_LED = LEDbuff[5];break;
case(6): LSA=0; LSB=1; LSC=1; i++; GPIO_LED = LEDbuff[6];break;
case(7): LSA=1; LSB=1; LSC=1; i=0; GPIO_LED = LEDbuff[7];break;
default:break;
}
}
void InterruptTimer0() interrupt 1
{
TH0 = 0xFC;
TL0 = 0x18;//定时1ms
SmgScan();
KeyScan();
}
不知道你这个问题是否已经解决, 如果还没有解决的话: