
UART 통신 설정을 위한
ATmega328P 데이터시트
' UART 포스팅 바로가기 '
2부 [UART] UART 통신은 어떻게 동작하는 걸까?
3부 [UART] UART 통신 설정을 위한 ATmega328P 데이터시트
完 [UART] 아두이노 UART 통신 기본 실험 || TX RX 연결부터 데이터 송수신까지
지금까지 UART 는 어떤 것인지 어떻게 동작하는지 알아보았습니다.
아두이노 라이브러리는 편리하지만, 내부에서 어떤 레지스터가 설정되는지는 드러내지 않습니다.
이번에는 ATmega328P 데이터시트를 직접 분석하며,
UART를 구성하는 핵심 레지스터를 하나씩 살펴보겠습니다.
데이터시트를 보는 이유
사실 아두이노에서 Serial.begin(9600) 한 줄을 입력하면 UART가 동작합니다.
편리하지만, 이 한 줄 뒤에는 MCU 내부의 레지스터를 직접 조작하는 동작이 숨어 있습니다.
데이터시트를 읽을 줄 안다는 것은 이 동작을 직접 제어할 수 있다는 뜻이고, 라이브러리가 지원하지 않는 세밀한 설정도 가능해진다는 의미입니다.
아두이노 UNO에 탑재된 MCU는 ATmega328P로, 데이터 시트에서 UART를 제어하는 레지스터들을 살펴보겠습니다.
ATmega328P 핀맵

아두이노 우노에는 DIP 타입의 ATmega328P가 탑재되어 있습니다.
UART 통신은 이 칩의 PD0(RXD) 과 PD1(TXD) 핀을 통해 이루어집니다.
데이터시트 기준으로는 각각 2번 핀과 3번 핀 에 해당하며, 이 두 핀을 통해 데이터를 송수신하게 됩니다.
UART 블럭 다이어그램

UART 하드웨어 모듈은 내부적으로 크게 세 가지 블록으로 구성되어 있습니다.
1. 클럭 발생부 (Clock Generator)
UART는 클럭이 없다고 했지만, 두 장치 사이를 연결하는 외부 클럭 선이 없다는 의미로 내부적으로는 클럭이 존재합니다.
클럭 발생부의 역할은 바로 BaudRate에 맞는 클럭을 만드는 것입니다.
아두이노 UNO의 외부 오실레이터는 16MHz로 동작합니다.
UBRRn (UART BaudRate Register)에 설정된 값으로 RaudRate에 맞게 16MHz 클럭을 이용해 원하는 Raud Rate 클럭을 생성합니다.
2. 송신부 (Transmitter)
데이터를 보내고 싶을 때는 UDRn (UART Data Register)에 값을 씁니다.
- 예를 들어 UDRn에 0x77을 쓰면, 이 값이 송신 시프트 레지스터 (Transmit Shift Registor)로 옮겨지고, 클럭 발생부에서 만들어진 BaudRate 클럭에 맞춰 1비트씩 TxDn으로 순서대로 출력됩니다.
패리티 비트를 설정했다면 패리티 제너레이터 (Parity Gernerator)를 거쳐 자동으로 패리티 비트가 붙어 TX핀을 통해 데이터가 송신됩니다.
3. 수신부 (Receiver)
수신부에서의 핵심 동작은 클럭 리커버리(Clock Recovery) 입니다.
비동기 통신 특성상 수신 측은 송신 측의 클럭을 직접 받지 못하기 때문에, RX핀에서 Start Bit가 감지되는 순간을 기준점으로 삼아 미리 약속된 BaudRate 클럭에 맞춰 이후 비트들을 순서대로 읽어들입니다.
- 이렇게 읽어들인 데이터는 Data Recovery를 거쳐 비트 단위로 복원되고, 패리티 비트가 설정되어 있다면 Parity Checker에서 오류 여부를 검사합니다.
- 이후 Receive Shift Register를 통해 최종적으로 UDRn 레지스터에 저장됩니다.
*상태 및 동작 레지스터
마지막으로 USCR은 UART Control and Status Register으로, UCSRnA, UCSRnB, UCSRnC 는 각각 UART의 상태 확인과 동작 제어를 담당하는 레지스터입니다.
레지스터 이름에서 n의 의미

