The purpose of the code I'm writing is that when my 0th bit of PINA is 1, the number displayed on PORTB is incremented. Likewise, if the 1st bit of PINA is 1, the number is decremented. If the button is held down, it will increment/decrement at a rate of once per second. If the button has been held down for at least 3 seconds, the rate is increased to one every 400 ms. If both buttons are pressed, the number displayed on PORTB is reset to 0. The timer period is set at 100 ms.
I split the state machine into 2 state machines running "concurrently". One SM adjusts the period that I'm incrementing/decrementing at, and the other does the transitions between waiting/adding/subtracting/resetting states.
The problem I'm having is that my state machine that modifies the period is not doing anything at all. I have a global variable to keep track of how many ticks (initialized to 10) I have to wait before incrementing/decrementing, and that this machine should modifying it when the number of ticks stayed in my Incr/Decr states exceeded 30 ticks (3 seconds). But this machine is not doing anything at all. I modified so that it will immediately and permanently change to 4 ticks when my concurrent SM starts, but that still doesn't do anything; incrementing/decrementing is still happening every 1 second rather than every 400 ms.
What's wrong with my code? Code in question:
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;
}
}