想实现的功能是按键第一次按下LED常亮(状态1),第二次按下LED发出SOS信号(状态2)(使用定时器中断控制LED先200ms闪烁三次,再500ms闪烁三次,再200ms闪烁三次,测试过SOS信号是正常的),第三次按下LED常灭(状态3),以此往复。现在出现了三个状态不稳定的情况(有时会直接跳过某个状态而进入下一个状态),请问是什么原因呢?以下是我的单片机代码
# include <STC8.h>
# include <intrins.h>
sbit KEY = P3 ^ 5;
sbit LED = P3 ^ 4;
unsigned int num = 0;
unsigned int LED_flag = 0;
unsigned int SOS_flag = 0;
void Init_IO()
{
P0M1 = 0x00;
P0M0 = 0x00;
P1M1 = 0x00;
P1M0 = 0x00;
P2M1 = 0x00;
P2M0 = 0x00;
P3M1 = 0x00;
P3M0 = 0x00;
P4M1 = 0x00;
P4M0 = 0x00;
P5M1 = 0x00;
P5M0 = 0x00;
P6M1 = 0x00;
P6M0 = 0x00;
P7M1 = 0x00;
P7M0 = 0x00;
}
void Timer0_Init(void) //20ms@24.000MHz
{
AUXR &= 0x7F; //12T
TMOD &= 0xF0;
TL0 = 0xC0;
TH0 = 0x63;
EA=1;
TF0 = 0;
TR0 = 0;
ET0 = 1;
}
void Timer0_Isr(void) interrupt 1 //SOS信号
{
TL0 = 0xC0;
TH0 = 0x63;
num++;
SOS_flag = 1;
}
void display_sos(unsigned char state)
{
static unsigned char st = 0;
static unsigned char cnt1 = 0;
if(state==0)
{
cnt1 = 0;
st = 0;
num =0;
TL0 = 0xC0;
TH0 = 0x63;
TR0 = 1;//计时开始
}
if(SOS_flag==1)
{
SOS_flag = 0;
if( st == 0)//三短
{
if(num == 10)//200ms
{
num =0;
cnt1++;
if(cnt1==1)
{
LED = 0;
}
else if(cnt1<=7)
{
LED = ~LED;
}
else if(cnt1>7)
{
st = 1;//三短结束,进入下一个状态————三长
}
}
}
if( st == 1)//三长
{
if(num == 25 )//500ms
{
num =0;
cnt1++;
if(cnt1<=13)
{
LED = ~LED;
}
else
{
st = 2;//三长结束,进入下一个状态————三短
}
}
}
if( st == 2)//三短
{
if(num == 10)//200ms
{
num =0;
cnt1++;
if(cnt1<=21)
{
LED = ~LED;
}
else
{
st = 3;//三短结束,进入间隔等待
}
}
}
if( st == 3)//每次sos信号间隔一秒
{
if(num == 50)//1s
{
cnt1++;
num =0;
if(cnt1>21)
{
LED =0;
st = 0;
cnt1=0;
}
}
}
}
}
void display()
{
static unsigned char state = 0;
if (LED_flag == 0)
{
LED = 0;
state = 0;
}
else if (LED_flag == 1)//常亮状态
{
LED = 1;
state = 0;
}
else if (LED_flag == 2)//SOS状态
{
display_sos(state);
state = 1;
}
else if (LED_flag == 3)//常灭状态
{
LED = 0;
state = 0;
}
}
void KeyScan()
{
static unsigned char last_key_state = 1;
static unsigned char cnt = 0;
if (KEY != last_key_state)
{
if (++cnt >= 3)
{
if (last_key_state == 0)
{
if (++LED_flag >= 3)
{
LED_flag = 0;
}
}
cnt = 0;
last_key_state = KEY;
}
}
else
{
cnt = 0;
}
}
void main()
{
LED = 0;
Init_IO();
Timer0_Init();
while (1)
{
KeyScan();
display();
}
}
|