본문으로 건너뛰기
고급약 40분

직렬 통신 검증 — UART·SPI·I2C의 프레임·설정 불일치·타이밍 결함을 시험 케이스로

보드 안의 칩과 칩, 보드와 PC는 대부분 UART·SPI·I2C로 이야기한다. 세 프로토콜의 프레임 구조(시작·데이터·패리티·정지 비트, CPOL·CPHA 모드, 7비트 주소와 ACK)를 테스터가 알아야 할 수준으로 정리하고, 보드레이트 오차 허용 범위, 프레이밍·오버런 오류, SPI 모드 불일치 증상, I2C 풀업·클럭 스트레칭·버스 고착 복구 같은 전형적 결함을 경계값 시험 케이스 표로 바꾼다.

  • #임베디드
  • #UART
  • #SPI
  • #I2C
  • #직렬통신
  • #경계값

개념

왜 테스터가 비트 단위까지 알아야 하나

웹 테스터는 TCP가 재전송과 순서 보장을 해 주니 비트를 몰라도 된다. 보드 안의 직렬 통신에는 그런 보호막이 얇거나 없다. UART는 오류를 감지해도 재전송하지 않고, SPI는 오류를 감지하는 장치조차 없으며, I2C는 ACK 한 비트가 유일한 확인이다. 통신 결함이 응용 계층까지 그대로 올라온다. 센서 값이 가끔 튀거나, 설정이 가끔 저장되지 않거나, 부팅이 가끔 멈추는 현상의 원인이 비트 하나의 타이밍인 경우가 많다.

세 프로토콜을 한눈에 비교하면 이렇다.

항목UARTSPII2C
선 수TX, RX (+ RTS/CTS)SCLK, MOSI, MISO, CS(장치당 1개)SDA, SCL 2개
클럭없음(비동기, 양쪽이 속도를 약속)마스터가 공급마스터가 공급, 슬레이브가 늦출 수 있음
연결1:11 마스터 : 여러 슬레이브여러 장치가 한 버스 공유
주소 지정없음CS 선으로 선택7비트(또는 10비트) 주소
오류 확인패리티(선택), 프레이밍없음(응용 계층 CRC에 의존)바이트마다 ACK/NACK
전형적 속도9600~921600bps수 MHz~수십 MHz100k~3.4MHz

UART — 시계 없이 약속만으로

UART는 클럭 선이 없다. 송신 쪽과 수신 쪽이 같은 속도(보드레이트) 를 미리 약속하고, 수신 쪽은 시작 비트의 하강 에지를 보고 자기 시계를 맞춘 뒤 비트 중앙에서 값을 읽는다.

유휴(High) ─┐   ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───── 유휴
           │ S │D0 │D1 │D2 │D3 │D4 │D5 │D6 │D7 │ P │ Stop
           └───┘                                     (High)
  S   = 시작 비트(항상 Low)
  D0~D7 = 데이터 비트, LSB 먼저
  P   = 패리티 비트(선택: 없음/짝수/홀수)
  Stop = 정지 비트(High, 1 또는 2비트)

설정은 흔히 8N1 처럼 줄여 쓴다. 데이터 8비트, 패리티 없음(None), 정지 비트 1개라는 뜻이다. 한 바이트를 보내는 데 시작 1 + 데이터 8 + 정지 1 = 10비트가 든다. 그래서 115200bps의 실제 데이터 처리량은 초당 약 11520바이트다. 테스터가 "초당 20KB 로그를 115200bps UART로 뽑는다"는 설계를 보면 계산만으로 결함 을 찾을 수 있다.

보드레이트 오차 허용

