// Debounce demo // Mega644 version // used as an example of a state machine. #include #include #include //timeout values for each task #define t1 200 #define t2 50 #define t3 50 //I like these #define begin { #define end } //State machine state names #define NoPush 1 #define MaybePush 2 #define Pushed 3 #define MaybeNoPush 4 //the three task subroutines void task1(void); //inc LEDs void task2(void); //non-debounced button 0 void task3(void); //debounced button 1 void initialize(void); //all the usual mcu stuff volatile unsigned char time1, time2, time3; //timeout counters unsigned char PushFlag; //message indicating a button push unsigned char led; //LED count unsigned char PushState; //state machine //********************************************************** //timer 0 comare match ISR ISR (TIMER0_COMPA_vect) begin //Decrement the three times if they are not already zero if (time1>0) --time1; if (time2>0) --time2; if (time3>0) --time3; end //********************************************************** //Entry point and task scheduler loop int main(void) begin initialize(); //main task scheduler loop while(1) begin if (time1==0) task1(); if (time2==0) task2(); if (time3==0) task3(); end end //********************************************************** //Task subroutines //Task 1 void task1(void) begin time1=t1; //reset the task timer if (PushFlag) //check for a button press begin //reset flag PushFlag = 0; //increment the LEDs ++led; PORTC = ~led; end end //******************************* //Task 2 void task2(void) begin time2=t2; //reset the task timer if (~PIND & 0x01) //button push begin PushFlag = 1; end end //******************************* //Task 3 void task3(void) begin time3=t3; //reset the task timer switch (PushState) begin case NoPush: if (~PIND & 0x02) PushState=MaybePush; else PushState=NoPush; break; case MaybePush: if (~PIND & 0x02) begin PushState=Pushed; PushFlag=1; end else PushState=NoPush; break; case Pushed: if (~PIND & 0x02) PushState=Pushed; else PushState=MaybeNoPush; break; case MaybeNoPush: if (~PIND & 0x02) PushState=Pushed; else begin PushState=NoPush; PushFlag=0; end break; end end //********************************************************** //Set it all up void initialize(void) begin //set up the ports DDRD = 0x00; // PORT D is an input DDRC = 0xff; // PORT C is an ouput PORTC = 0xff ; // turn off leds //set up timer 0 for 1 mSec timebase OCR0A = 249; //set the compare re to 250 time ticks TIMSK0= (1<