我本意是想使用按键通过中断方式实现流水灯,但是现在按键还没按下就开始流水灯了,麻烦各位指点一二
代码里没有按键识别,k1虽然定义为p30口,代码里没有读取判断按键状态的代码,需要在while(1){按键读取代码},然后根据按键是否按下,控制中断允许或禁止,从而控制流水灯。
不知道你这个问题是否已经解决, 如果还没有解决的话:问题解答:
由于没有提供具体的代码,所以无法直接检查哪个地方逻辑有误。我们可以根据参考资料提供的代码来进行修改,实现按键中断流水灯的效果。
1.首先,需要添加外部中断相关的代码。在参考代码中,开启了定时器0中断,我们可以在按键按下时调用一个外部中断来触发流水灯的效果,具体代码如下:
#include <reg52.h>
typedef unsigned int u16;
typedef unsigned char u8;
#define LED P0
#define KEY P1
bit LED_flag = 0; //定时到1s的标志位
u8 n; //循环变量,用作LED总线的位索引index
void InitTimer0(void); //定时器0,初始化
void ExtInt_Init(void); //外部中断初始化
void main()
{
LED = 0xFE; //初始值,最右边的灯亮
InitTimer0();
ExtInt_Init();
while(1)
{
if(LED_flag == 1)
{
LED_flag = 0;
LED = (LED >> 1) | 0x80; //LED右移,最左边的灯亮
}
}
}
void InitTimer0(void)
{
TMOD |= 0x01; //用|=防止配置冲突
TH0 = (65536 - 50000)/256; ///定时器0,置初值(定时50ms)
TL0 = (65536 - 50000)%256;
EA = 1;
ET0 = 1;
TR0 = 1;
}
void Timer0() interrupt 1 //定时器0,中断服务函数
{
static u16 i;
TH0 = (65536 - 50000)/256; ///定时器0,重装初值(定时50ms)
TL0 = (65536 - 50000)%256;
i++;
if(i==20) // 1s = 20 × 50ms
{
i=0;
LED_flag=1;
}
}
void ExtInt_Init(void) //外部中断初始化
{
EA = 1;
EX0 = 1; //开INT0中断
IT0 = 0; //设定INT0下降沿触发
}
void Int0() interrupt 0 //外部中断0处理函数
{
LED = 0xFE; //按下按键,最右边灯亮
}
2.修改正常计时的流水灯效果。在以上代码中,定时器0定时50ms,20次中断即1s。在每次中断发生时,右移LED的值,实现流水灯的效果。由于LED的最左边一位要一直保持高电平,所以每次右移需要在最左边位写入1,同时在参考代码中,初始值是最右侧一位高电平,所以需要将LED的初始值改为0xFE(二进制11111110),最右侧一位为低电平,其他全是高电平,代码中已经做了修改。
这样的流水灯效果实现不需要按下按键即可开始,按下按键后最右侧一位就亮了,然后开始流水灯效果。如果需要按下按键后流水灯才开始,可以在初始化时将LED的值赋为0xFF,也就是所有灯都不亮,等待按键触发后开始流水灯效果。