마이크로컨트롤러에서 사용할 수 있는 범용 입출력 핀의 수는 많지 않으므로 직렬 통신이 사용된다.
직렬 통신은 1개의 입출력 핀을 통해 8개 비트를 8번에 나누어 전송하는 방식이다.
직렬 통신 중 가장 흔히 사용되는 UART로 진행한다.
UART 통신은 전이중 통신으로 송신과 수신을 동시에 진행할 수 있으며 이를 위해서 2개의 범용 입출력 핀이 필요하다.
ATMega328(아두이노 우노 칩에서 사용되는)에서는 PD0 핀과 PD1 핀이 사용된다. (아두이노 우노는 0, 1핀이다.)
/*
* UART_TEST.c
*
* Created: 2023-06-20 오후 8:46:56
* Author : Yoon
*/
#define F_CPU 16000000L
#include <avr/io.h>
#include <util/delay.h>
void UART_INIT(void)
{
UCSR0A |= (1 << U2X0); // 2배속 모드
UBRR0H = 0x00; // 9600bps
UBRR0L = 207;
UCSR0C |= 0x06; // 비동기, 8bit 데이터, 1bit start, 1bit stop, no parity
UCSR0B |= (1 << RXEN0); // 수신 가능
UCSR0B |= (1 << TXEN0); // 송신 가능
}
unsigned char UART_receive(void)
{
while(!(UCSR0A & (1 << RXC0))); // 데이터 수신 대기
return UDR0;
}
void UART_transmit(unsigned char data)
{
while(!(UCSR0A & (1 << UDRE0))); // 송신 가능 대기
UDR0 = data; // 데이터 전송
}
int main(void)
{
unsigned char data;
UART_INIT(); // UART 통신 초기화
while (1)
{
data = UART_receive(); // 데이터 수신
UART_transmit(data); // 수신된 문자를 에코백
}
return 0;
}
1. UCSR0A(USART Control and Status Register 0A) 레지스터 : UART 통신의 제어와 상태 체크
UX20 : 비동기 전송모드에서만 사용되며, 2배속 모드이면 1, 1배속 모드이면 0의 값을 가진다.
RXC0 : 수신 버퍼(UDR0)에 읽지 않은 문자가 있을 때는 1이 되고, 버파가 비어 있을 때는 0이 된다. UCSR0B 레지스터의 RXCIE0 비트와 함께 사용되어 수신 완료 인터럽트를 발생시킬 수 있다.
UDRE0 : 송신 버퍼(UDR0)가 비어 있어 데이터를 받을 준비가 되어 있을 때 1이 된다. UCSR0B 레지스터의 UDRIE0 비트와 함께 사용되어 송신 데이터 레지스터 준비 완료 인터럽트를 발생시킬 수 있다.
2. UCSR0B
RXCIE0 : 수신 완료 인터럽트를 발생을 허용한다.
TXCIE0 : 송신 완료 인터럽트를 발생을 허용한다.
RXEN0 : UART 수신기의 수신 기능을 활성화한다.
TXEN0 송신기의 송신 기능을 활성화한다.
3. UCSR0C : 데이터 형식 및 통신 방법을 결정한다.
4. UBRR0H, HBRR0L : 보율을 12비트로 표현한다.
5. UDR0 : 송수신된 데이터가 저장되는 버퍼 레지스터
C:\Program Files (x86)\Atmel\Studio\7.0\packs\atmel\ATmega_DFP\1.7.374\include\avr
#include <stdio.h>
#include <stdint.h>
void printBinary(uint8_t value) {
for (int i = 7; i >= 0; i--) {
if ((value >> i) & 1)
printf("1");
else
printf("0");
}
printf("\n");
}
int main(void) {
uint8_t UCSR0A = 0b00000000;
uint8_t U2X0 = 1;
uint8_t RXC0 = 7;
uint8_t UDRE0 = 5;
printf("UCSR0A in binary: ");
printBinary(UCSR0A);
UCSR0A |= (1 << U2X0);
printf("[init] UCSR0A in binary: ");
printBinary(UCSR0A);
UCSR0A = !(UCSR0A & (1 << RXC0));
printf("[RX] UCSR0A in binary: ");
printBinary(UCSR0A);
UCSR0A = !(UCSR0A & (1 << UDRE0));
printf("[TX] UCSR0A in binary: ");
printBinary(UCSR0A);
UCSR0A = UCSR0A & (1 << RXC0);
printf("[RX] UCSR0A in binary: ");
printBinary(UCSR0A);
UCSR0A = UCSR0A & (1 << UDRE0);
printf("[TX] UCSR0A in binary: ");
printBinary(UCSR0A);
return 0;
}
'Embeded SW > AVR' 카테고리의 다른 글
아트멜 스튜디오 시작하기. (0) | 2023.06.18 |
---|---|
아두이노 우노에서 ISP 방식으로 업로드하기 (0) | 2023.06.18 |