I am building a traffic light system. So when the button is not pressed, led 1 and 4 will turn on for 4 seconds, then led 2 and 3 will turn on for 4 seconds. If the button is pressed, the led for pedestrian (led 5) will wait and turn on only when the led 2 is on (it means that when we press the button, if led 1 and 4 are on, then led 5 will wait until led 1 and 4 are off). Only led 5 and 2 will turn on at this time, others will be off. After 2 seconds, led 5 will be off, led 3 will be on for 2 seconds. Led 2 will be on for the entire time (4 seconds). Then we return to normal. But the problem is when I run the program, all 4 leds are on.
#include <avr/io.h>
#include <avr/interrupt.h>
volatile int second = 1;
volatile boolean buttonPressed = false;
enum light_state {EW, SN, PES, START_UP};
enum light_state state;
int main(void) {
DDRB = 0xFF; //Set LEDs as output
DDRD &= ~(1 << 2); //Set button as input
PORTD |= (1 << PORTD2);
EIMSK |= (1 << INT0); //enable PORTB2 as external interrupt
EICRA |= (1 << ISC01); //detect falling edge
EIFR |= (1 << INTF0); //clear flag
TCCR1B |= (1 << WGM12) | (1 << CS12) | (1 << CS10); //turn on CTC mode and set up Timer 1 with the prescaler of 1024
OCR1A = 15624; //enable output Compare A Match Interrupt
TIMSK1 = 1 << OCIE1A; //set CTC compare value to 2 Hz at 16 MHz AVR clock , with a prescaler of 1024
sei();
while (1) {
if (!buttonPressed) {
switch (state) {
case EW:
PORTB &= ~((1 << PORTB1) | (1 << PORTB4));
PORTB |= (1 << PORTB2) | (1 << PORTB3);
state = SN;
break;
case SN:
PORTB |= (1 << PORTB1) | (1 << PORTB4);
PORTB &= ~((1 << PORTB2) | (1 << PORTB3));
state = EW;
break;
case START_UP :
PORTB &= ~((1 << PORTB1) | (1 << PORTB2) | (1 << PORTB3) | (1 << PORTB4));
state = SN;
break;
default:
state = START_UP;
break;
}
second = 1;
} else {
switch (state) {
case PES:
PORTB |= (1 << PORTB2) | (1 << PORTB5);
PORTB &= ~((1 << PORTB1) | (1 << PORTB3) | (1 << PORTB4));
state = SN;
break;
case SN:
PORTB |= (1 << PORTB2) | (1 << PORTB3);
PORTB &= ~((1 << PORTB1) | (1 << PORTB4));
state = EW;
break;
case START_UP :
PORTB &= ~((1 << PORTB1) | (1 << PORTB2) | (1 << PORTB3) | (1 << PORTB4) | (1 << PORTB5));
state = PES;
break;
default:
state = START_UP;
break;
}
buttonPressed = false;
second = 1;
}
}
}
ISR(INT0_vect) {
buttonPressed = true;
}
ISR(TIMER1_COMPA_vect) {
if (buttonPressed) {
if (second == 2) {
second = 1;
}
}
second++;
}