직렬 통신 방식

UART, I2C, SPI

마이크로컨트롤러에서 사용하는 직렬serial 통신은 크게 다음과 같이 분류할 수 있다:

  동기(synchronous) 비동기(asynchronous)
전이중(full-duplex) SPI UART
반이중(half-duplex) I2C  

통신방향에는 세가지 종류가 있다:

  1. Simplex – 단방향 연결
    • 데이터 전송이 단방향으로만 가능하다
  2. Half duplex – 양방향 연결, 단방향 전송
    • 데이터 전송이 양방향으로 가능하지만, 한번에 한방향으로만 가능하다
  3. Full duplex – 양방향 연결, 쌍방 전송
    • 양방향으로 동시에 데이터 전송이 가능하다

UART(Universal Asynchronous Receiver/Transmitter)

위 표에 언급한 세가지 통신방식 중 가장 간단하고 느린 통신 방식. RX와 TX 단 두라인을 사용하는 비동기 방식의 전이중 통신이며, 1:1 연결을 갖는다. 쌍방간에 미리 정의된 통신속도(baudrate)와 패리티 유/무, 그리고 stop 비트 갯수에 따라 비트를 해석한다. 보통 8비트의 데이터와 1비트의 start 비트, 그리고 1비트의 stop 비트, 총 10비트 프레임을 전송한다. start 비트는 불리언 로직상 false(low) 값을 갖고, stop 비트는 true(high) 값을 갖는다.

데이터시트를 보면 통상 클럭에 따른 +/- 에러율을 표기하는데, 클럭이 통신속도를 지원하기에 느리거나, 분주비가 정수로 떨어지지 않은 경우 쌍방간의 동기 타이밍이 어긋날 수 있음을 나타낸다. + 에러일 경우 클럭에서 분주된 통신속도가 설정된 통신속도보다 빠르다는 것이고, - 일 경우 느리다는 것이다1. 에러 마진을 계산할 때는 송신, 수신 양측을 고려해야 한다. 예컨대, 송신측이 2% 빠르고 수신측도 2% 빠를 경우 에러율은 0% 이다.

baud rate error

클럭 에러는 프레임 시작부터 idle 까지 누적된다. idle 타임 뒤의 새로운 프레임은 이전 클럭 에러에서 자유롭다. 반면, idle 이 없는 경우 에러는 계속 누적될 것이다.

각 비트는 샘플링을 통해 수신된다. 통상 16 개.

RS232, RS485, RS422를 비롯해서 쉘 기능을 구현하는 등, MCU 디버깅용으로도 아직까지 널리 쓰이고 있다.

I2C(Inter-intergrated circuit)

I2C(아이-스퀘어드-씨)는 SDA와 SCL 단 두라인을 사용하는 동기 방식의 반이중 통신이다. 고유한 address를 갖는 여러개의 slave가 하나의 master와 통신하도록 보통 구성된다. 데이터 전송은 항상 start condition 으로 시작해 stop condition 으로 끝난다. 각 condition은 SCL 라인이 high일 때, SDA의 falling edge에서 검출하기 때문에 데이터(또는 제어비트)와 구분된다. start/stop condition 외의 데이타 또는 제어비트들은 SCL 라인이 반드시 low일 때 상태전이가 일어나기 때문이다.

그외 기억해둘만한 특징은 두 라인 모두 풀업 저항으로 묶이도록 구현되어 있기 때문에 master/slave 어느쪽에서나 라인을 제어할 수 있다는 것이다. 가령 slave는 어떤 행위를 준비하는 동안 master가 보내는 클럭을 잠시 잡아둘 수 있다(동기화). 이 특성때문에 N:N multi master 연결이 가능해진다.

온도, 습도, 가속도 등 여러 센서 모듈의 인터페이스가 대게 I2C로 만들어진다.

MCU 개발 경력이 좀 된다면 한번씩은 I2C 때문에 골머리 썩은 경험이 있을 것이다. 소프트웨어적으로 구현이 간단하기도 하고, 하드웨어적으로 구현된 다른 주변장치에 비해 erratum 문서가 많은만큼 SoC에서 제공하는 기능을 사용하기보다 직접 구현해 쓰는 게 속 편한 경우가 있다. 프로토콜 자체는 단순한 데 비해 어딜가나 I2C 이슈는 빠지지 않고 볼 수 있었다.

아래는 STM32 기반 하드웨어적으로 구현된 I2C 사용방법을 설명한다.

