在老师布置作业时,遇到一个问题。用独立按键控制LED流水灯,要求按一次K1左移,按K2实现右移,持续1S。且要在当前的LED位置实现切换方向。一开始做的时候,一直要等待亮完一次之后在某个节点按下按钮才能实现切换,无法实现按下按键切换马上切换。理论上来说,用中断可以很容易解决这个问题,但如果没有中断呢?该如何实现,我们是否可以将延时时间等分成无限小份?
要解决的问题有:
①如何实现按键按下立马切换,而不是要长按才能切换。
②如何实现在当前位置切换,而不是从头开始。
#include"reg51.h"
#include"intrins.h"
typedef unsigned char u8;
typedef unsigned int u16;
#define LED P2
sbit S0=P3^0;
sbit S1=P3^1;
u8 LED_TEMP=0;
u16 i;
void Delay1ms() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
void LED1()
{
S0=1;S1=1;
if(S0==0)
{
if(LED_TEMP!=0){LED=LED_TEMP;}
else {LED=~0x01;}
while(1)
{
for(i=0;i<1000;i++){Delay1ms();if(S1==0)break;}
LED_TEMP=LED;
LED=_crol_(LED,1);
if(S1==0)break;
}
}
if(S1==0)
{
if(LED_TEMP!=0){LED=LED_TEMP;}
else {LED=~0x80;}
while(1)
{
for(i=0;i<1000;i++){Delay1ms();if(S0==0)break;}
LED_TEMP=LED;
LED=_cror_(LED,1);
if(S0==0)break;
}
}
}
void main()
{
while(1)
{
LED1();
}
}
完整代码如上。
要解决第一个问题,我们可以设置一个变量LED_TEMP,当我们刚开启单片机时,其值为0。LED每切换一次就让其更新保存一次值。当另一个按键按下的时候,其值不为0,就让LED直接获取LED_TEMP的值。就可解决问题①
要解决第二个问题,我们可以让延时函数设置为1ms,相当于把1s等分成1000份,这样子就可以实现按下即立刻切换。因为如果我们直接设置1S的延时,必须要让1S的延时结束才可以继续执行下一步的语句,就会导致必须长按才可以切换,达不到即按即切换的切换。
如有更好的办法,欢迎交流。
作者能力有限,大佬勿喷。