看了下你的程序,没调试过,所以也不能肯定问题出在哪,只是指出以下几点:
1、延时子程序中,注意你用的是uchar j ,j的取值是0~255,你后面要它加到一千多,飞了!最大问题应该在这里,改成 uint j;这应该是你的手误吧,最要命的就是手误。
2、return(key); 这句编译居然可以通过?我看中间连空隔都没有,我没试过,不是应该写成
return key;的吗? 这里key根本就是多余,直接 return j;就行了;
3、注意在给P1口赋值0x0f或0xf0的时候,P1 = 0x0f; 写两句,或者scan1 = P1;连写两句,第二句无实际意义,就是为了增加一个延时,以避免P1口在变化之后马上读取“有可能”(我是说有可能)会读到不稳定的值。这个与语法无关,与硬件特性有关;
4、键盘扫描还是用switch-case语句吧,我不是说你用的查表方式不对,只是将表查过来又读回去,总觉得影响阅读性。你这上下两个表是讲究一一对应性的,排这个表估计就花了不少时间,要一一对应,就用switch-case,必要时候,还可以以一对多;
5、P1=0xff在你这个程序当中,可有可无。它的作用是在读取P1端口前对它进行置1操作,可以使读到稳定的数值,你的程序在线反转法里面,读之前都有一个P1=0X0f,所以,可以省掉前面那句。这句也与语法无关,跟硬件特性有关,不是所有的单片机在读端口前都需要加,在51系列,图个省心,你就加上吧。(不加不一定会错,加了一定不会错。)
先试试吧,如果还是试不出来,明天我帮你调试一下。
共阳数码管怎么输出低电平亮?是不是电路里有反相器?
P27 = 0; //位选左边第一个数码管显示
/*
用线反转法使按矩阵按键按下第一个显示0,第二个显示1 ...,最后一个显示F
P0是数码管(共阳)的段选,P2是位选,P1是矩阵键盘
*/
#include
void delay(void);
unsigned char get_key(void);
sbit P27 = P2^7;
unsigned char code display_key[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf}; //0到F和“-”
unsigned char code key_code[] = {0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,
0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77}; //16个按键的16进制数
void main()
{
unsigned char temp,key;
P0 = 0xbf; //令初始显示为“-”
P27 = 0; //位选左边第一个数码管显示
P1 = 0xff; //P1口的写1操作,顺便问问为什么要写1,单单是P1口需要写1么? P1这里是给个初始值
while(1)
{
P1 = 0xf0;
temp = P1;
if((temp&0xf0) != 0xf0) //判断按键是否按下
{
key = get_key();
P0 = display_key[key]; //数码管显示数字
这里给个延时看下 是不是你太快了
}
}
}
unsigned char get_key(void)
{
unsigned char scan1,scan2,keycode,key,j;
P1 = 0xf0; //这里P1是得到这结果过吗 你这是赋值
scan1 = P1;
if((scan1&0xf0)!= 0xf0) //判断按键是否按下
{
delay(); //延时,除去抖动
scan1 = P1;
if((scan1&0xf0) != 0xf0)
{
P1 = 0x0f; //反转
scan2 = P1;
keycode = scan1|scan2; //得到按键的十六进制数
for(j = 0;j <= 15;j++) //通过for循环找到是第几个按键
{
if(keycode == key_code[j])
{
key = j;
return(key); //返回找到符合的按键
}
}
}
}
}
void delay(void) //延时15ms
{
unsigned char j; // unsigned int j;
for(j = 0;j < 1650;j++)
;
延时函数里的
for(j = 0;j < 1650;j++)
这个句不对吧,自己仔细看下,j能加到>1650吗,死在这了吧!