0

我写代码的目的是,当我的 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;
    }
}
4

0 回答 0