我写代码的目的是,当我的 PINA 的第 0 位为 1 时,PORTB 上显示的数字会递增。同样,如果 PINA 的第 1 位为 1,则数字递减。如果按住按钮,它将以每秒一次的速度递增/递减。如果按钮已按住至少 3 秒,则速率将增加到每 400 毫秒一次。如果同时按下两个按钮,则 PORTB 上显示的数字将重置为 0。定时器周期设置为 100 ms。
我将状态机拆分为 2 个“同时”运行的状态机。一个 SM 调整我正在递增/递减的周期,而另一个 SM 则在等待/添加/减去/重置状态之间进行转换。
我遇到的问题是我修改周期的状态机根本没有做任何事情。我有一个全局变量来跟踪在递增/递减之前必须等待多少滴答声(初始化为 10),并且当保持在我的 Incr/Decr 状态的滴答声数量超过 30 个滴答声(3秒)。但是这台机器根本没有做任何事情。我进行了修改,以便在我的并发 SM 启动时立即永久更改为 4 个滴答声,但这仍然没有任何作用;递增/递减仍然每 1 秒而不是每 400 毫秒发生一次。
我的代码有什么问题?有问题的代码:
enum States {Init, ButPres, Incr, Wait, Decr, Reset} state;
enum other_States {Init1, change_tick_total} state1;
unsigned char button = 0x00;
unsigned char cnt = 0x00;
unsigned char tick_cnt = 0;
unsigned char tick_total = 0x0A;
void change_period_tick() {
switch (state1) {
case Init1:
state = change_tick_total;
break;
case change_tick_total:
state = change_tick_total;
break;
default:
state = Init1;
break;
}
switch (state1) {
case change_tick_total:
if (tick_cnt > 30)
tick_total = 0x04;
else
tick_total = 0x0A;
break;
default:
break;
}
}
void tick(){
switch(state){
case Init:
state = ButPres;
break;
case ButPres:
if(button == 0x01)
state = Incr;
else if(button == 0x02)
state = Decr;
else if(button == 0x03)
state = Reset;
else
state = ButPres;
break;
case Incr:
if(button == 0x01 && cnt < 9)
state = Incr;
else
state = Wait;
break;
case Decr:
if(button == 0x02 && cnt > 0){
state = Decr;
}
else
state = Wait;
break;
case Wait:
if(button == 0x03)
state = Reset;
else if(button)
state = Wait;
else
state = ButPres;
break;
case Reset:
if(button == 0x03)
state = Reset;
else
state = Init;
break;
default:
state = Init;
break;
}
switch(state){
case Init:
cnt = 0x00;
PORTB = cnt;
break;
case Incr:
if(cnt < 0x09){
++tick_cnt;
if (tick_cnt % tick_total == 1)
++cnt;
PORTB = cnt;
}
break;
case Decr:
if(cnt > 0x00){
++tick_cnt;
if (tick_cnt % tick_total == 1)
--cnt;
PORTB = cnt;
}
break;
case Reset:
cnt = 0;
PORTB = cnt;
default:
tick_cnt = 0; //once we're out of INCR/DECR, the tick_cnt resets, as we're on a new cycle of counting ticks
break;
}
}
int main(void)
{
state = Init;
state1 = Init1;
DDRA = 0x00; PORTA = 0xFF;
DDRB = 0xFF; PORTB = 0x00;
// Initializes the LCD display
TimerSet(100);
TimerOn();
tick_total = 0x0A;
while(1) {
button = ~PINA;
change_period_tick(); //this does no seem to be running at all
tick();
while(!TimerFlag){}
TimerFlag = 0;
}
}