Slave mode

  • The address of the interface
    • OAR1
    • OAR2(if ENDUAL=1)
    • General Call address(if ENGC=1)
  • 헤더 또는 어드레스가 일치하지 않는 경우 무시, 다음 start condition을 기다림
  • 헤더가 일치하고 10비트 모드일 경우 ACK 응답
  • 어드레스가 일치하는 경우:
    • ACK 응답
    • ADDR 플래그 비트 활성
    • 인터럽트 발생(if ITEVFEN=1)
    • 듀얼모드(ENDUAL=1)일 경우 소프트웨어는 DUALF 비트를 체크해야 함
  • TRA 비트로 수신모드인지 전송모드인지 판단할 수 있음
  • 10비트 모드에서 어드레스를 수신한 뒤부터 slave는 항상 수신모드에 있음. 헤더 다음 바이트가(11110xx1)이고 start condition이 연속으로 두번 따라오면 전송모드로 전환됨
  • 어드레스가 수신되면, ADDR 비트가 클리어될 때까지 SCL 라인은 low 상태를 유지

Slave transmitter

  1. 어드레스를 수신(ADDR=1)한 뒤 해당 비트를 클리어(SR1->SR2 순서로 읽기)
  2. 데이터 레지스터(DR)가 비어있을 경우(TxE=1) 해당 레지스터에 데이터 저장
    • DR 레지스터에 데이터가 쓰여지면 TxE 비트는 자동으로 클리어 됨
  3. ACK 응답을 받으면 TxE 비트가 활성화됨가 동시에 인터럽트 발생(if ITEVFEN=1 & ITBUFEN=1)

  • slave는 ADDR 비트가 클리어되고 DR 레지스터가 데이터로 채워질 때까지 SCL 라인을 low 상태로 유지
  • TxE 비트가 활성된 상태에서 다음 데이터 전송 마지막까지 DR 레지스터에 아무런 값이 쓰여지지 않으면 BTF 비트가 활성화되고 SCL 라인은 low 상태를 유지하게 됨. BTF 비트는 R1->SR1 순서로 읽으면 클리어 되고, SCL 라인도 동작 재개.

Slave receiver

  1. 어드레스 수신 후, ADDR 비트를 클리어하면 slave는 데이터를 수신하기 시작
  2. 각 바이트 수신할 때마다:
    • 응답(if ACK=1)비트 발송
    • RxNE 플래그 활성
    • 인터럽트 발생(if ITEVFEN=1 & ITBUFEN=1)
  3. 마지막 바이트가 전송된 뒤 master는 Stop Condtion을 발생시킴. slave는 stop condtion을 detect하고 STOPF 비트를 활성, 인터럽트 발생(if ITEVFEN=1)

  • RxEN 비트가 활성화되었지만 다음 데이터 수신까지 DR 레지스터를 읽지 않는다면 BTF 비트가 활성, SCL 라인은 low 상태 유지
  • RxNE=1 인 경우, 현재 데이터의 전송이 완료되기 전에 DR 레지스터를 읽으므로써 RxNE 비트를 클리어해주어야 함
  • 사용자는 SR1 레지스터를 읽고 활성화된 비트를 반드시 클리어해주어야 함
    • 따라서 i2c 인터럽트 서비스 루틴에서는 ADDR과 STOPF 비트가 모두 활성화된 경우 두 비트 모두 클리어 시키기위해 다음과 같이 처리를 해주어야 함:
      • if (ADDR == 1) { READ SR1; READ SR2; }
      • if (STOPF == 1) { READ SR1; READ CR1; }

Master mode

Start condition을 발생하면 자동적으로 master mode로 전환된다(MSL 비트 활성). Master mode는 다음과 같이 준비되어야 한다:

  1. CR2 레지스터에서 peripheral input clock 설정
    • Sm mode에서는 최소 2MHz, Fm mode에서는 최소 4MHz
  2. CCR(clock control registers) 설정
  3. TRISE(rise time register) 설정
  4. CR1 레지스터에서 PE(peripheral) 활성화
  5. CR1 레지스터에서 START 비트 활성
    • SB 비트가 활성, 인터럽트 발생(if ITEVFEN=1)
  6. SR1 레지스터 체크 후 DR 레지스터에 slave address 저장
    • 위 시퀀스로 SB 비트가 클리어 됨
    • slave address의 최하위 비트LSB가 1이면 receiver mode, 0이면 transmitter mode
  7. ADDR 비트 활성, 인터럽트 발생(if ITEVFEN=1)
    • SR1->SR2 순서로 레지스터를 읽으면 ADDR 비트가 클리어 됨
  8. ACK 응답 받으면 TxE 비트 활성, 인터럽트 발생(if ITEVFEN=1 & ITBUFEN=1)
    • DR 레지스터에 전송할 데이터를 저장하면 TxE 비트는 클리어 됨
    • TxE 비트가 활성화되어 있고 DR 레지스터에 데이터가 입력되지 않으면 BTF 비트가 활성(SCL 라인 low로 유지, SR1 레지스터 읽고 DR 레지스터에 데이터를 입력하면 BTF 비트 클리어 됨)
  9. 마지막 데이터가 전송되고 나면 STOP 비트를 활성
    • STOP 비트는 TxE 비트와 BTF 비트 모두 활성된 상태에서 set되어야 함
    • MSL 비트는 클리어되고 slave mode로 돌아감

