//--------------------------------------------------------------------------------------- // Programm Nr.: 14 // Content : workflow control with timer0 interrupt (example traffic light) // Author : digital AG Halle // Date : 27.07.2008 // System : ATmega8-16PU - Dai Hoc Hue Development Board //--------------------------------------------------------------------------------------- // programm memory usage: 12,9 % //--included Files----------------------------------------------------------------------- #include #include #include #include //--declarations------------------------------------------------------------------------- #ifndef F_CPU #define F_CPU 8000000 //CPU frequency = 8 MHz #endif #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif uint16_t count; //count = 0....65535 -> that means 0...537,2 seconds //1 second is 122 steps uint8_t count2; //count2 = 0....255 uint16_t count3; //for control the pulsing signal uint8_t reload2; //reload value for timer2 uint8_t state; //state variable for different output situations uint8_t KEYS; //actual key-value uint8_t KEYS_OLD; //last key-value unsigned char P_SIG1; //pedestrians button request signal unsigned char P_SIG2; //pedestrians GREEN signal //--INTERRUPT SERVICE ROUTINES (ISR)----------------------------------------------------- SIGNAL (TIMER0_OVF_vect) //event: timer0 overflow 255->0 { count++; //counter in the ISR (to extent ISR-time) //at the specific moments, only the variable state is changed if (count < 244){ //time 1 reached ( 2 seconds) state=0; } if ((count >= 244)&&(count < 366)){ //time 2 reached ( 3 seconds) state=1; } if ((count >= 366)&&(count < 1952)){ //time 3 reached ( 8 seconds) state=2; if(P_SIG1==FALSE) count--; } if ((count >= 1952)&&(count < 2074)){ //time 4 reached (10 seconds) state=3; } if ((count >= 2074)&&(count < 2196)){ //time 5 reached (12 seconds) state=4; } if ((count >= 2196)&&(count < 2928)){ //time 6 reached (17 seconds) state=5; } if (count >= 2928){ //time 6 reached (17 seconds) count=0; //reset counter (end of counter cycle) } } SIGNAL (TIMER2_OVF_vect) //event: timer2 overflow 255->0 { TCNT2 = reload2; //load timer2 count-register for the next run if (P_SIG2==TRUE) //give free { count2++; //counter in the ISR (to extent ISR-time) if (count2 < 50) //condition time 1 reached PORTB |= (1<=100) //condition time 2 reached: end of counter cycle count2=0; //reset counter } if (P_SIG1==TRUE) //give free pulsed signal { count2++; //counter in the ISR (to extent ISR-time) count3++; if ((count2 < 50)&&(count3 < 4095)) //condition time 1 reached PORTB |= (1<=100) //condition time 2 reached: end of counter cycle count2=0; //reset counter if (count3 >=8191) count3=0; //reset counter for pulsing } } //--MAIN PROGRAMM------------------------------------------------------------------------ int main(void) { //--INITIALISATION--------------------------------------------------------------- //LEDs are: Signal name: /* PD0 - pedestrians RED (PR) PD1 - pedestrians GREEN (PG) PD3 - pedestrians request button pressed (S) PD5 - cars RED (CR) PD6 - cars YELLOW (CY) PD7 - cars GREEN (CG) */ DDRB = 2; //PORTB.BIT1 output (PIEZO) PORTB = 2; //PIEZO start value = off (high-level (because it is between MC-output and Vcc)) DDRC = 225; //PORT C: Bit 1,2,3,4 are inputs (Keys 1 - 4) PORTC = 30; //PORT C: Bit 1,2,3,4 internal Pullup-Resistors active DDRD = 255; // all LEDs output PORTD = 222; // start state: both RED lights are on for safety // remember: the LED is on when the pin is at low-level! //INTERRUPTS: //Timer0 (programm time base) // 8000000/256/256/61 = 2 // reload is not needed - we use the full timer0 range 0->255->0->255.... TIMSK |= (1< prescaler = 256 //Timer2 (sound signal output (signal for blind pedestrians)) TCCR2 |= (1< timer2 freq. = 1 MHz // Interrupt at every 20 kHz // ***Be careful: The Clock Select Bits of Timer2 are different from the ones of Timer0!*** reload2 = 205; TCNT2 = reload2; //--PROGRAMM CODE BEFORE MAIN LOOP (USED JUST ONE TIME)-------------------------- sei(); //enable flag for all interrupts KEYS_OLD=PINC; //initialise KEYS_OLD //--MAIN LOOP-------------------------------------------------------------------- while(1) { //realize the changes for output lines and sound-signal by checking state variable switch (state){ case 0: { PORTD = 222 ; P_SIG2=FALSE; }; break; //start state: PR,CR case 1: PORTD = 158 ;break; //PR,CR,CY case 2: { if (P_SIG1==TRUE) PORTD = 118; //PR,CG, pulsing signal for pedestrians (green will come) else PORTD = 126; //PR,CG }; break; case 3: PORTD = 182; break; //PR,CY, pulsing signal for pedestrians (green will come) case 4: PORTD = 214; break; //PR,CR, pulsing signal for pedestrians (green will come) case 5: { PORTD = 221; P_SIG2=TRUE; P_SIG1=FALSE; }; break; //PG,CR, signal pedestrians green } if (state==2){ //check pedestrians button (S1) only in state 2 KEYS=PINC; //read input byte from PORT C if (KEYS_OLD!=KEYS) //check of a change at PORT C inputs //it also works against chatter at the keys { if ((KEYS&226)==!(0x02)) //if key 1 was pressed { P_SIG1=TRUE; } } KEYS_OLD=KEYS; //save actual KEY-value for the next time } } return 0; } //--MAIN PROGRAMM END-------------------------------------------------------------------- //--EXTERNAL ROUTINES-------------------------------------------------------------------- //--PROGRAMM END-------------------------------------------------------------------------