← Embedded C 강의 목록으로
🔌
STM32
STM32 · 선수: 18강

19. USART 시리얼 통신

이제 칩이 사람·PC와 텍스트로 대화합니다. UART(범용 비동기 직렬)는 디버그 메시지, 센서 모듈, 부트로더 등 어디에나 쓰입니다. USART1을 9600bps로 설정해 인사 문자열을 보내고, 받은 문자를 그대로 되돌리는 에코를 구현합니다. μVision Serial 창에서 송수신을 직접 볼 수 있어, UART는 시뮬레이터로 검증하기 가장 좋은 주변장치입니다.

USARTUARTBRRTXERXNE에코
소요 시간
약 1.5시간
난이도
📊 중급
선수 조건
🎯 18강
결과물
USART1(PA9/PA10)을 BRR=fCK/baud로 설정하고 TXE/RXNE 폴링으로 문자열을 송신·에코할 수 있습니다.

이 강의에서 배우는 것

  • 1UART의 비동기 통신 원리와 프레임(8N1)을 이해한다
  • 2USART1의 핀(PA9/PA10)과 클럭을 설정한다
  • 3BRR로 보율을 계산·설정한다
  • 4TXE/RXNE 플래그로 폴링 송수신을 구현한다
  • 5μVision Serial 창에서 송수신을 확인한다

소개

UART는 클럭선 없이 양쪽이 약속한 보율로 데이터를 주고받습니다. 송신측 TX가 수신측 RX에 교차 연결되고 GND를 공유합니다. 가장 흔한 설정은 8N1(데이터8·패리티 없음·정지1).

핵심 개념

1) USART1 핀·클럭과 보율

신호모드
TXPA9AF 푸시풀(0xB)
RXPA10플로팅 입력(0x4)
c
/* USART1 은 APB2(RCC_APB2ENR_USART1EN). fCK = PCLK2 = 72MHz */
BRR = fCK / baud;   /* 9600 → 72000000/9600 = 7500 */

2) 송수신(폴링)

c
while (!(USART1->SR & USART_SR_TXE)) { }   /* 송신 버퍼 빌 때까지 */
USART1->DR = c;                            /* 한 글자 송신 */

if (USART1->SR & USART_SR_RXNE) c = USART1->DR;   /* 읽으면 RXNE 자동 클리어 */

CR1에 TE(송신)·RE(수신)·UE(USART 인에이블)를 켭니다: `CR1 = TE | RE | UE`.

핵심 예제

c
#include "stm32f10x.h"
static void usart1_init(void){
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN | RCC_APB2ENR_USART1EN;
    GPIOA->CRH &= ~((0xFu<<4) | (0xFu<<8));
    GPIOA->CRH |= (0xBu<<4);   /* PA9 TX = AF 푸시풀 */
    GPIOA->CRH |= (0x4u<<8);   /* PA10 RX = 플로팅 입력 */
    USART1->BRR = 7500u;       /* 9600 @ 72MHz */
    USART1->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE;
}
static void tx(char c){ while(!(USART1->SR & USART_SR_TXE)){} USART1->DR=(uint16_t)c; }
int main(void){
    usart1_init();
    const char *s = "Hello, STM32 UART!\r\n"; while(*s) tx(*s++);
    while (1) { if (USART1->SR & USART_SR_RXNE) tx((char)USART1->DR); }  /* 에코 */
}

BRR 검산: 9600→7500, 19200→3750, 115200→625. 시뮬레이터 View → Serial Windows → UART #1 에 인사 문자열이 출력되고, 입력 문자가 에코됩니다.

자주 하는 실수

Q. 글자가 깨져서 나와요.

A. 보율 불일치입니다. BRR 계산에 쓴 fCK(USART1=PCLK2=72MHz)와 터미널 보율이 같은지 확인하세요.

Q. 첫 글자만 나오고 멈춰요.

A. TXE를 기다리지 않고 DR에 연속으로 쓰면 이전 글자를 덮어씁니다. 매 글자 전에 while(!(SR & TXE))로 대기하세요.

Q. PA9/PA10을 일반 입출력으로 뒀어요.

A. TX(PA9)는 AF 푸시풀(0xB), RX(PA10)는 입력이어야 USART 신호가 핀에 연결됩니다.

정리

  • UART는 보율을 맞춘 두 선(TX/RX)으로 비동기 통신한다(8N1 흔함)
  • USART1은 PA9(TX)/PA10(RX), APB2 버스, BRR=fCK/baud
  • 송신은 TXE 대기 후 DR 쓰기, 수신은 RXNE 확인 후 DR 읽기
  • 시뮬레이터 UART #1 창으로 송수신 텍스트를 직접 본다
  • TX는 AF 푸시풀로 설정해야 한다

과제

  1. 정수를 받아 10진 문자열로 보내는 print_num() 작성
  2. 받은 문자가 소문자면 대문자로 바꿔 에코하는 변환 추가
  3. 115200bps 의 BRR 값을 계산하고 적용
예제 코드 / 강의 자료

전체 강의 자료와 예제 코드(과제·정답 포함)는 GitHub에서 자유롭게 받아볼 수 있습니다.

GitHub에서 보기 ↗