//Debounce demo //used as an example of a state machine. #include <90s8515.h> //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 unsigned char reload; //timer 0 reload to set 1 mSec 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 overflow ISR interrupt [TIM0_OVF] void timer0_overflow(void) begin //reload to force 1 mSec overflow TCNT0=reload; //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 void 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; PORTB = ~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 DDRB=0xff; // PORT B is an ouput //set up timer 0 reload=256-125; //value for 1 Msec at 8 MHz TCNT0=reload; TIMSK=2; //turn on timer 0 overflow ISR TCCR0=3; //prescalar to 64 //init the LED status (all off) led=0x00; PORTB=~led; //init the task timers time1=t1; time2=t2; time3=t3; //init the message //for no button push PushFlag = 0; //init the state machine PushState = NoPush; //crank up the ISRs #asm sei #endasm end