시작 비트에서 한 번 맞춘 시계로 10비트를 끝까지 읽어야 하므로, 양쪽 시계가 조금씩 어긋나면 마지막 비트쯤에서 샘플링 지점이 비트 경계를 넘는다. 수신기가 비트 중앙에서 샘플링한다면 10비트 끝에서 반 비트(50%)까지 밀려도 되니 이론상 한계는 약 ±5%다. 하지만 이 오차는 양쪽 오차의 합 이고, 에지가 무뎌지고 샘플링 방식에도 여유가 필요하므로 실무에서는 한쪽당 ±2~3% 안쪽 을 안전 범위로 본다.

오차는 주로 MCU 클럭을 정수로 나눠 보드레이트를 만들 때 생긴다.

MCU 클럭 16 MHz, 목표 115200bps, 16배 오버샘플링
  분주값 = 16,000,000 / (16 × 115200) = 8.68 → 9로 반올림
  실제 속도 = 16,000,000 / (16 × 9) = 111,111bps
  오차 = (111,111 − 115,200) / 115,200 ≈ −3.5%   ← 위험

이 보드는 PC와는 대개 통신이 되다가, 역시 오차가 반대 방향으로 있는 다른 장치와 붙이면 가끔 깨진다. 내장 RC 발진기를 쓰는 MCU는 온도에 따라 클럭이 1~2% 흔들리므로 저온·고온에서만 깨지는 UART 도 흔하다.

UART 오류 종류

오류의미흔한 원인
프레이밍 오류(framing error)정지 비트 자리에서 High가 아니라 Low를 읽음보드레이트 불일치, 잡음, 데이터 비트 수 설정 불일치
패리티 오류패리티 비트가 계산과 다름잡음, 패리티 설정 불일치
오버런 오류(overrun)이전 바이트를 읽기 전에 다음 바이트가 도착해 덮어씀ISR이 늦음, 수신 버퍼(FIFO) 부족, 다른 인터럽트가 길게 점유
브레이크 감지한 프레임 이상 Low가 계속됨선 끊김, 상대 장치 리셋, 의도된 브레이크 신호

오버런은 레슨 1의 인터럽트 문제와 곧바로 연결된다. 통신 자체는 멀쩡한데 소프트웨어가 제때 읽지 못해서 생긴다. 그래서 오버런 시험은 "최대 속도로 연속 수신하면서 다른 인터럽트 부하를 겹치는" 형태가 된다.

흐름 제어

수신 쪽이 처리하지 못할 때 송신을 멈추게 하는 장치가 흐름 제어다. 하드웨어 방식은 RTS/CTS 선, 소프트웨어 방식은 XON(0x11)/XOFF(0x13) 문자를 쓴다. 시험 포인트는 수신 버퍼가 거의 찼을 때 실제로 송신이 멈추는지, 이진 데이터 속 0x11·0x13을 제어 문자로 오인하지 않는지, 한쪽만 흐름 제어를 켰을 때 무엇이 멈추는지다.

SPI — 빠르지만 아무것도 확인하지 않는다

SPI는 마스터가 클럭(SCLK)을 주고, 클럭 한 번마다 MOSI(마스터→슬레이브)와 MISO(슬레이브→마스터)로 동시에 한 비트씩 주고받는다. 슬레이브 선택은 장치마다 따로 있는 CS(Chip Select, 보통 Low 활성) 선으로 한다.

CPOL과 CPHA — 네 가지 모드

SPI에는 표준 협회가 없어서 칩마다 클럭의 극성과 위상이 다르다. 이 두 설정의 조합이 모드 0~3이다.

모드CPOL(유휴 시 클럭)CPHA(샘플링 에지)샘플링 시점
0Low첫 번째 에지상승 에지
1Low두 번째 에지하강 에지
2High첫 번째 에지하강 에지
3High두 번째 에지상승 에지

모드가 틀리면 통신이 완전히 실패하지 않는다는 점이 위험하다. 전형적 증상은 이렇다.

  • 값이 한 비트 밀린다 — 0x55를 보냈는데 0xAA나 0x2A가 읽힌다. 모든 값이 2배 또는 절반처럼 보인다
  • 대부분 맞고 가끔 틀린다 — 샘플링 에지가 데이터 변화 순간과 겹쳐, 배선 길이·온도·클럭 속도에 따라 결과가 흔들린다
  • 첫 바이트만 틀린다 — 모드 0과 3처럼 샘플링 에지는 같지만 유휴 극성이 다를 때, CS 직후 첫 비트에서만 어긋난다