데이터시트에서 레지스터 이름을 보면 UCSRnA, UBRRn, UDRn처럼 n이라는 문자가 붙어 있습니다.
이 n은 UART 모듈의 번호를 의미합니다.
MCU에 따라 UART 모듈이 여러 개 탑재된 경우 n이 0, 1, 2... 순서로 붙어 각 모듈을 구분합니다.
아두이노 UNO에 탑재된 ATmega328P는 UART 모듈이 하나뿐입니다.
따라서 이 MCU에서 n은 항상 0입니다.
결과적으로 레지스터 이름은 UCSR0A, UBRR0, UDR0 등으로 정해집니다.
BaudRate 를 위한 레지스터 - UBRRn
UBRRn은 BaudRate를 결정하는 12비트 레지스터입니다. 상위 4비트(UBRRnH)와 하위 8비트(UBRRnL)로 나뉘어 있으며, 두 레지스터를 합쳐 총 12비트로 BaudRate 값을 설정합니다.
BaudRate 설정 공식은 다음과 같습니다.
*focs : 아두이노 크리스탈 주파수
아두이노 UNO의 외부 크리스탈은 16MHz이므로, 9600 bps 설정 시 필요한 UBRR 값은
약 103이라는 결괏값이 나오며 이 과정에서 미세한 오차가 발생하지만, MCU 내부 로직이 허용 범위 내에서 자동으로 보정하도록 설계되어 있습니다
상태 레지스터 - UCSRnA

UCSRnA는 UART의 현재 상태를 나타내는 플래그 레지스터입니다.
각 비트는 아래 표의 기능을 합니다.
|
비트
|
이름
|
설명
|
|
7
|
RXC
|
수신 완료. 1이면 UDRn에 읽을 데이터가 있음
|
|
6
|
TXC
|
송신 완료. 시프트 레지스터까지 전부 비워진 상태
|
|
5
|
UDRE
|
송신 버퍼 비어있음. 1이면 UDRn에 데이터를 써도 됨
|
|
4
|
FE
|
프레임 에러. Stop Bit를 잘못 읽으면 1로 세트
|
|
3
|
DOR
|
데이터 오버런. 수신 버퍼가 가득 찬 상태에서 새 데이터가 들어오면 1
|
|
2
|
UPE
|
패리티 에러. 패리티 비트 불일치 시 1
|
|
1
|
U2X
|
배속 모드. 1로 설정 시 통신 속도를 2배로 높임
|
|
0
|
MPCM
|
멀티프로세서 통신 모드. 일반적으로 사용 안 함, 항상 0
|
이 중 실제 통신에서 가장 자주 확인하게 되는 비트는 7번 비트 RXC와 5번 비트 UDRE입니다.
RXC는 데이터를 받을 준비가 됐는지, UDRE는 데이터를 보낼 준비가 됐는지를 나타내기 때문입니다.
제어 레지스터 - UCSRnB

UCSRnB는 송수신기 활성화와 인터럽트를 설정하는 레지스터입니다.
각 비트는 아래 표의 기능을 합니다.
|
비트
|
이름
|
설명
|
|
7
|
RXCIE
|
RX 완료 인터럽트 활성화
|
|
6
|
TXCIE
|
TX 완료 인터럽트 활성화
|
|
5
|
UDRIE
|
송신 버퍼 빈 인터럽트 활성화
|
|
4
|
RXEN
|
수신기 활성화. 반드시 1로 설정
|
|
3
|
TXEN
|
송신기 활성화. 반드시 1로 설정
|
|
2
|
UCSZ2
|
데이터 비트가 9비트일 때 사용하는 추가 비트
|
|
1
|
RXB8
|
9비트 수신 시 9번째 비트 저장
|
|
0
|
TXB8
|
9비트 송신 시 9번째 비트 설정
|
이 중 실제 통신에서 가장 자주 확인하게 되는 비트는 4번 비트 RXEN와 3번 비트 TXEN입니다.
프레임 설정 레지스터 - UCSRnC

