728x90
[UART + LED]
과제
UART를 활용하여 입력된 신호에 따라서 LED bar를 작동시켜라
- R 입력 시, 오른쪽 방향으로 LED bar On(순차적으로)
- L 입력 시, 왼쪽 방향으로 LED bar On(순차적으로)
- B 입력 시, Blink(점멸)
Code
<Header File>
cpp
접기// LED_BAR.h // #ifndef LED_BAR_H_ #define LED_BAR_H_ #define F_CPU 16000000UL #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #include <stdio.h> #define LED_BAR_PORT PORTA // LED_BAR를 PORTA에 연결 #define LED_BAR_DDR DDRA // 입/출력 방향 #define LED_COUNT 8 // LED_BAR는 총 8칸 typedef struct _led { volatile uint8_t *port; // 컴파일러 마음대로 해석하지 말라는 의미 uint8_t pin; }LED; // LED라는 이름을 가진 구조체 생성 extern LED leds[LED_COUNT]; // leds 배열이 정의된 것이 아니라, 다른 소스 파일에서 정의된 leds 배열을 참조하게 된다. void LED_Init(); // LED_BAR 초기화를 위한 함수 void LED_BAR_Init(); // LED_BAR 초기화 void LED_On(LED *led); // LED On을 위한 함수 void LED_Off(LED *led); // LED Off를 위한 함수 void LED_Left_Shift(LED *leds); // LED 좌시프트 void LED_Right_Shift(LED *leds); // LED 우시프트 void LED_Blink(uint8_t *LED_Data); // LED Blink void LED_Single_On(); // LED Lamp On #endif /* LED_BAR_H_ */
cpp
접기// UART.h // ifndef UART_H_ #define UART_H_ #define F_CPU 16000000UL #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #include <stdio.h> void UART_Init(); void UART_Transmit(char data); unsigned UART_Receive(); #endif /* UART_H_ */
<Source File>
cpp
접기// LED_BAR.c // #include "LED_BAR.h" LED leds[LED_COUNT] = { {&PORTA, 0}, // (주소값, 핀번호) {&PORTA, 1}, {&PORTA, 2}, {&PORTA, 3}, {&PORTA, 4}, {&PORTA, 5}, {&PORTA, 6}, {&PORTA, 7}, }; void LED_Init(LED *led) { *(led->port - 1) |= (1<< led->pin); } void LED_BAR_Init() { LED_BAR_DDR = 0xff; // 출력 모드 설정 LED_BAR_PORT = 0x00; // 꺼진 상태로 출발 for (int i = 0 ; i < LED_COUNT ; i++) { LED_Init(&leds[i]); } } void LED_On(LED *led) { *(led->port) |= (1<<led->pin); } void LED_Off(LED *led) { *(led->port) &= ~(1<<led->pin); } void LED_Left_Shift(LED *leds) { for (int i = 0 ; i < LED_COUNT ; i++) { LED_On(&leds[i]); _delay_ms(200); } for (int i = 0 ; i < LED_COUNT ; i++) { LED_Off(&leds[i]); _delay_ms(200); } } void LED_Right_Shift(LED *leds) { for (int i = 7 ; i >= 0 ; i--) { LED_On(&leds[i]); _delay_ms(200); } for (int i = 7 ; i >= 0 ; i--) { LED_Off(&leds[i]); _delay_ms(200); } } void LED_Blink(uint8_t *LED_Data) { LED_BAR_PORT = 0xaa; for (int i = 0 ; i < 15 ; i++) { LED_BAR_PORT = ~LED_BAR_PORT; _delay_ms(300); i++; } LED_BAR_PORT = 0x00; } void LED_Single_On() { PORTD |= (1<<PIND2); _delay_ms(1000); PORTD &= ~(1<<PIND2); }
cpp
접기// UART.c // #include "UART.h" void UART_Init() { UBRR0H = 0x00; UBRR0L = 0xcf; // 9600bps, 2배속 UCSR0A = (1<<U2X0); // 2배속 모드 set UCSR0B |= (1<<RXEN0); // 수신 가능(RX PIN 허용) UCSR0B |= (1<<TXEN0); // 송신 가능(TX PIN 허용) UCSR0B |= (1<<RXCIE0); // 수신 Interrupt Enable } void UART_Transmit(char data) { while(!((UCSR0A) & (1<<UDRE0))); // UDR이 비어있다면, 다음 문장으로 넘어감 UDR0 = data; } unsigned UART_Receive() { while(!((UCSR0A) & (1<<RXC0))); return UDR0; }
<main.c>
cpp
접기#include "LED_BAR.h" #include "UART.h" FILE OUTPUT = FDEV_SETUP_STREAM(UART_Transmit, NULL, _FDEV_SETUP_WRITE); char rxBuff; uint8_t rxFlag = 0; ISR(USART0_RX_vect) { rxBuff = UDR0; rxFlag = 1; } int main(void) { UART_Init(); LED_BAR_Init(); stdout = &OUTPUT; sei(); while (1) { if (rxFlag == 1) { rxFlag = 0; switch(rxBuff) { case 'R' : printf("%c", rxBuff); LED_Right_Shift(&leds); break; case 'L' : printf("%c", rxBuff); LED_Left_Shift(&leds); break; case 'B' : printf("%c", rxBuff); LED_Blink(&leds); break; default: printf("Finish"); LED_Single_On(); break; } } } return 0; }
Result
각 버튼의 입력에 따라 LED Bar가 동작하며,
동작이 종료되면 Finish를 출력하고, LED Lamp가 On되도록 코딩

728x90