ra_mi 2024. 9. 22. 12:05

간단한 신호등 제어 시스템 설계를 해보자 

 

1. 동작 

 - AUTO MODE (button 0)

 1) vertical_red & horizontal_green

 2) vertical_red & horizontal_yellow 

 3) vertical_green & horizontal_green

 4) vertical_yellow & horizontal_green 

의 순서로 동작 

 - MANUAL MODE (button 1, button 2)

button 1 누르면 manual mode로 진입(현재 상태 그대로 stop), 그 후 button 2를 누르면 auto모드의 순서대로 다음 순서로 넘어감

 

2. FSM 

 

3. code 

#include F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>

enum {AUTO, MANUAL}; 

void ledFUNC(uint8_t state){
    case 0:
      state = (1 << LED_UD_R)|(1 << LED_RL_G);
      PORTE = state;
      break;
      case 1:
      state = (1 << LED_UD_R)|(1 << LED_RL_Y);
      PORTE = state;
      break;
      case 2:
      state = (1 << LED_UD_G)|(1 << LED_RL_R);
      PORTE = state;
      break;
      case 3:
      state = (1 << LED_UD_Y)|(1 << LED_RL_R);
      PORTE = state;
      break;
}

int main(){
    DDRE = 0xff; 
    DDRA = 0x00;
    PORTA = 0xff; 

    uint8_t buttonState; 
    uint8_t ledMode = 0; 
    uint8_t ledState = 0x00; 

    while(1){
        buttonState = PINA;     // 외부에서 들어오는 값 
        if (buttonState & (1<<0) == 0){
            ledMode = AUTO; 
        }
        if (buttonState & (1<<1) == 0){
            ledMode = MANUAL; 
        }

        switch(ledMode){
            case AUTO:
            ledFUNC(ledState); 
                switch (ledState){
                    case 0: 
                        _delay_ms(3000); 
                        ledState = 1; 
                    case 1: 
                        _delay_ms(1000);
                        ledState = 2; 
                    case 2: 
                        _delay_ms(3000); 
                        ledState = 3; 
                    case 3: 
                        _delay_ms(1000);
                        ledState = 0;   
                }
            break; 
            case MANUAL:
            ledFUNC(ledState); 
            if (buttonState & (1<<2) == 0){
                ledState = (ledState + 1) % 4; 
                ledFUNC(ledState); 
                _delay_ms(200); 
            }
            break; 
        }
    }
}