모드 불일치는 낮은 클럭에서는 우연히 동작하다가 클럭을 올리면 드러나기도 한다. 그래서 SPI 클럭 속도는 경계값 시험 대상 이다.

CS 타이밍과 기타 시험 포인트

  • CS 셋업·홀드 시간 — CS를 내린 뒤 첫 클럭까지, 마지막 클럭 뒤 CS를 올릴 때까지 칩이 요구하는 최소 시간(데이터시트 표). 최적화 빌드에서 코드가 빨라지면 이 시간이 줄어 실패하기도 한다
  • 여러 슬레이브 — 두 CS가 동시에 Low가 되면 MISO에서 두 칩이 충돌한다. 공유 버스를 두 태스크가 쓰면 잠금 누락으로 이런 일이 생긴다
  • 무결성 확인 — SPI 자체에 오류 검출이 없으므로 플래시 쓰기 후 되읽기 비교, 응용 계층 CRC가 있는지 확인한다

I2C — 두 선을 여럿이 나눠 쓴다

I2C는 SDA(데이터)와 SCL(클럭) 두 선을 여러 장치가 공유한다. 핵심은 오픈 드레인 구조다. 어떤 장치도 선을 High로 밀지 않는다. 선을 Low로 끌어내릴 수만 있고, High는 풀업 저항 이 만든다. 그래서 풀업 저항이 없으면 버스가 동작하지 않고, 값이 잘못되면 가끔만 동작한다.

풀업 저항 값은 속도와 버스 정전용량(배선 길이·장치 수)의 균형이다. 저항이 크면 상승 시간이 길어져 빠른 속도에서 High가 제때 올라오지 않고, 저항이 작으면 장치가 Low로 끌어내릴 때 전류가 커진다. 오실로스코프로 상승 시간을 재는 것이 확인 방법이다(레슨 4).

트랜잭션 구조

S | 주소 7비트 | R/W | ACK | 데이터 8비트 | ACK | 데이터 8비트 | NACK | P
  START: SCL High인 동안 SDA가 High→Low
  STOP : SCL High인 동안 SDA가 Low→High
  ACK  : 수신 쪽이 9번째 클럭에서 SDA를 Low로 당김
  NACK : SDA가 High로 남음(아무도 당기지 않음)

주소는 7비트라서 한 버스에 이론상 112개 정도(예약 주소 제외)의 장치를 둘 수 있다. 같은 센서 두 개를 붙이려면 주소 핀으로 주소를 바꿔야 하고, 이 설정이 겹치면 두 장치가 동시에 응답 한다. 주소 표기는 데이터시트마다 7비트(0x50)와 R/W 비트를 붙인 8비트(0xA0/0xA1)로 달라서, 설정 오류의 단골 원인이다.

NACK은 "장치가 없다", "장치가 바쁘다", "마지막 바이트를 다 받았다"를 모두 뜻할 수 있다. EEPROM은 쓰기 사이클(수 ms) 동안 NACK으로 응답한다. 이때 소프트웨어가 재시도 없이 실패로 처리 하면 연속 쓰기에서 간헐적 저장 실패가 된다.

속도 모드

모드최대 속도
Standard-mode100 kbit/s
Fast-mode400 kbit/s
Fast-mode Plus1 Mbit/s
High-speed mode3.4 Mbit/s

버스에서 가장 느린 장치가 속도를 정한다. Fast-mode Plus를 지원하지 않는 센서가 하나라도 있으면 1MHz로 올릴 수 없다.

클럭 스트레칭