Master receiver

Receiver 모드일 때 master는 각 바이트를 수신할 때 마다:

  • acknowledge pulse를 전송
  • RxNE 비트 활성, 인터럽트 발생(if ITEVFEN=1 & ITBUFEN)
Closing the communication
Method 1 (when interrupts have the highest priority)
  1. NACK 신호를 보내기 위해서는 두번째 마지막 데이터 바이트를 수신했을 때 ACK 비트를 클리어해야 함
  2. Stop/Restart 신호를 보내기 위해서는 해당 비트를 두번째 마지막 데이터 바이트를 수신했을 때 설정해야 함
  3. single 바이트인 경우 acknowledge는 비활성, stop condition은 ADDR 비트를 클리어 한뒤 바로 설정되어야 함
Method 2 (when lower priority or polling)
  1. 마지막 세 바이트가 남았을 때, RxNE가 활성되더라도 DR을 읽지 않는다
  2. N-1번째 데이터가 도착했을 때 데이터 레지스터와 시프트 레지스터 모두 가득 찬 상태이기 때문에 BTF 비트가 활성화된다(따라서 SCL 라인은 low 상태로 유지됨)
  3. 이 때 ACK 비트를 클리어하고 DR 레지스터를 읽는다(N-2번째 데이터)
  4. 그러면 N번째 데이터를 수신하게 되고 NACK 신호를 보내게 됨
  5. START/STOP 설정
  6. DR 읽음(N-1번째 데이터)
  7. RxEN이 활성화 될 때까지 기다림
  8. DR 읽음(N번째 데이터)

위 내용은 N>2인 경우에만 유효하다. Single byte인 경우는 다음과 같이 수행:

  1. ADDR 비트가 활성화되었을 때 ACK 비트를 클리어
  2. ADDR 비트를 클리어
  3. STOP/START 설정
  4. RxNE 비트가 활성화 되었을 때 DR 레지스터 읽음

Two bytes인 경우:

  1. ACK 비트와 POS 비트 모두 설정
  2. ADDR 비트가 활성화될 때까지 기다림
  3. ADDR 비트 클리어
  4. ACK 비트 클리어
  5. BTF 비트가 활성화될 때까지 기다림
  6. STOP 비트 설정
  7. DR 레지스터를 두차례 걸쳐 읽음

Error conditions

Bus error(BERR)

어드레스 혹은 데이터 전송 중에 stop 또는 start condition 신호가 포착될 경우 발생.

  • BERR 비트 활성, 인터럽트 발생(if ITERREN=1)
  • slave mode일 경우 데이터는 discard되고 라인은 release 됨
    • start 오류인 경우, slave는 restart로 해석하고 주소 또는 stop condition을 기다림
    • stop 오류인 경우, stop condition으로 해석함
  • master mode인 경우 무시함, 현재 전송 상태가 유지됨. 전적으로 소프트웨어 처리에 달려있음

Acknowledge failure(AF)

nonacknowledge 비트를 포착한 경우 발생.

  • AF 비트 활성, 인터럽트 발생(if ITERREN=1)
  • 송신측은 통신을 반드시 reset 해야함
    • slave인 경우, 라인들이 released 됨
    • master인 경우, stop 또는 start condition이 재전송되어야 함

Arbitration lost(ARLO)

Overrun/underrun error(OVR)

Interrupts

Interrupt event Event flag Enable control bit
Start bit sent(Master) SB ITEVFEN
Address sent(Master) or Address matched(Slave) ADDR ITEVFEN
10-bit header sent(Master) ADD10 ITEVFEN
Stop received(Slave) STOPF ITEVFEN
Data byte transfer finished BTF ITEVFEN
Receive buffer not empty RxNE ITEVFEN and ITBUFEN
Transmit buffer empty TxE ITEVFEN and ITBUFEN
Bus error BERR ITERREN
Arbitration loss(Master) ARLO ITERREN
Acknowledge failure AF ITERREN
Overrun/Underrun OVR ITERREN
PEC error PECERR ITERREN
Timeout/Tlow error TIMEOUT ITERREN
SMBus Alert SMBALERT ITERREN

SPI(Serial Peripheral Interface)

언급된 통신 방식 중 가장 고속으로 SD 카드와 같은 고속 통신이 필요한 주변장치 인터페이스에 사용된다.

보통 MISO, MOSI, SCK, SS 네 개의 핀을 데이지 체인 방식으로 연결한다. 입출력 핀이 따로 있는 것으로 알 수 있듯이 1:N 동기식 전이중 통신.

모드와 클럭 극polarity, 상phase 에 대한 내용은 차차 업데이트하기로..

References