728x90
반응형
[UART + LED]
과제
UART를 활용하여 입력된 신호에 따라서 LED bar를 작동시켜라
- R 입력 시, 오른쪽 방향으로 LED bar On(순차적으로)
- L 입력 시, 왼쪽 방향으로 LED bar On(순차적으로)
- B 입력 시, Blink(점멸)
Code
<Header File>
// 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_ */
// 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>
// 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);
}
// 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>
#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
반응형