슬레이브가 준비되지 않았을 때 SCL을 Low로 붙잡아 마스터를 기다리게 하는 기능이다. 마스터가 이를 지원하지 않거나, 소프트웨어로 흉내 낸(bit-bang) I2C가 SCL을 확인하지 않으면 슬레이브가 준비되기 전에 데이터를 읽어 쓰레기 값이 나온다. 스트레칭이 비정상적으로 길어지면 마스터가 무한히 기다리므로 타임아웃이 있는지 가 시험 포인트다.

버스 고착과 복구

I2C의 대표적 현장 결함은 SDA가 Low로 고착 되는 것이다. 슬레이브가 바이트 전송 도중 마스터가 리셋되면, 슬레이브는 아직 전송 중이라고 생각하고 SDA를 Low로 붙잡은 채 다음 클럭을 기다린다. 마스터는 버스가 사용 중이라 START를 못 보낸다. 교착이다.

표준적인 복구 방법은 마스터가 SCL에 클럭을 최대 9번 보내 슬레이브가 남은 비트를 다 내보내게 한 뒤 STOP을 보내는 것이다. 시험은 이렇게 한다.

1. 센서 읽기 루프를 돌린다
2. 로직 분석기로 데이터 바이트 중간에 트리거
3. 그 순간 MCU만 리셋(워치독 강제 만료 또는 리셋 핀)
4. 판정: 재부팅 후 버스 복구 루틴이 동작해 센서 읽기가 재개되는가
         복구되지 않으면 전원을 끊기 전까지 센서가 죽어 있음 → 결함

세 프로토콜의 결함·경계값 시험 케이스

모듈 3 레슨 1의 경계값 분석을 통신 설정에 그대로 적용하면 이런 표가 된다.

ID대상시험 조건기대 결과잡는 결함
U-01UART상대 장치 보드레이트 −3%, +3%오류 없이 수신분주 오차가 큰 설정
U-02UART상대 보드레이트 −6%, +6%프레이밍 오류 감지·카운트, 시스템 멈춤 없음오류 처리 누락, 무한 루프
U-03UART최대 속도로 수신 버퍼 크기 +1바이트 연속 전송, 동시에 타이머 인터럽트 부하오버런 없음 또는 감지 후 복구ISR 지연, 버퍼 부족
U-05UART저온(−20°C)·고온(+70°C)에서 U-01 반복동일 결과RC 발진기 온도 드리프트
S-01SPI클럭을 규격 최대, 최대의 110%최대에서 정상, 초과에서 오류 검출여유 없는 타이밍
S-02SPI최적화 수준 변경 빌드(-O0, -O2)동일 동작CS 셋업 시간이 코드 속도에 의존
S-03SPI두 태스크가 같은 버스의 다른 장치에 동시 접근데이터 혼선 없음버스 잠금 누락, CS 동시 활성
I-01I2C존재하지 않는 주소로 읽기NACK 처리, 타임아웃 내 오류 반환NACK 무시, 무한 대기
I-02I2CEEPROM 연속 페이지 쓰기쓰기 사이클 NACK을 재시도로 처리간헐적 저장 실패
I-03I2C슬레이브가 SCL을 규정보다 길게 붙잡음마스터 타임아웃 후 복구무한 대기
I-04I2C전송 중 마스터 리셋(버스 고착 유도)재부팅 후 9클럭 복구, 통신 재개복구 루틴 없음
I-05I2C풀업 저항을 설계값의 2배로 교체, 버스 속도 최대상승 시간 규격 이내, 오류 없음풀업·정전용량 여유 부족

U-02처럼 범위 밖 조건에서의 기대 결과는 "동작"이 아니라 "안전하게 실패" 다. 오류를 감지하고 카운트하고, 시스템 전체가 멈추지 않는 것이 합격이다.

실무에서 왜 필요한가

