๐ English Abstract
This comprehensive technical guide addresses critical hardware and firmware challenges in multi-slave RS-485 Modbus RTU networks. It details practical troubleshooting methods for resolving ground loop noise via galvanic isolation and tuning driver enable (DE) switching timing to prevent frame truncation. Furthermore, it outlines a robust implementation of non-blocking, circular DMA reception combined with UART Idle Line Detection to eliminate buffer overruns and process variable-length frames efficiently.
์ฐ์ ์ฉ ํ์ฅ(Industrial Field)์์ ๊ฐ์ฅ ๊ด๋ฒ์ํ๊ฒ ์ฌ์ฉ๋๋ ์ง๋ ฌ ํต์ (Serial Communication) ํ๋กํ ์ฝ ์ค ํ๋๋ ๋จ์ฐ RS-485 ๊ธฐ๋ฐ Modbus RTU์ ๋๋ค. ์ฐจ๋ ์ ํธ(Differential Signaling) ๋ฐฉ์์ ์ฌ์ฉํ๋ฏ๋ก ์ด๋ก ์ ์ผ๋ก ์ต๋ 1.2km ๊ฑฐ๋ฆฌ๊น์ง 115.2kbps ์ด์์ ์๋๋ก ์์ ์ ์ธ ๋ฐ์ดํฐ ์ ์ก์ด ๊ฐ๋ฅํ์ง๋ง, ์ค์ ๋ค์ค ์ฌ๋ ์ด๋ธ(Multi-Slave) ํ ํด๋ก์ง ํ์ฅ์์๋ ์์ธ์ ์ ์ ์๋ ํ๋ ์ ์์ค(Frame Loss), CRC ์ค๋ฅ(Cyclic Redundancy Check Error), UART ์์ ์ค๋ฒ๋ฐ(Overrun Error) ๋ฌธ์ ๋ก ์ธํด ํต์ ์ ๋ขฐ์ฑ์ด ๊ธ๊ฒฉํ ๋จ์ด์ง๋ ๊ฒฝ์ฐ๊ฐ ๋น๋ฒํ๊ฒ ๋ฐ์ํฉ๋๋ค.
๋ณธ ํฌ์คํ ์์๋ RS-485 Modbus RTU ๋ค์ค ์ฌ๋ ์ด๋ธ ์์คํ ์์ ๋ฐ์ํ๋ ํ๋์จ์ด์ ๊ฒฐํจ์ธ ์ ์ง ๋ฃจํ ๋ ธ์ด์ฆ(Ground Loop Noise)์ ๋ฒ์ค ์ ํ ์ง์ฐ(Bus Turnaround Delay) ๋ฌธ์ ์ ์์ธ์ ์ ๋ฐ ๋ถ์ํ๊ณ , ์ด๋ฅผ ์๋ฒฝํ ํด๊ฒฐํ๋ ํ๋์จ์ด ์ค๊ณ์๊ณผ ์๋ฒ ๋๋ MCU(STM32 ๋ฑ) ํ๊ฒฝ์์์ ๋ฌด์์(Non-blocking) ์ํ DMA(Circular DMA) ์์ ๋ฒํผ ๊ตฌํ ํธ๋ฌ๋ธ์ํ ๊ณผ์ ์ ์์ธํ ๋ค๋ฃน๋๋ค.
1. ์ ์ง ๋ฃจํ ๋ ธ์ด์ฆ(Ground Loop Noise) ๋ฐ์ ์์ธ๊ณผ ํ๋์จ์ด ์ ์ฐ ์๋ฃจ์
๋ง์ ์์ง๋์ด๋ค์ด RS-485๋ ์ฐจ๋ ์ ํธ(A/B 2์ ์)์ด๋ฏ๋ก ์ ์ง(GND) ์ฐ๊ฒฐ์ด ํ์ ์๊ฑฐ๋, ๊ฐ ์ฌ๋ ์ด๋ธ ๋ ธ๋์ ์ ์ง๋ฅผ ๋จ์ํ ๋ฌถ์ด์ฃผ๊ธฐ๋ง ํ๋ฉด ๋๋ค๊ณ ์คํดํฉ๋๋ค. ํ์ง๋ง ์ด๋ ์ฅ๊ฑฐ๋ฆฌ ๋๋ ๊ณต์ฅ ์ ๋ ฅ๋ง ํ๊ฒฝ์์ ์์คํ ๋ถ๊ดด๋ฅผ ์ด๋ํ๋ ์ฃผ์์ธ์ด ๋ฉ๋๋ค.
๊ฐ. ์ ์ง ์ ์์ฐจ(Ground Potential Difference)์ ๊ณตํต ๋ชจ๋ ์ ์ ์์ฉ ๋ฒ์
RS-485 ํธ๋์๋ฒ(Transceiver) IC(์: MAX485, SN65HVD72 ๋ฑ)๋ ํ์ค ๊ท๊ฒฉ์ **๊ณตํต ๋ชจ๋ ์ ์(Common-Mode Voltage)** ์์ฉ ๋ฒ์๊ฐ -7V ~ +12V๋ก ์ ํ๋์ด ์์ต๋๋ค. ๋ฌผ๋ฆฌ์ ์ผ๋ก ๋จ์ด์ง ๋ง์คํฐ(Master) ์ฅ๋น์ ์ฌ๋ฌ ์ฌ๋ ์ด๋ธ(Slave) ๋ ธ๋๊ฐ ์๋ก ๋ค๋ฅธ ์ ์ ๊ณต๊ธ ์ฅ์น(Power Supply)๋ ์ใผใน(Earth Ground)๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ, ๊ฐ ์ง์ ๊ฐ์ ์ ๋ณผํธ์์ ์์ญ ๋ณผํธ์ ๋ฌํ๋ ์ ์ง ์ ์์ฐจ๊ฐ ๋ฐ์ํฉ๋๋ค.
- ๋ ธ์ด์ฆ ์ ์ ๊ฒฝ๋ก: ์ ์ง๊ฐ ์ ์์ฐจ๋ก ์ธํด ์ฐจํ ํธ์์คํธ ํ์ด ์ผ์ด๋ธ(STP)์ ์ด๋๋ง ๋๋ 3๋ฒ์งธ ์ ์ง์ ์ ๋ฐ๋ผ ๋์ฉ๋ ์ ๋ฅ๊ฐ ํ๋ฅด๋ ์ ์ง ๋ฃจํ(Ground Loop)๊ฐ ํ์ฑ๋ฉ๋๋ค.
- ํ์: ์ฐจ๋ ์ ํธ(V_A - V_B) ์์ ๊ณ ์ฃผํ ๋ฆฌํ ๋ฐ ์คํ์ ์ ์์ด ์ค๋ฆฌ๋ฉด์ ๊ณตํต ๋ชจ๋ ๋ฒ์๋ฅผ ์ด๊ณผํ๊ฒ ๋๊ณ , ํธ๋์๋ฒ ๋ด๋ถ ์์ ๋น๊ต๊ธฐ(Comparator)๊ฐ ๋ฐ์ดํฐ ๋นํธ๋ฅผ 0 ๋๋ 1๋ก ์ค์ธํ์ฌ CRC Mismatch ๋ฐ Framing Error๋ฅผ ์ ๋ฐํฉ๋๋ค. ์ฌํ ๊ฒฝ์ฐ ํธ๋์๋ฒ IC๊ฐ ํ๊ดด๋ฉ๋๋ค.
๋. ํ๋์จ์ด์ ํธ๋ฌ๋ธ์ํ : ๊ฐ๋ฐ๋ ์ ์ฐ(Galvanic Isolation) ์ ์ฉ
์ด ๋ฌธ์ ๋ฅผ ๊ทผ๋ณธ์ ์ผ๋ก ํด๊ฒฐํ๊ธฐ ์ํด์๋ ๊ฐ ์ฌ๋ ์ด๋ธ ๋ ธ๋์ RS-485 ๋ฌผ๋ฆฌ ๊ณ์ธต์ ์ ์ด๋ถ(MCU) ์ ์ ์์ญ๊ณผ ์์ ํ ์ ๊ธฐ์ ์ผ๋ก ๋ถ๋ฆฌํ๋ ๊ฐ๋ฐ๋ ์ ์ฐ(Galvanic Isolation)์ ์ ์ฉํด์ผ ํฉ๋๋ค.
- ๋์งํธ ์ ์ฐ๊ธฐ(Digital Isolator) ์ฌ์ฉ: ๊ณ ์ ์ตํ ์ปคํ๋ฌ(Optocoupler) ๋๋ ์์ด๋ก/์ฉ๋์ฑ ์ ์ฐ IC(์: ADuM1401, ISO7741)๋ฅผ MCU UART TX/RX/DE ๋ผ์ธ๊ณผ RS-485 ํธ๋์๋ฒ ์ฌ์ด์ ๋ฐฐ์นํฉ๋๋ค. ์ต๊ทผ์๋ ํธ๋์๋ฒ์ ์ ์ฐ๊ธฐ๊ฐ ์ผ์ฒดํ๋ ISO1410 ๋๋ ADM2483 ๊ฐ์ ์นฉ์ ๊ถ์ฅํฉ๋๋ค.
- ์ ์ฐ DC-DC ์ปจ๋ฒํฐ(Isolated DC-DC Converter): ํธ๋์๋ฒ VCC์ GND_ISO ์ ์์ 1:1 ์ ์ฐ DC-DC ์ปจ๋ฒํฐ(์: B0505S-1W)๋ฅผ ํตํด ๊ณต๊ธํ์ฌ ์์คํ GND์ ํต์ GND(ISO_GND)๋ฅผ ์์ ํ ๋ถ๋ฆฌํฉ๋๋ค.
- ๋จ์ผ ์ง์ ์ด๋ ์ ์ง(Single-point Shield Grounding): ์ด๋ ์ผ์ด๋ธ์ ์ฐจํ๋ง์ ๋ฐ๋์ ์ ์ฒด ๋ฒ์ค ๋คํธ์ํฌ ์ค ๋จ ํ ๊ณณ(๋ณดํต ๋ง์คํฐ ์ธก)์์๋ง Earth Ground์ ์ ์งํ๊ณ , ์ฌ๋ ์ด๋ธ ์ธก์ 100ฮฉ ์ ํญ๊ณผ 1nF ์บก(RC ํํฐ)์ ๊ฑฐ์ณ ์์์ ์ฐ๊ฒฐํ๊ฑฐ๋ floating ์์ผ ์ ์ง ๋ฃจํ ์ ๋ฅ ์์ฑ์ ์ฐจ๋จํฉ๋๋ค.
2. ๋ฒ์ค ์ ํ ์ง์ฐ(Bus Turnaround Delay) ๋ฐ DE Timing ํ์ด๋ฐ ํธ๋ฌ๋ธ์ํ
RS-485๋ ๋ฐ๋๊ณต(Half-Duplex) ํต์ ๋ฐฉ์์ ์ฌ์ฉํ๋ฏ๋ก, ๋ฐ์ดํฐ ์ก์ ์ ํธ๋์๋ฒ์ DE(Driver Enable) / RE(Receiver Enable) ํ์ ์ ์ดํ์ฌ ๋ฒ์ค ์ ์ ๊ถ์ ํ๋ํ๊ณ ์๋ฃ ํ ์ฆ์ ์์ ์ํ๋ก ์ ํํด์ผ ํฉ๋๋ค. ์ด ํ์ด๋ฐ ์กฐ์ ์คํจ๋ ํ๋ ์ ์์ค์ 50% ์ด์์ ์ฐจ์งํฉ๋๋ค.
๊ฐ. ์ก์ ์๋ฃ ์ธํฐ๋ฝํธ ์ ํ ์ค๋ฅ: TXE vs TC
STM32 ๋ฑ MCU ํ์จ์ด ์์ฑ ์ ํํ ํ๋ ์ค์๋ UART ์ก์ ์๋ฃ ํ์ ์ ๋ ์ง์คํฐ ๋น ์ํ(TXE: Transmit Data Register Empty)๋ก ํ๋ ๊ฒ์ ๋๋ค.
// ์๋ชป๋ ๊ตฌํ ์์ (Framing Cut-off ๋ฐ์)
void Modbus_SendByte(uint8_t data) {
USART1->DR = data;
while (!(USART1->SR & USART_SR_TXE)); // TXE๋ง ํ์ธํ๊ณ ๋ฐ๋ก DE๋ฅผ LOW๋ก ์ ํ!
RS485_DE_LOW(); // ๋ง์ง๋ง ๋ฐ์ดํธ์ Stop Bit๊ฐ ์ก์ ์ค์ธ๋ฐ ํธ๋์๋ฒ๊ฐ ๊บผ์ง!
}
ํด๊ฒฐ์ฑ : TXE๋ ์ก์ ๋ฐ์ดํฐ ๋ฒํผ๊ฐ ๋น์์์ ์๋ฏธํ ๋ฟ, ์ํํธ ๋ ์ง์คํฐ(Shift Register)๋ฅผ ํตํด ๋ผ์ธ์ผ๋ก ๋ฌผ๋ฆฌ์ ์ธ ๋นํธ๊ฐ ๋ชจ๋ ์ ์ก๋์์์ ๋ณด์ฅํ์ง ์์ต๋๋ค. ๋ฐ๋ผ์ ๋ฐ๋์ ์ํํธ ๋ ์ง์คํฐ๊น์ง ์์ ํ ๋น์์ง ๊ฒ์ ๋ํ๋ด๋ TC(Transmission Complete) ํ๋๊ทธ๋ฅผ ํ์ธํ ํ DE ํ์ ์์ ๋ชจ๋(LOW)๋ก ์ ํํด์ผ ํ๋ ์์ ๋ง์ง๋ง ๋ฐ์ดํธ ์๋ฆผ(Truncation)์ ๋ง์ ์ ์์ต๋๋ค.
๋. Modbus RTU t3.5 Silent Interval๊ณผ ํ๋์จ์ด ์๋ ๋ฐฉํฅ ์ ์ด
Modbus RTU ๊ท๊ฒฉ์ ํ๋ ์๊ณผ ํ๋ ์ ์ฌ์ด๋ฅผ ๊ตฌ๋ถํ๊ธฐ ์ํด ์ต์ 3.5 ๋ฐ์ดํธ ์ ์ก ์๊ฐ(t3.5) ์ด์์ ๋ฌด์ ํธ ์ ํด(Silent Interval) ์๊ฐ์ ์๊ตฌํฉ๋๋ค. ๋ณด๋ ์ดํธ(Baud Rate)๊ฐ 9600bps์ผ ๊ฒฝ์ฐ 1๋ฐ์ดํธ ์ ์ก ์๊ฐ์ ์ฝ 1.04ms์ด๋ฏ๋ก, t3.5๋ ์ฝ 3.64ms์ ๋๋ค.
- ๋ฌธ์ ์ํฉ: ์ฌ๋ ์ด๋ธ๊ฐ ๋ง์คํฐ์ ์๋ต ์๊ตฌ๋ ์๋ต ์ฒ๋ฆฌ ํ DE ํ์ ์์ ๋ชจ๋๋ก ๋ฆ๊ฒ ์ ํํ๋ฉด, ๋ง์คํฐ๊ฐ ์ ์กํ๋ ๋ค์ ํ๋ ์์ Header(Slave ID, Function Code) ๋ฐ์ดํธ๊ฐ ์ ์ค๋ฉ๋๋ค. ๋ฐ๋๋ก ๋๋ฌด ์ผ์ฐ ์ ํํ๋ฉด ์์ฌ ์๋ต์ Tail ๋ฐ์ดํธ๊ฐ ๊นจ์ง๋๋ค.
- ํ๋์จ์ด ์คํ ํ ๊ธ(Auto-Direction Control) ์ ์ฉ: ์ํํธ์จ์ด GPIO ์ ์ด ์ง์ฐ(Interrupt Latency) ๋ฌธ์ ๋ฅผ ์๋ฒฝํ ํํผํ๊ธฐ ์ํด THVD1429๋ MAX13487๊ณผ ๊ฐ์ด ํ๋์จ์ด ๋ด๋ถ์์ TXD ์ ํธ๋ฅผ ๊ฐ์งํ์ฌ DE๋ฅผ ์๋ ์ ์ดํ๋ ํธ๋์๋ฒ๋ฅผ ์ฌ์ฉํ๊ฑฐ๋, MCU ์์ฒด์ RS485 Driver Enable Hardware Flow Control feature(STM32์ `USART_CR3_DEM` / `DEAT`, `DEDT` ๋ ์ง์คํฐ)๋ฅผ ํ์ฑํํ์ฌ ๋๋ ธ์ด(ns) ๋จ์๋ก ์ ํํ๊ฒ timing์ ๋ง์ถฅ๋๋ค.
3. ๋ฌด์์/๋น๋๊ธฐ ์์ ์ ์ํ ์ํ DMA(Circular DMA) ์์ ๋ฒํผ ํธ๋ฌ๋ธ์ํ
Modbus RTU ๋ค์ค ์ฌ๋ ์ด๋ธ ๋คํธ์ํฌ์์๋ ๋ง์คํฐ์ ํด๋ง ์ฃผ๊ธฐ๊ฐ ๋ถ๊ท์นํ๊ฑฐ๋ ํต์ ๋ ธ์ด์ฆ๋ก ์ธํด ๊ฐ๋ณ ๊ธธ์ด์ ๋ฐ์ดํฐ ํจํท์ด ์์ ๋ฉ๋๋ค. ๋ฐ์ดํธ ๋จ์ ์ธํฐ๋ฝํธ(RXNE) ๋ฐฉ์์ ๊ณ ์ ํต์ (115.2kbps ์ด์) ์ MCU CPU ์ ์ ์จ์ ๊ทน๋๋ก ๋์ด๊ณ ์ค๋ฒ๋ฐ ์๋ฌ(ORE)๋ฅผ ์ ๋ฐํ๋ฏ๋ก, Circular DMA + IDLE Line Detection ์กฐํฉ์ด ํ์์ ์ ๋๋ค.
๊ฐ. UART Idle Line Interrupt์ Circular DMA ์ฐ๋ ๋ฉ์ปค๋์ฆ
UART ์์ ๋ผ์ธ์ด 1๋ฐ์ดํธ ์ด์ ๋์ High ์ํ๋ฅผ ์ ์ง(Idle ์ํ)ํ๋ฉด MCU๋ IDLE Line Flag๋ฅผ ์ธ์ฐ๊ณ ์ธํฐ๋ฝํธ๋ฅผ ๋ฐ์์ํต๋๋ค. DMA๋ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ๋ฉ๋ชจ๋ฆฌ๋ก ๋ฐ์ดํฐ๋ฅผ ์์ ํ๊ณ ์์ผ๋ฉฐ, IDLE ์ธํฐ๋ฝํธ๊ฐ ๋ฐ์ํ๋ ์์ ์ ์์ ๋ ๋ฐ์ดํฐ์ ๊ธธ์ด๋ฅผ ๊ณ์ฐํ์ฌ ํจํท์ ๋ถ๋ฆฌ ์ฒ๋ฆฌํฉ๋๋ค.
๋. ๋ฌด์์ DMA ์์ ๋ฒํผ Pointer Arithmetic (STM32 HAL ๊ธฐ์ค ๊ตฌํ ์์)
DMA ์์ ๋ฒํผ ํฌ๊ธฐ๊ฐ $N$์ผ ๋, DMA์ Counter ๋ ์ง์คํฐ(`NDTR`)๋ ๋ฐ์ดํฐ๊ฐ ์์ ๋ ๋๋ง๋ค $N$์์๋ถํฐ $0$์ผ๋ก ์นด์ดํธ๋ค์ด(Decrement)๋ฉ๋๋ค. ์ด๋ฅผ ํตํด ํ์ฌ ์์ฑ ์ค์ธ ๋ฒํผ์ ํค๋ ํฌ์ธํฐ๋ฅผ ์ญ์ฐํ์ฌ ๋ฌด์์๋ก ๋ค์ด์ค๋ ํ๋ ์์ ์ค์๊ฐ ์ฌ๋ผ์ด์ฑํฉ๋๋ค.
#define DMA_RX_BUFFER_SIZE 256
uint8_t dma_rx_ring_buffer[DMA_RX_BUFFER_SIZE];
uint16_t old_pos = 0;
// UART ์ด๊ธฐ์ DMA ์์ ๋ฐ IDLE ์ธํฐ๋ฝํธ ํ์ฑํ
void Modbus_UART_Init(void) {
HAL_UART_Receive_DMA(&huart1, dma_rx_ring_buffer, DMA_RX_BUFFER_SIZE);
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
}
// UART global interrupt service routine (ISR)
void USART1_IRQHandler(void) {
// IDLE Line ๊ฐ์ง ํ์ธ
if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET) {
__HAL_UART_CLEAR_IDLEFLAG(&huart1); // IDLE ํ๋๊ทธ ํด๋ฆฌ์ด
uint16_t current_pos = DMA_RX_BUFFER_SIZE - __HAL_DMA_GET_COUNTER(huart1.hdmarx);
if (current_pos != old_pos) {
uint16_t length = 0;
// Case A: ๋ฉ์ด๋ผ์ด๋(Wrap-around) ์์ด ์์ฐจ์ ๋ฐ์ดํฐ ์์
if (current_pos > old_pos) {
length = current_pos - old_pos;
Process_Modbus_Frame(&dma_rx_ring_buffer[old_pos], length);
}
// Case B: ๋ฒํผ ๋์ ๋์ด ๋ง ๋ฒํผ์ ์ฒ์์ผ๋ก ๋๋์๊ฐ ๊ฒฝ์ฐ (๋ฌด์์ ๋ฐ์ดํธ ์ฒ๋ฆฌ)
else {
length = (DMA_RX_BUFFER_SIZE - old_pos) + current_pos;
// ์์ linear ๋ฒํผ๋ก ์ชผ๊ฐ์ง ๋ฐ์ดํฐ ๋ณต์ฌ ํ ์ฒ๋ฆฌ
uint8_t temp_frame[DMA_RX_BUFFER_SIZE];
uint16_t head_len = DMA_RX_BUFFER_SIZE - old_pos;
memcpy(temp_frame, &dma_rx_ring_buffer[old_pos], head_len);
memcpy(&temp_frame[head_len], &dma_rx_ring_buffer[0], current_pos);
Process_Modbus_Frame(temp_frame, length);
}
old_pos = current_pos; // ํฌ์ธํฐ ๊ฐฑ์
}
}
HAL_UART_IRQHandler(&huart1);
}
๋ค. Edge Cases ๋ฐ ๋ฎ์ด์ฐ๊ธฐ(Data Overwrite) ๋ฐฉ์ง ๊ธฐ๋ฒ
๋ค์ค ์ฌ๋ ์ด๋ธ ํต์ ์ค ๋ง์คํฐ์ ๊ณ ์ Polling์ด๋ ๋ ธ์ด์ฆ์ฑ ๋ฒ์คํธ ๋ฐ์ดํฐ ์ ์ ์ DMA ์์ ๋ฒํผ๊ฐ ์ค๋ฒํ๋ก์ฐ(Overflow)๋ ์ ์์ต๋๋ค.
- Double Buffering ๋๋ Ping-Pong Buffer: ๋งค์ฐ ๋์ ๋ฐ์ดํฐ ์ ์ก์จ์ด ์๊ตฌ๋๋ ๊ฒฝ์ฐ DMA ๋ฒํผ๋ฅผ Half-Transfer Interrupt(HT)์ Transfer Complete Interrupt(TC)๋ฅผ ํ์ฉํด 2๊ฐ๋ก ๋ถํ ํ์ฌ DMA๊ฐ Block A๋ฅผ ์ฑ์ฐ๋ ๋์ CPU๋ Block B๋ฅผ ์์ ํ๊ฒ ์ฒ๋ฆฌํ๋๋ก ์ค๊ณํฉ๋๋ค.
- CRC16 ๋น ๋ฅธ ๊ฒ์ฆ: `Process_Modbus_Frame()` ๋ด๋ถ ์ฒซ ๋จ๊ณ์์ ํด๋น ๋ ธ๋์ ID(Address) ์ผ์น ์ฌ๋ถ์ **Modbus CRC-16(Modbus RTU Spec)**์ ๋น ๋ฅด๊ฒ ์ ๊ฒ์ฆํ์ฌ, ์ ํจํ์ง ์์ ๋ ธ์ด์ฆ ํจํท์ ์ฆ์ ํ๊ธฐ(`Discard`)ํ๊ณ ๋ฒํผ ํฌ์ธํฐ๋ง ๋๊ธฐํํฉ๋๋ค.
4. ๊ฒ์ฆ ๋ฐ ๋๋ฒ๊น ์ฒดํฌ๋ฆฌ์คํธ
RS-485 Modbus RTU ๋ค์ค ์ฌ๋ ์ด๋ธ ์์คํ ๊ตฌ์ถ ํ ํต์ ๋ถ์์ ์์๊ฐ ์์ฌํ ๊ฒฝ์ฐ, ์๋ ์ฒดํฌ๋ฆฌ์คํธ์ ๋ฐ๋ผ ๋จ๊ณ๋ณ๋ก ๊ฒ์ฆ์ ์งํํฉ๋๋ค.
| ๊ฒ์ฆ ํญ๋ชฉ | ์ธก์ ๋๊ตฌ / ๋ฐฉ๋ฒ | ์ ์ ๊ธฐ์ค ๋ฐ ์กฐ์น ์ฌํญ |
|---|---|---|
| ๊ณตํต ๋ชจ๋ ์ ์ | DMM / ๋ฉํฐ๋ฏธํฐ (DC/AC V) | ๋ง์คํฐ GND์ ๊ฐ ์ฌ๋ ์ด๋ธ ISO_GND ๊ฐ ์ ์์ฐจ๊ฐ < 1V ์ด๋ด์ด์ด์ผ ํจ (์ ์ฐ ๋ฏธ์ ์ฉ ์ ํธ๋์๋ฒ ๊ต์ฒด ํ์) |
| ์ข ๋จ ์ ํญ (Termination) | ์ค์ค๋ก์ค์ฝํ (Oscilloscope) | ๋ฒ์ค ์ ๋๋จ ๋ ธ๋์๋ง 120ฮฉ ์ ์. ์ ํธ์ ์ ํธ ๋ฐ์ฌ(Reflection) ๋ฐ ๋ง์(Ringing) ํ์ ์ ๋ฌด ํ์ธ |
| DE Timing ์ ํธ | 2์ฑ๋ ์ค์ค๋ก์ค์ฝํ (TXD & DE) | TXD์ Stop bit ์ ์ก ์๋ฃ ์์ ๊ณผ DE ํ์ด High->Low๋ก ๋จ์ด์ง๋ ์์ ๊ฐ ์ง์ฐ์ด 1๋นํธ ์๊ฐ ์ด๋ด์ฌ์ผ ํจ |
| DMA Overflow | MCU Logic Analyzer / UART Log | UART Error Register์ `ORE`(Overrun Error) ๋ฐ `FE`(Framing Error) ํ๋๊ทธ ๋ฐ์ ํ์๊ฐ 0์ด์ด์ผ ํจ |
๊ฒฐ๋ก : ๊ฒฐํจ ์๋ RS-485 ๋คํธ์ํฌ๋ฅผ ์ํ ํ๋์จ์ดยท์ํํธ์จ์ด ํตํฉ ์ ์ด
RS-485 Modbus RTU ๋ค์ค ์ฌ๋ ์ด๋ธ ํต์ ์ ํ๋ ์ ์์ค ํธ๋ฌ๋ธ์ํ ์ ์ํํธ์จ์ด ์์ธ ์ฒ๋ฆฌ๋ง์ผ๋ก๋ ํด๊ฒฐํ ์ ์์ต๋๋ค. ๊ฐ๋ฐ๋ ์ ์ฐ์ ํตํ ์ ์ง ๋ฃจํ ๋ ธ์ด์ฆ ์ ๊ฑฐ, ์ ํํ TC ํ๋๊ทธ ๋ฐ ์๋ ๋ฐฉํฅ ์ ์ด๋ฅผ ํตํ DE ๋ฒ์ค ์ ํ ์ง์ฐ ์ต์ํ๋ผ๋ ํ๋์จ์ด์ ๊ธฐ๋ฐ์ด ๋จผ์ ํ๋ฆฝ๋์ด์ผ ํฉ๋๋ค.
์ด ์์ STM32์ IDLE Line Detection๊ณผ Circular DMA ๋ง ๋ฒํผ ๊ธฐ๋ฐ ๋ฌด์์ ์์ ๊ตฌ์กฐ๋ฅผ ๊ฒฐํฉํจ์ผ๋ก์จ, CPU ๊ฐ์ ์ ์ต์ํํ๋ฉด์๋ ์ด๋ค ๊ฐ๋ณ ๊ธธ์ด ํจํท์ด๋ ๋ ธ์ด์ฆ ํ๊ฒฝ์์๋ ๋จ 1๋ฐ์ดํธ์ ์์ค ์์ด ์์ ์ ์ผ๋ก ๋์ํ๋ ๊ณ ์ฑ๋ฅ ์ฐ์ ์ฉ ํต์ ์์คํ ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค.