IC8ΛPΛCIRCUIT
/// 기술 자료 · MCU · 통신

UART 보레이트와 클럭 오차

UART 가 「가끔」 깨진다면 배선보다 먼저 볼 것이 보레이트 오차다. MCU 는 자기 클럭을 정수로 나눠 보레이트를 만들기 때문에, 클럭과 보레이트 조합에 따라 몇 % 씩 어긋난다.

왜 오차가 생기나

UART 는 따로 클럭 선이 없다. 보내는 쪽과 받는 쪽이 「같은 속도로 센다」고 약속하고, 받는 쪽은 시작 비트에서 박자를 맞춘 뒤 각 비트의 가운데에서 값을 읽는다. 그런데 MCU 는 보레이트를 클럭 ÷ 정수로만 만들 수 있다. 72 MHz ÷ 115200 = 625 처럼 딱 나누어떨어지면 오차가 0이지만, 16 MHz ÷ (16 × 115200) = 8.68 처럼 소수가 나오면 반올림한 만큼 속도가 틀어진다. 그 어긋남이 프레임 끝(약 10비트)까지 쌓여 반 비트에 가까워지면 읽기가 틀린다.

값 넣어 보기

STM32: 해당 USART 의 APB 클럭
실제 보레이트 · 오차
-
푸는 순서

    이 클럭에서 자주 쓰는 보레이트 전부

    보레이트분주값실제오차판단
    시작D0D1 … D6D7정지 받는 쪽은 비트 가운데(점선)에서 읽는다 — 오차가 쌓여 마지막 비트에서 경계를 넘으면 틀린다
    시작 비트에서 맞춘 박자를 정지 비트까지 약 10비트 동안 이어 간다. 그동안 쌓인 어긋남이 반 비트 가까이 되면 읽기가 틀린다.

    공식과 근거

    STM32 (16배): BRR = 반올림(fck / baud)  ·  실제 = fck / BRR
    STM32 (8배): USARTDIV = 반올림(2 × fck / baud), BRR 아래 4비트 = USARTDIV[3:0] ≫ 1  ·  실제 = 2 × fck / USARTDIV
    AVR: UBRR = 반올림(fosc / (16 × baud)) − 1  ·  실제 = fosc / (16 × (UBRR + 1))  (U2X=1 이면 16 대신 8)
    오차 % = (실제 − 목표) / 목표 × 100

    근거: STM32 레퍼런스 매뉴얼 USART 장(보레이트 생성 · 수신기 허용 오차 표), ATmega328P 데이터시트 USART 장(보레이트 설정 표).

    어디까지 괜찮나

    받는 쪽이 견딜 수 있는 어긋남은 제조사 매뉴얼에 「수신기 허용 오차」로 나오고, 설정에 따라 대략 3~4% 수준이다. 이건 보내는 쪽과 받는 쪽 오차를 합친 값이라 한쪽 MCU 만 볼 때는 넉넉히 잡는다.

    한쪽 오차판단
    ±1% 안쪽안전 — 상대가 조금 틀어져도 버틴다
    ±1~2%대부분 되지만 상대 쪽 오차 · 케이블 · 온도에 따라 가끔 깨질 수 있다
    ±2% 넘음위험 — 클럭 · 보레이트 조합을 바꾼다

    흔한 실수

    RC 내부 발진기로 높은 보레이트 — 내부 발진기는 온도 · 전압에 따라 1~2% 쯤 흔들린다. 계산 오차가 0% 여도 실제로는 틀어진다. 높은 보레이트 · 긴 통신이면 크리스털을 쓴다.
    16 MHz 아두이노에서 115200 — U2X=0 이면 오차가 약 −3.5% 로 꽤 크다(아두이노 기본 라이브러리는 U2X=1 을 써서 +2.1%). 그래서 같은 보드라도 57600 이나 250000 이 더 깨끗한 경우가 있다.
    클럭을 바꾸고 BRR 은 그대로 — 저전력 모드에서 클럭을 낮추거나 PLL 설정을 바꾸면 보레이트도 함께 바뀐다. 클럭을 바꾸는 코드 옆에서 UART 초기화를 다시 한다.

    자주 묻는 것

    왜 크리스털이 11.0592 MHz 같은 이상한 값인가

    11.0592 MHz · 14.7456 MHz · 18.432 MHz 는 9600 · 115200 같은 표준 보레이트로 딱 나누어떨어지는 값이라 오차가 0% 가 된다. 표에 넣어 보면 확인할 수 있다.

    오버샘플링 8배는 언제 쓰나

    클럭에 비해 보레이트가 아주 높을 때(예: 수 Mbps) 쓴다. 더 높은 속도를 낼 수 있는 대신 잡음과 클럭 어긋남에 덜 너그럽다.