직렬 통신 결함은 재현이 어렵고 증상이 엉뚱한 곳에 나타난다. SPI 모드가 틀린 온도 센서는 "온도가 가끔 두 배로 튄다"로 보고되고, 복구 루틴이 없는 I2C 버스 고착은 "현장에서 가끔 센서가 죽는데 전원을 껐다 켜면 된다"로 보고된다. 개발자는 벤치에서 재현하지 못하면 "하드웨어 문제"로 넘기기 쉽다. 프로토콜의 프레임과 경계 조건을 아는 테스터는 증상을 통신 층의 가설로 바꾸고, 로직 분석기로 그 가설을 확인하고, 설정·타이밍·복구 중 어디가 문제인지 결함 보고서에 적을 수 있다. 이것이 "재현 안 됨"으로 닫힐 결함을 수정 가능한 결함으로 바꾸는 차이다.

채용시장에서의 위치

임베디드 검증 공고의 자격요건에 "UART·SPI·I2C·CAN 등 통신 프로토콜 이해"가 거의 빠지지 않는다. 면접에서는 "UART 보드레이트가 3% 어긋나면 어떻게 되나", "SPI 모드가 틀리면 어떤 증상이 나오나", "I2C 버스가 Low로 고착되면 어떻게 복구하나" 같은 질문이 나온다. 정답 암기보다 증상에서 원인을 추론하고 시험으로 확인하는 순서 를 말할 수 있는지가 평가된다. 로직 분석기로 직접 디코딩해 본 경험, 보드레이트 오차를 계산해 본 경험이 있으면 웹 QA 출신이어도 설득력이 크게 올라간다.

실습 과제

과제 1 — 보드레이트 오차 계산 (10분)

MCU 클럭 8MHz, 16배 오버샘플링 UART로 9600, 57600, 115200bps를 만들 때 각각의 분주값(반올림)과 실제 속도, 오차(%)를 계산한다. 어느 설정이 ±2% 안전 범위를 벗어나는지 표시하고, 벗어나는 설정에 대해 개발팀에 제안할 대안(클럭 변경, 8배 오버샘플링, 소수 분주 지원 여부 확인)을 한 줄씩 적는다.

과제 2 — SPI 모드 불일치 증상 추론 (10분)

온도 센서가 SPI 모드 0을 요구하는데 MCU가 모드 1로 설정되어 있다. 센서가 0x19(25°C)를 보낼 때 MCU가 읽을 수 있는 값이 무엇일지 비트 단위로 추론하고, "온도가 가끔 튄다"는 현장 보고와 연결해 결함 보고서의 원인 가설 문단을 3~4문장으로 쓴다.

과제 3 — I2C 시험 케이스 확장 (15분)

본문 시험 케이스 표의 I-01~I-05에 더해, 한 버스에 온도 센서(0x48), EEPROM(0x50), 전원 관리 칩(0x68)이 있는 보드를 가정해 추가 케이스 4개를 설계한다. 주소 충돌, 한 장치의 전원만 꺼진 상태, 버스 속도 변경, EEPROM 쓰기 중 다른 장치 읽기를 각각 한 케이스로 만들고 기대 결과와 잡는 결함을 적는다.

자가 체크리스트

  • UART 프레임(시작·데이터·패리티·정지 비트)과 8N1의 의미를 그림으로 설명할 수 있다
  • 보드레이트 오차가 어디서 생기고 실무 허용 범위가 대략 얼마인지 계산으로 보일 수 있다
  • 프레이밍 오류와 오버런 오류의 차이와 각각의 흔한 원인을 말할 수 있다
  • SPI의 네 선과 CPOL·CPHA 모드 0~3, 모드 불일치의 전형적 증상을 설명할 수 있다
  • I2C가 풀업 저항을 필요로 하는 이유와 ACK/NACK의 여러 의미를 말할 수 있다
  • 클럭 스트레칭과 버스 고착의 원인, 9클럭 복구 절차와 그 시험 방법을 설명할 수 있다
  • 통신 설정을 경계값 시험 케이스로 바꾸고 범위 밖 조건의 기대 결과를 "안전하게 실패"로 적을 수 있다

