[프로젝트 회고-①] 통신 구조 다시 살펴보기
#Embedded최근 진행한 프로젝트 통신 위주로 다시 살펴보기
최근 임베디드 스쿨에서 차량용 임베디드 SW 개발 프로젝트를 진행했다.
기간은 26.03.25 ~ 26.04.08으로 총 15일간 진행한 프로젝트로 짧은 기간이였지만 주말 포함 하루 10시간이상 투자하고 막바지에는 밤도 새면서 진행한 프로젝트로 시스템 규모가 꽤 복잡하나 완성도 높게 마무리하였다.
MCU와 MCU 사이의 통신 그리고 MCU와 모듈들의 통신 구조를 다시 복습할 겸 회고하려고 한다.
소스코드는 여기에!
전체적인 시스템 설계서는 아래 그림과 같다.

위에서 내가 담당한 부분은 빨간 동그라미로 표시하였다.
운전석 ECU와 전동문 ECU 사이의 CAN 통신에서 추상화된 함수 개발은 다른 팀원이 담당하였고 나는 해당 함수를 사용하여 운전석 ECU위주에서 전동문 ECU와의 통신을 담당하였다.
위 시스템에서 통신 기술은 크게 3개(I2C, UART, CAN) 가 사용된다.
CAN 통신은 내용이 방대하고 어렵기 때문에 다음에 정리하고
이번에는 프로젝트에서는 사용하지는 않았지만 중요한 SPI통신까지 총 3가지 통신 (SPI, I2C, UART) 에 대해서 정리하려고 한다.
직렬(Serial) 통신
위에서 언급한 통신은 모두 데이터를 1비트씩 순차적으로 보내는 직렬(Serial) 통신이다.
이와 대비되는 병렬 통신이란 여러 개의 선을 이용해 데이터를 한 번에 보내는 방식이다.
예를 들어 8비트를 전송한다면 8개의 선을 이용해 한 번에 보낸다.
https://ko.wikipedia.org/wiki/%EC%A7%81%EB%A0%AC_%ED%86%B5%EC%8B%A0
속도가 빠르다는 장점이 있지만 배선이 복잡해지고 여러 개의 선을 모두 동일한 길이로 만들어 운영하기 어려워 전파 지연이 쉽게 발생하고 여러 개의 선으로 인해 신호 간섭에 취약하다.
현대에서는 주로 컴퓨터 내부 장치들이 통신할 때는 병럴 통신을 이용하고 외부와 통신할 때는 직렬 통신을 이용한다.
동기 통신
동기 통신이란 통신을 할 때 클럭도 같이 보내면서 동기화를 맞추는 통신이다.
클럭에 맞춰 데이터의 시작과 끝을 판단할 수 있다.
그러나 클럭을 같이 보내기 때문에 거리가 비교적 짧은 환경에서 활용된다.
SPI통신과 I2C 통신이 대표적이다.
SPI(Serial Peripheral Interface)
SPI 통신은 동기 직렬 통신으로 기본적으로 4개의 선이 필요합니다.
구조: 1개의 마스터가 1개 이상의 슬레이브를 제어 (마스터-슬레이브 구조) -> 1:N
신호선: 4개의 신호선을 사용
- SCLK (Serial Clock): 마스터가 생성하는 클록 신호
- MOSI (Master Out Slave In) : 마스터에서 슬레이브로 데이터 전송
- MISO (Master In Slave Out) : 슬레이브에서 마스터로 데이터 전송
- SS/CS (Slave Slect/Chip Select) : 통신할 슬레이브를 선택
데이터 전송을 위한 선이 두 개 존재하므로 당연히 전이중(Full-Duplex) 통신 을 지원한다.
https://wikidocs.net/278729
슬레이브가 추가될 때마다 CS 선을 추가 연결하여 슬레이브를 구별한다.
고속으로 데이터 전송이 가능하고 낮은 전력을 소비하는 장치에 적합하다.
단점으로는 많은 핀 수가 필요하고 클럭 기반이라 비교적 짧은 거리에서 작동한다.
I2C(Inter-Integrated Circuit)
I2C 통신은 마찬가지로 동기 직렬 통신이나 2개의 선이 필요하다.
구조: 멀티 마스터 / 멀티 슬레이브 -> N:N
신호선:
- SDA(Serial Data) : 데이터 전송
- SCL(Serial Clock) : 클럭 전송
SDA와 SCL은 풀업 저항을 통해 VCC와 연결되어 있다.
https://en.wikipedia.org/wiki/I%C2%B2C
- SCL와 SDA가 High로 유지된다.
- SDA가 LOW로 바뀌면서 데이터 통신 시작을 알린다. (노란색 S부분)
- SCL이 LOW 상태일 때 SDA는 비트를 변경한다. (파란색 부분)
- SCL이 High 상태일 때 SDA의 비트를 읽는다. (초록색 부분)
- 이 과정을 마지막 비트(N)까지 반복한다.
- SCL과 SDA가 둘다 High로 다시 돌아오면 통신이 끝났다. (노란색 P부분)
선이 두 개이기 때문에 마스터는 슬레이브를 주소값을 기반으로 구별한다.
데이터 전송을 위한 선이 1개이기 때문에 당연히 반이중(Half-Duplex) 통신만 가능하다.
정확히는 SDA 하나를 여러 디바이스가 공유하는 구조이기에 동시에 송수신할 수 없는 구조이다.
이번 프로젝트에서 모니터링 기능을 위한 LCD 디스플레이에 I2C 통신을 사용하였는데
디스플레이는 MCU한테 받은 데이터를 표시만 해주면 되지 MCU한테 따로 데이터를 보낼 일이 없기 때문에 반이중 통신의 I2C가 적합했다.
비동기 통신
앞서 살펴본 SPI와 I2C는 동기 통신으로 클럭을 전송할 선이 따로 필요했다.
클럭을 이용해서 데이터 프레임의 시작과 끝을 알 수 있기 때문에 클럭을 사용했지만 비동기 통신에는 클럭을 같이 보내지 않아도 된다.
그러면 어떻게 데이터 프레임의 시작과 끝을 알 수 있을까?
- 데이터의 시작을 알리는
Start Bit와 종료를 알리는Stop Bit를 넣어서 보내면 된다.
비동기 통신은 클럭 신호를 같이 보내지 않기 때문에 동기 통신에 비해 통신 거리가 길다는 장점이 있지만 Start와 Stop 비트 등이 추가되어 통신 오버헤드가 비교적 크다는 단점이 있다.
이번에는 대표적인 비동기 통신인 UART을 보자.
UART(Universal Asynchronous Receiver Transmitter)
UART는 TX와 RX 두 개의 선을 이용해서 통신한다. 데이터 선이 2개이므로 당연히 전이중(Full-Duplex) 통신 을 지원한다.
다른 통신과 대비되는 UART의 특징은 1:1 통신만 가능하다는 점이다.
주로 MCU와 MCU 사이의 통신 혹은 USB-UART를 이용하여 PC에서 디버깅할 때 사용된다.
이번 프로젝트에서는 TC375와 오디오 모듈(keyes player mini), 블루투스 모듈(ESP32) 사이의 통신에서 사용이 되었다.
또한 초음파 센서를 활용한 거리 측정에서 거리 값을 실시간으로 확인하기 위해 USB-UART를 사용하여 Putty에서 디버깅 용도로 사용했다.