马老师,你好,帮我看看我的状态机按键,谢谢!!
马老师,你好,我碰到一个按键问题,百思不得其解,所以又来麻烦你了,我是看了你的书以后,用状态机写了一人非矩阵的按键扫描,大至情况是:UP键(可连_发),DOWN键(可连_发),ENTER键,ESC键,问题是:其它的键都好使,就是UP键为什么要按几下它才有反应呀,UP键和DOWN键都是一样的程序,为什么DOWN键就不会,我已经排除了硬件固障,更换了按键还是一样,所以我在想还是程序问题,一直不知怎么回事,所以请教,谢谢先!!按键程序如下:
/******************按键函数***********************************************/
#define key_input PIND // 按键输入口
#define key_mask 0b00001111 // 按键输入屏蔽码
#define key_no 0
#define up 1
#define down 2
#define enter 3
#define esc 4
#define key_state_0 0
#define key_state_1 1
#define key_state_2 2
#define key_state_3 3
#define key_state_4 4
#define key_state_5 5
#define key_state_6 6
unsigned char key_time1=0,key_time2=0,key_return1;
unsigned char read_key(void)
{
static unsigned char key_state = 0,key_old;
unsigned char key_press,key_return=key_no;
key_press = key_input & key_mask; // 读按键I/O电平
switch (key_state)
{
case key_state_0: // 按键初始态
if (key_press != key_mask)
{
key_old = key_press; // 记录原电平
key_state = key_state_1; // 键被按下,状态转换到键确认态
}
break;
case key_state_1: // 按键确认态
if (key_press == key_old) // 与原电平比较(消抖处理)
{
if (key_press == 0b00001110) //UP键检测
{
key_state = key_state_2; // 状态转换到键释放态
key_time1=0;
}
else if(key_press == 0b00001101) //DOWN键检测
{
key_state = key_state_3; // 状态转换到键释放态
key_time2=0;
}
else if (key_press == 0b00001011) //ENTER检测
{
key_return = enter;
key_state = key_state_6; // 状态转换到键释放态
}
else if (key_press == 0b00000111) //ESC键检测
{
key_return = esc;
key_state = key_state_6; // 状态转换到键释放态
}
}
else
key_state = key_state_0; // 按键已抬起,转换到按键初始态
break;
case key_state_2:
if(key_press ==key_mask)
{
key_state = key_state_0;
key_return=up;
}
else if(++key_time1>=100)
{
key_state=key_state_4;
key_time1=0;
key_return=7;//输出为7时产生连_发功能
}
break;
case key_state_3:
if(key_press ==key_mask)
{
key_state = key_state_0;
key_return=down;
}
else if(++key_time2>=100)
{
key_state=key_state_5;
key_time2=0;
key_return=8;//输出为8时产生连_发功能
}
break;
case key_state_4:
if (key_press == key_mask) key_state = key_state_0;//按键已释放,转换到按键初始态
else
{
if(++key_time1>=50)//按键计数时间
{
key_time1=0; //清按键计时
key_return=7;//输出为7时产生连_发功能
}
}
break;
case key_state_5:
if(key_press=key_mask) key_state=key_state_0;
else if(++key_time2>=50)//按键计数时间
{
key_time2=0; //清按键计时
key_return=8;//输出为8时产生连_发功能
}
break;
case key_state_6:
if (key_press == key_mask) key_state = key_state_0;
break;
}
return key_return;
} 程序好象没看出什么问题。你先简化整个系统软件,就测试这个按键部分,看是硬件还是其它软件的影响。 好的,谢谢马老师!!! 马老师,你好,我把UP键的连_发功能去掉了,就不会有那种按键不响应的现象了,但我觉得UP键和DOWN键是一样的,为什么DOWN键就不会有这种现象,现在还是不得其解,郁闷的要命。 把PORTD的低四位都设置成输入方式上拉有效吗? 马老师,你好,我是这样设置低四位的
PORTD|=0X0F;
DDRD&=~0X0F; 其它不变,改动以下一点:
if (key_press == 0b00001101) //UP键检测 =======》UP和DOWN的输入换一下
{
key_state = key_state_2; // 状态转换到键释放态
key_time1=0;
}
else if(key_press == 0b00001110) //DOWN键检测 ======》
{
key_state = key_state_3; // 状态转换到键释放态
key_time2=0;
}
如果此时UP键不好,是程序有问题,如果是DOWN有问题,是输入信号的问题。 马老师,你好,非常感谢您在百忙之中能帮我解答问题
我已经按照您的要求改了一下,变成DOWN键有问题,如你所说是输入信号问题,我不知道输入信号是指哪点。
后来我改了一下key_time1>=100,把它改成key_time1>160,UP键就没问题了。
在后来我就程序没改,什么都没动,直接换了一片单片机,UP键一样好使,一点问题没有,我就奇怪了。
马老师,你能不能帮我讲讲这到底是怎么一回事呀。就上述两种改法。
谢谢!!! mark,以后用的上。 马老师,你好,非常感谢您在百忙之中能帮我解答问题
我已经按照您的要求改了一下,变成DOWN键有问题,如你所说是输入信号问题,我不知道输入信号是指哪点。
后来我改了一下key_time1>=100,把它改成key_time1>160,UP键就没问题了。
在后来我就程序没改,什么都没动,直接换了一片单片机,UP键一样好使,一点问题没有,我就奇怪了。
马老师,你能不能帮我讲讲这到底是怎么一回事呀。就上述两种改法。
谢谢!!!
根据你讲的情况,我估计可能是引脚接触不良问题(是焊接的吗?排除假焊、虚焊等。如果是贴片,PCB弯一弯,或稍微重按芯片就好了等)。
因为程序不动,只是把D0定义由UP变成DOWN(0b00001110),那么DOWN就不正常了,问题很可能出在D0这个脚上。
换了芯片,D0接触好了,或原芯片的D0有问题(如受过电流冲击受过伤)。当然,你已经肯定有上拉了。
time的时间变化应该是假向,因为接触不好什么怪现象都会发生,而且是随机的。
如果是软件问题,不知道你的测试程序是否就只是这个按键代码,如果还有其它的功能代码,还使用了许多中断什么的,就比较复杂了。
因此找BUG,要首先要把你认为可能出问题的代码段独立出来单独调试,一个一个的都没有问题,再逐步合在一起调试。这个需要实践、经验、和时间的积累。 我用的是你的实验板,不是焊接的,是用锁槽,
如果我还是用原来那片单片机,我改一下IO口,比如改成PORTB,PORTA,PORTC,结果还是一样,
纳闷了,不过我还是会去慢慢找,直到找出原因为止。
谢谢马老师!!!! 那可能这块芯片本身不太好了。建议你换一片,如果再发生是再找原因。不要在这里化时间了。 是的,我换了,可以用了,可能买了水货。谢谢了!! mark mark mark mark 没有碰不到的问题,只有想不到的问题。 up与down的按键硬件对调一下,再程序对调一下,这不就检测出问题所在了吗? mark 回复【楼主位】harng
-----------------------------------------------------------------------
mark mark 看不懂 哎 mark,谢谢!
页:
[1]