흔한 실수

  • "통신이 된다"를 한 번의 정상 송수신으로 판정한다. 보드레이트 오차·모드 불일치는 대부분 맞고 가끔 틀린다. 장시간·온도·속도 경계에서 반복해야 한다.
  • 범위 밖 조건의 기대 결과를 비워 둔다. 설정 밖에서의 합격 기준은 오류 감지와 복구, 시스템 전체가 멈추지 않는 것이다.
  • 오버런을 통신 문제로만 본다. 오버런은 대개 소프트웨어가 늦게 읽어서 생긴다. 인터럽트 부하를 겹쳐 시험해야 드러난다.
  • I2C 주소를 7비트·8비트 표기 확인 없이 옮겨 적는다. 0x50과 0xA0은 같은 장치일 수 있다. 데이터시트의 표기 방식을 먼저 확인한다.
  • NACK을 곧바로 장치 고장으로 처리한다. EEPROM의 쓰기 사이클 NACK은 정상 동작이다. 재시도 정책이 있는지 확인한다.
  • 버스 고착 복구를 시험하지 않는다. 벤치에서는 전원을 자주 껐다 켜서 드러나지 않는다. 전송 중 리셋을 의도적으로 만들어야 한다.
  • SPI에 무결성 검사가 있다고 가정한다. SPI 자체는 아무것도 확인하지 않는다. 되읽기나 CRC가 설계에 있는지 확인한다.

참고 자료

  • NXP UM10204 — I2C-bus specification and user manual — 속도 모드, 풀업 계산, 클럭 스트레칭, 버스 복구 절차의 1차 출처
  • Analog Devices, "Introduction to SPI Interface" (Analog Dialogue) — CPOL·CPHA 모드 설명
  • 사용 중인 MCU의 레퍼런스 매뉴얼(UART·SPI·I2C 장)과 각 주변 칩 데이터시트의 타이밍 표 — 셋업·홀드 시간의 실제 근거
  • 레슨 s5-m46-l01 — 인터럽트와 ISR 지연이 만드는 비결정적 결함
  • 레슨 s1-m03-l01 — 동등분할과 경계값 분석
  • 레슨 s5-m46-l04 — 로직 분석기 프로토콜 디코딩과 트리거

낯선 말 풀이

이 레슨에 나온 약어입니다. 본문에서도 처음 나올 때 점선으로 표시해 두었습니다 (제목과 링크 글자는 그대로 둡니다).

TCP — 전송 제어 규약
데이터를 빠뜨리지 않고 순서대로 보내는 약속. 웹도 이 위에서 돌아간다.
UART — 직렬 통신 장치
기기와 컴퓨터를 선으로 잇고 글자를 한 줄씩 주고받는 가장 단순한 통신 방식.
CS — 고객 지원 · 칩 선택 신호
이 커리큘럼에서 두 가지로 쓰인다. ① 고객 문의와 불만을 직접 받는 조직 ② 여러 부품이 한 선을 나눠 쓸 때 "지금은 네 차례" 라고 하나를 고르는 신호. 앞뒤에 문의·고객이 있으면 ①, 통신·배선 이야기면 ②다.
CRC — 순환 중복 검사
데이터가 전송 중에 깨지지 않았는지 짧은 검사값으로 확인하는 방법.
MCU — 마이크로컨트롤러
아주 작은 컴퓨터 한 칩. 가전·자동차·산업 기기 안에 들어간다.
ID — 식별자
무엇 하나를 다른 것과 구별하기 위해 붙인 이름이나 번호.
CAN — 캔 통신
자동차 안의 작은 컴퓨터들이 서로 신호를 주고받는 통신 방식.
QA — 품질보증
만든 것이 쓸 만한지 확인하고, 애초에 덜 망가지게 만드는 방법을 정하는 일. "테스트"는 그 일의 일부다.

용어집 전체 보기