UCSRnC는 데이터 프레임 형식을 결정하는 레지스터입니다.
각 비트는 아래 표의 기능을 합니다.
|
UMSELn1 (7번)
|
UMSELn0 (6번)
|
모드
|
|
0
|
0
|
비동기 USART
|
|
0
|
1
|
동기 USART
|
|
1
|
0
|
예약됨
|
|
1
|
1
|
Master SPI 모드 (MSPIM)
|
|
UPMn1 (5번)
|
UPMn0 (4번)
|
패리티 모드
|
|
0
|
0
|
비활성
|
|
0
|
1
|
예약됨
|
|
1
|
0
|
짝수 패리티
|
|
1
|
1
|
홀수 패리티
|
|
USBSn (3번)
|
정지 비트 갯수
|
|
0
|
1-bit
|
|
1
|
2-bit
|
|
UCSZn2 (B 2번)
|
UCSZn1 (2번)
|
UCSZn0 (1번)
|
데이터 사이즈
|
|
0
|
0
|
0
|
5-bit
|
|
0
|
0
|
1
|
6-bit
|
|
0
|
1
|
0
|
7-bit
|
|
0
|
1
|
1
|
8-bit
|
|
1
|
0
|
0
|
예약됨
|
|
1
|
0
|
1
|
예약됨
|
|
1
|
1
|
0
|
예약됨
|
|
1
|
1
|
1
|
9-bit
|
그리고 0번 비트인 UCPOL 은 외부클럭을 사용할 때 필요한 비트입니다.
데이터 레지스터 - UDRn

UDRn은 송신과 수신을 모두 담당하는 8비트 데이터 레지스터입니다.
하나지만 내부적으로 송신 버퍼와 수신 버퍼가 분리되어 있습니다.
기본 9600bps, 8N1을 코드로 쓴다면
// BaudRate(9600) 설정
UBRR0H = 0; UBRR0L = 103;
// 송수신기(RX, TX) 활성화
UCSR0B = (1 << RXEN0) | (1 << TXEN0);
// 프레임 형식 설정: 8 Data Bits, No Parity, 1 Stop Bit
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
기본 설정인 9600bps, 8N1을 레지스터 수준에서 직접 풀어쓰면 해당 코드와 같습니다.
즉, 이 세 줄만 설정해주면 UART 통신을 시작할 준비가 끝납니다.
이후 데이터를 보낼 때는 UDR0에 값을 쓰고, 데이터를 받을 때는 UDR0를 읽으면 됩니다.
마무리

AI 활용 설정
사진 설명을 입력하세요.
레지스터 내용이 다소 복잡하게 느껴질 수 있지만, 라이브러리를 사용하는 일반적인 환경에서는 몰라도 됩니다.
Serial.begin(9600) 한 줄이 이 모든 과정을 자동으로 처리해주기 때문입니다.
다만 알고 있으면 라이브러리 없이도 UART를 직접 구현할 수 있고, 고급 활용도 가능해집니다.
도움이 되는 내용인 만큼, 가볍게 읽어두시는 것도 좋다고 생각합니다.
다음 글에서는 실제 하드웨어 연결로 넘어가, UART 통신을 위한 기본 회로도를 함께 살펴보겠습니다.

TEL (062-226-1777, 010-9891-7244), E-mail (ipmes@ipmes.co.kr)
임베디드 시스템 | PCB 설계 제작 | 펌웨어 개발 | 신호처리 | 응용프로그램
#IPMES, #아이피엠이에스, #연구노트, #임베디드, #PCB제작, #펌웨어개발,
#하드웨어개발, #소프트웨어개발, #회로설계,
#광주PCB, #광주시제품, #광주시제품개발, #광주OEM, #광주광역시PCB,
#광주임베디드, #광주음성처리, #광주신호처리, #광주광역시임베디드,
#광주회로설계, #광주아트웍, #PCB샘플링
#UART #UART통신 #시리얼통신 #직렬통신 #비동기통신
#ATmega328P #아트메가328P #아두이노UART #아두이노우노 #UART통신레지스터
'연구노트 > 통신 설계' 카테고리의 다른 글
| [UART] 아두이노 UART 통신 기본 실험 || TX RX 연결부터 데이터 송수신까지 (0) | 2026.06.05 |
|---|---|
| [UART] UART 통신은 어떻게 동작하는 걸까? (0) | 2026.05.29 |
| [UART] UART란 무엇인가? (0) | 2026.05.25 |
| RS-485 통신 인터페이스 설계 (0) | 2025.10.22 |
| LVDS 통신 인터페이스 설계 (0) | 2025.10.21 |