串口通信:从 UART 入门到 GNSS 设备调试

1. 先分清三个层次

日常所说的"串口"经常把三个不同层次混在一起:

text 复制代码
应用协议:NMEA、AT 指令、Modbus-RTU、厂商二进制协议
UART 帧:波特率、数据位、校验位、停止位
物理接口:TTL/CMOS、RS-232、RS-422、RS-485

三者分别解决不同问题:

  • 应用协议:一串字节分别表示什么,怎样判断一条消息结束;
  • UART:一个字符怎样转换成起始位、数据位、校验位和停止位;
  • 物理接口:逻辑 0 和逻辑 1 在线路上使用什么电压和接线方式传输。

UART、RS-232、RS-485 和 NMEA 不是同一层概念,不能相互替代。
#mermaid-svg-eTUx3jg1rTvP7YAl{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-eTUx3jg1rTvP7YAl .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-eTUx3jg1rTvP7YAl .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-eTUx3jg1rTvP7YAl .error-icon{fill:#552222;}#mermaid-svg-eTUx3jg1rTvP7YAl .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-eTUx3jg1rTvP7YAl .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-eTUx3jg1rTvP7YAl .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-eTUx3jg1rTvP7YAl .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-eTUx3jg1rTvP7YAl .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-eTUx3jg1rTvP7YAl .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-eTUx3jg1rTvP7YAl .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-eTUx3jg1rTvP7YAl .marker{fill:#333333;stroke:#333333;}#mermaid-svg-eTUx3jg1rTvP7YAl .marker.cross{stroke:#333333;}#mermaid-svg-eTUx3jg1rTvP7YAl svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-eTUx3jg1rTvP7YAl p{margin:0;}#mermaid-svg-eTUx3jg1rTvP7YAl .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-eTUx3jg1rTvP7YAl .cluster-label text{fill:#333;}#mermaid-svg-eTUx3jg1rTvP7YAl .cluster-label span{color:#333;}#mermaid-svg-eTUx3jg1rTvP7YAl .cluster-label span p{background-color:transparent;}#mermaid-svg-eTUx3jg1rTvP7YAl .label text,#mermaid-svg-eTUx3jg1rTvP7YAl span{fill:#333;color:#333;}#mermaid-svg-eTUx3jg1rTvP7YAl .node rect,#mermaid-svg-eTUx3jg1rTvP7YAl .node circle,#mermaid-svg-eTUx3jg1rTvP7YAl .node ellipse,#mermaid-svg-eTUx3jg1rTvP7YAl .node polygon,#mermaid-svg-eTUx3jg1rTvP7YAl .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-eTUx3jg1rTvP7YAl .rough-node .label text,#mermaid-svg-eTUx3jg1rTvP7YAl .node .label text,#mermaid-svg-eTUx3jg1rTvP7YAl .image-shape .label,#mermaid-svg-eTUx3jg1rTvP7YAl .icon-shape .label{text-anchor:middle;}#mermaid-svg-eTUx3jg1rTvP7YAl .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-eTUx3jg1rTvP7YAl .rough-node .label,#mermaid-svg-eTUx3jg1rTvP7YAl .node .label,#mermaid-svg-eTUx3jg1rTvP7YAl .image-shape .label,#mermaid-svg-eTUx3jg1rTvP7YAl .icon-shape .label{text-align:center;}#mermaid-svg-eTUx3jg1rTvP7YAl .node.clickable{cursor:pointer;}#mermaid-svg-eTUx3jg1rTvP7YAl .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-eTUx3jg1rTvP7YAl .arrowheadPath{fill:#333333;}#mermaid-svg-eTUx3jg1rTvP7YAl .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-eTUx3jg1rTvP7YAl .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-eTUx3jg1rTvP7YAl .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-eTUx3jg1rTvP7YAl .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-eTUx3jg1rTvP7YAl .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-eTUx3jg1rTvP7YAl .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-eTUx3jg1rTvP7YAl .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-eTUx3jg1rTvP7YAl .cluster text{fill:#333;}#mermaid-svg-eTUx3jg1rTvP7YAl .cluster span{color:#333;}#mermaid-svg-eTUx3jg1rTvP7YAl div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-eTUx3jg1rTvP7YAl .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-eTUx3jg1rTvP7YAl rect.text{fill:none;stroke-width:0;}#mermaid-svg-eTUx3jg1rTvP7YAl .icon-shape,#mermaid-svg-eTUx3jg1rTvP7YAl .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-eTUx3jg1rTvP7YAl .icon-shape p,#mermaid-svg-eTUx3jg1rTvP7YAl .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-eTUx3jg1rTvP7YAl .icon-shape .label rect,#mermaid-svg-eTUx3jg1rTvP7YAl .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-eTUx3jg1rTvP7YAl .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-eTUx3jg1rTvP7YAl .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-eTUx3jg1rTvP7YAl :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 应用协议

NMEA、AT、Modbus、自定义协议
UART 控制器

字符与比特帧转换
电平转换或差分收发器
物理线路

TTL/CMOS、RS-232、RS-422、RS-485


2. 什么是串行通信和 UART

2.1 串行通信

串行通信是指数据按照时间顺序,一个比特或一个符号接一个符号地传输。

它与并行通信的主要区别是:

  • 并行通信同时使用多条数据线传输多个比特;
  • 串行通信使用较少线路连续传输,布线更简单,也更容易用于较长距离。

串行通信是一个大类,UART、SPI、I²C、USB 和 CAN 都采用串行传输。嵌入式开发中口头所说的"串口",通常特指 UART 异步串口

2.2 UART

UART 是 Universal Asynchronous Receiver/Transmitter,中文为"通用异步收发器"。

它负责:

  • 把 CPU 提供的字符或字节转换成连续比特;
  • 发送起始位、数据位、可选校验位和停止位;
  • 从接收线上恢复一个字符;
  • 检测帧错误、校验错误和接收溢出等异常。

UART 规定的是传输时序和帧格式,不规定线路必须使用 3.3 V、RS-232 或 RS-485。


3. UART 为什么叫"异步"

UART 通常没有单独的时钟线。发送端和接收端各自使用本地时钟,并提前设置相同的波特率。

接收端的基本工作过程是:

  1. 等待线路处于空闲状态;
  2. 检测到起始位;
  3. 按约定波特率计时;
  4. 在每个数据位的中间附近采样;
  5. 检查校验位和停止位;
  6. 将数据位组合成一个字符。

#mermaid-svg-bOvY0LVPtClukNMj{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-bOvY0LVPtClukNMj .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-bOvY0LVPtClukNMj .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-bOvY0LVPtClukNMj .error-icon{fill:#552222;}#mermaid-svg-bOvY0LVPtClukNMj .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-bOvY0LVPtClukNMj .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-bOvY0LVPtClukNMj .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-bOvY0LVPtClukNMj .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-bOvY0LVPtClukNMj .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-bOvY0LVPtClukNMj .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-bOvY0LVPtClukNMj .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-bOvY0LVPtClukNMj .marker{fill:#333333;stroke:#333333;}#mermaid-svg-bOvY0LVPtClukNMj .marker.cross{stroke:#333333;}#mermaid-svg-bOvY0LVPtClukNMj svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-bOvY0LVPtClukNMj p{margin:0;}#mermaid-svg-bOvY0LVPtClukNMj .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-bOvY0LVPtClukNMj .cluster-label text{fill:#333;}#mermaid-svg-bOvY0LVPtClukNMj .cluster-label span{color:#333;}#mermaid-svg-bOvY0LVPtClukNMj .cluster-label span p{background-color:transparent;}#mermaid-svg-bOvY0LVPtClukNMj .label text,#mermaid-svg-bOvY0LVPtClukNMj span{fill:#333;color:#333;}#mermaid-svg-bOvY0LVPtClukNMj .node rect,#mermaid-svg-bOvY0LVPtClukNMj .node circle,#mermaid-svg-bOvY0LVPtClukNMj .node ellipse,#mermaid-svg-bOvY0LVPtClukNMj .node polygon,#mermaid-svg-bOvY0LVPtClukNMj .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-bOvY0LVPtClukNMj .rough-node .label text,#mermaid-svg-bOvY0LVPtClukNMj .node .label text,#mermaid-svg-bOvY0LVPtClukNMj .image-shape .label,#mermaid-svg-bOvY0LVPtClukNMj .icon-shape .label{text-anchor:middle;}#mermaid-svg-bOvY0LVPtClukNMj .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-bOvY0LVPtClukNMj .rough-node .label,#mermaid-svg-bOvY0LVPtClukNMj .node .label,#mermaid-svg-bOvY0LVPtClukNMj .image-shape .label,#mermaid-svg-bOvY0LVPtClukNMj .icon-shape .label{text-align:center;}#mermaid-svg-bOvY0LVPtClukNMj .node.clickable{cursor:pointer;}#mermaid-svg-bOvY0LVPtClukNMj .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-bOvY0LVPtClukNMj .arrowheadPath{fill:#333333;}#mermaid-svg-bOvY0LVPtClukNMj .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-bOvY0LVPtClukNMj .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-bOvY0LVPtClukNMj .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-bOvY0LVPtClukNMj .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-bOvY0LVPtClukNMj .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-bOvY0LVPtClukNMj .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-bOvY0LVPtClukNMj .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-bOvY0LVPtClukNMj .cluster text{fill:#333;}#mermaid-svg-bOvY0LVPtClukNMj .cluster span{color:#333;}#mermaid-svg-bOvY0LVPtClukNMj div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-bOvY0LVPtClukNMj .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-bOvY0LVPtClukNMj rect.text{fill:none;stroke-width:0;}#mermaid-svg-bOvY0LVPtClukNMj .icon-shape,#mermaid-svg-bOvY0LVPtClukNMj .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-bOvY0LVPtClukNMj .icon-shape p,#mermaid-svg-bOvY0LVPtClukNMj .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-bOvY0LVPtClukNMj .icon-shape .label rect,#mermaid-svg-bOvY0LVPtClukNMj .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-bOvY0LVPtClukNMj .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-bOvY0LVPtClukNMj .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-bOvY0LVPtClukNMj :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 线路空闲
检测起始位
按波特率计时
采样数据位
检查校验位和停止位
输出一个字符

常见非反相 UART 的逻辑状态为:

  • 空闲状态:逻辑 1;
  • 起始位:逻辑 0;
  • 停止位:逻辑 1。

接收器常采用多倍于波特率的时钟进行过采样,以提高起始位检测和采样的可靠性。具体过采样倍数由芯片实现决定,常见值包括 8 倍或 16 倍。


4. UART 帧是什么样的

一个 UART 字符通常按以下顺序发送:

text 复制代码
空闲 → 起始位 → 数据位 → 可选校验位 → 停止位 → 空闲

以最常见的 8N1 为例:

text 复制代码
1 个起始位 + 8 个数据位 + 无校验位 + 1 个停止位

多数 UART 先发送最低有效位,即 LSB first
#mermaid-svg-x8dAHDdDybuBWBr1{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-x8dAHDdDybuBWBr1 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-x8dAHDdDybuBWBr1 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-x8dAHDdDybuBWBr1 .error-icon{fill:#552222;}#mermaid-svg-x8dAHDdDybuBWBr1 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-x8dAHDdDybuBWBr1 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-x8dAHDdDybuBWBr1 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-x8dAHDdDybuBWBr1 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-x8dAHDdDybuBWBr1 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-x8dAHDdDybuBWBr1 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-x8dAHDdDybuBWBr1 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-x8dAHDdDybuBWBr1 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-x8dAHDdDybuBWBr1 .marker.cross{stroke:#333333;}#mermaid-svg-x8dAHDdDybuBWBr1 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-x8dAHDdDybuBWBr1 p{margin:0;}#mermaid-svg-x8dAHDdDybuBWBr1 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-x8dAHDdDybuBWBr1 .cluster-label text{fill:#333;}#mermaid-svg-x8dAHDdDybuBWBr1 .cluster-label span{color:#333;}#mermaid-svg-x8dAHDdDybuBWBr1 .cluster-label span p{background-color:transparent;}#mermaid-svg-x8dAHDdDybuBWBr1 .label text,#mermaid-svg-x8dAHDdDybuBWBr1 span{fill:#333;color:#333;}#mermaid-svg-x8dAHDdDybuBWBr1 .node rect,#mermaid-svg-x8dAHDdDybuBWBr1 .node circle,#mermaid-svg-x8dAHDdDybuBWBr1 .node ellipse,#mermaid-svg-x8dAHDdDybuBWBr1 .node polygon,#mermaid-svg-x8dAHDdDybuBWBr1 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-x8dAHDdDybuBWBr1 .rough-node .label text,#mermaid-svg-x8dAHDdDybuBWBr1 .node .label text,#mermaid-svg-x8dAHDdDybuBWBr1 .image-shape .label,#mermaid-svg-x8dAHDdDybuBWBr1 .icon-shape .label{text-anchor:middle;}#mermaid-svg-x8dAHDdDybuBWBr1 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-x8dAHDdDybuBWBr1 .rough-node .label,#mermaid-svg-x8dAHDdDybuBWBr1 .node .label,#mermaid-svg-x8dAHDdDybuBWBr1 .image-shape .label,#mermaid-svg-x8dAHDdDybuBWBr1 .icon-shape .label{text-align:center;}#mermaid-svg-x8dAHDdDybuBWBr1 .node.clickable{cursor:pointer;}#mermaid-svg-x8dAHDdDybuBWBr1 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-x8dAHDdDybuBWBr1 .arrowheadPath{fill:#333333;}#mermaid-svg-x8dAHDdDybuBWBr1 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-x8dAHDdDybuBWBr1 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-x8dAHDdDybuBWBr1 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-x8dAHDdDybuBWBr1 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-x8dAHDdDybuBWBr1 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-x8dAHDdDybuBWBr1 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-x8dAHDdDybuBWBr1 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-x8dAHDdDybuBWBr1 .cluster text{fill:#333;}#mermaid-svg-x8dAHDdDybuBWBr1 .cluster span{color:#333;}#mermaid-svg-x8dAHDdDybuBWBr1 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-x8dAHDdDybuBWBr1 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-x8dAHDdDybuBWBr1 rect.text{fill:none;stroke-width:0;}#mermaid-svg-x8dAHDdDybuBWBr1 .icon-shape,#mermaid-svg-x8dAHDdDybuBWBr1 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-x8dAHDdDybuBWBr1 .icon-shape p,#mermaid-svg-x8dAHDdDybuBWBr1 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-x8dAHDdDybuBWBr1 .icon-shape .label rect,#mermaid-svg-x8dAHDdDybuBWBr1 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-x8dAHDdDybuBWBr1 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-x8dAHDdDybuBWBr1 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-x8dAHDdDybuBWBr1 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 空闲

1
起始位

0
D0
D1
...
D7
可选校验位
停止位

1

4.1 起始位

起始位通知接收端:

一个新字符开始了。

接收端利用空闲态到起始位的跳变建立当前帧的采样时刻。

4.2 数据位

数据位承载实际内容,常见为 7 位或 8 位。现代嵌入式设备大多使用 8 位。

4.3 校验位

常见设置为:

  • N:无校验;
  • E:偶校验;
  • O:奇校验。

奇偶校验只能发现一部分比特错误,不能代替 CRC 等更可靠的帧校验。

4.4 停止位

停止位让线路回到空闲状态,用于标记帧结束并提供一定时序余量。

常见为 1 位或 2 位。它的主要作用不是"让 CPU 休息",而是帮助接收端识别帧边界和重新同步。


5. 串口参数与有效速率

两个设备必须使用兼容的参数。

参数 常见值 作用
波特率 9600、38400、115200 等 决定线路符号传输速度
数据位 7、8 每帧承载的数据位数
校验位 N、E、O 进行简单错误检测
停止位 1、2 标记一帧结束
流控 无、RTS/CTS、XON/XOFF 接收端忙时控制发送端暂停

115200 8N1 表示:

text 复制代码
波特率 115200
8 个数据位
无校验
1 个停止位

5.1 波特率与比特率

波特率表示每秒传输多少个符号。

普通 UART 每个符号表示一个二进制位,所以波特率和线路比特率通常数值相等。但在一般通信理论中,两者不是永远相同。

5.2 一帧占多少时间

每个 UART 字符占用的总比特时间为:

Nframe=1+Ndata+Nparity+NstopN_{\text{frame}} = 1+N_{\text{data}}+N_{\text{parity}}+N_{\text{stop}}Nframe=1+Ndata+Nparity+Nstop

其中:

  • NframeN_{\text{frame}}Nframe:一个字符占用的总比特时间数;
  • 1:一个起始位;
  • NdataN_{\text{data}}Ndata:数据位数;
  • NparityN_{\text{parity}}Nparity:校验位数,无校验时为 0;
  • NstopN_{\text{stop}}Nstop:停止位数。

一个字符的理论传输时间为:

Tchar=NframeBT_{\text{char}} = \frac{N_{\text{frame}}}{B}Tchar=BNframe

其中:

  • TcharT_{\text{char}}Tchar:一个字符的传输时间,单位为 s;
  • BBB:波特率,单位为 Baud。

8N1

Nframe=1+8+0+1=10N_{\text{frame}}=1+8+0+1=10Nframe=1+8+0+1=10

115200 Baud 时,理论最大字符速率约为:

11520010=11520 Byte/s\frac{115200}{10}=11520\ \text{Byte/s}10115200=11520 Byte/s

这个结果还没有扣除 NMEA、RTCM 或自定义协议中的帧头、长度、校验等开销。

5.3 流控

  • 无流控:实现简单,但接收程序不及时可能丢数据;
  • RTS/CTS:使用额外硬件引脚控制暂停和继续;
  • XON/XOFF:在字节流中使用特殊控制字符。

对于任意二进制数据,使用 XON/XOFF 时必须确认协议是否进行了转义,否则有效数据可能被误认为流控字符。


6. 串口是字节流,消息边界要自己定义

从不同层次看:

  • 物理线上传输的是比特;
  • UART 控制器通常以字符或字节收发;
  • 程序看到的是连续字节流;
  • 上层协议负责把字节流恢复成完整消息。

串口驱动通常不保留应用程序的消息边界。一次 read() 可能得到:

  • 半帧;
  • 一帧;
  • 多帧;
  • 一帧末尾加下一帧开头。

因此:

不能把一次 read() 等同于一条完整消息。

6.1 常见分帧方式

文本结束符

例如 NMEA 或 AT 指令常用:

text 复制代码
\r\n

表示一行结束。

固定长度

每条消息始终包含固定字节数,解析简单,但扩展性较弱。

帧头、长度和校验

典型二进制结构:

text 复制代码
帧头 | 消息类型 | 长度 | 数据区 | CRC

这是 GNSS 厂商二进制协议和许多自定义协议的常见做法。

6.2 推荐的接收流程

#mermaid-svg-YodqY08KaZAUmaor{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-YodqY08KaZAUmaor .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-YodqY08KaZAUmaor .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-YodqY08KaZAUmaor .error-icon{fill:#552222;}#mermaid-svg-YodqY08KaZAUmaor .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-YodqY08KaZAUmaor .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-YodqY08KaZAUmaor .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-YodqY08KaZAUmaor .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-YodqY08KaZAUmaor .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-YodqY08KaZAUmaor .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-YodqY08KaZAUmaor .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-YodqY08KaZAUmaor .marker{fill:#333333;stroke:#333333;}#mermaid-svg-YodqY08KaZAUmaor .marker.cross{stroke:#333333;}#mermaid-svg-YodqY08KaZAUmaor svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-YodqY08KaZAUmaor p{margin:0;}#mermaid-svg-YodqY08KaZAUmaor .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-YodqY08KaZAUmaor .cluster-label text{fill:#333;}#mermaid-svg-YodqY08KaZAUmaor .cluster-label span{color:#333;}#mermaid-svg-YodqY08KaZAUmaor .cluster-label span p{background-color:transparent;}#mermaid-svg-YodqY08KaZAUmaor .label text,#mermaid-svg-YodqY08KaZAUmaor span{fill:#333;color:#333;}#mermaid-svg-YodqY08KaZAUmaor .node rect,#mermaid-svg-YodqY08KaZAUmaor .node circle,#mermaid-svg-YodqY08KaZAUmaor .node ellipse,#mermaid-svg-YodqY08KaZAUmaor .node polygon,#mermaid-svg-YodqY08KaZAUmaor .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-YodqY08KaZAUmaor .rough-node .label text,#mermaid-svg-YodqY08KaZAUmaor .node .label text,#mermaid-svg-YodqY08KaZAUmaor .image-shape .label,#mermaid-svg-YodqY08KaZAUmaor .icon-shape .label{text-anchor:middle;}#mermaid-svg-YodqY08KaZAUmaor .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-YodqY08KaZAUmaor .rough-node .label,#mermaid-svg-YodqY08KaZAUmaor .node .label,#mermaid-svg-YodqY08KaZAUmaor .image-shape .label,#mermaid-svg-YodqY08KaZAUmaor .icon-shape .label{text-align:center;}#mermaid-svg-YodqY08KaZAUmaor .node.clickable{cursor:pointer;}#mermaid-svg-YodqY08KaZAUmaor .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-YodqY08KaZAUmaor .arrowheadPath{fill:#333333;}#mermaid-svg-YodqY08KaZAUmaor .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-YodqY08KaZAUmaor .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-YodqY08KaZAUmaor .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YodqY08KaZAUmaor .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-YodqY08KaZAUmaor .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YodqY08KaZAUmaor .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-YodqY08KaZAUmaor .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-YodqY08KaZAUmaor .cluster text{fill:#333;}#mermaid-svg-YodqY08KaZAUmaor .cluster span{color:#333;}#mermaid-svg-YodqY08KaZAUmaor div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-YodqY08KaZAUmaor .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-YodqY08KaZAUmaor rect.text{fill:none;stroke-width:0;}#mermaid-svg-YodqY08KaZAUmaor .icon-shape,#mermaid-svg-YodqY08KaZAUmaor .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YodqY08KaZAUmaor .icon-shape p,#mermaid-svg-YodqY08KaZAUmaor .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-YodqY08KaZAUmaor .icon-shape .label rect,#mermaid-svg-YodqY08KaZAUmaor .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YodqY08KaZAUmaor .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-YodqY08KaZAUmaor .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-YodqY08KaZAUmaor :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 否



失败
成功
读取任意数量字节
追加到接收缓冲区
找到合法帧头?
丢弃无效前导字节
完整帧是否到齐?
检查长度和校验
移动位置并重新同步
输出完整帧

工程实现应限制最大帧长,并能在丢字节或校验失败后重新同步。


7. UART 与 TTL、RS-232、RS-422、RS-485

7.1 TTL/CMOS UART

常见 MCU 和 GNSS 模块直接提供 1.8 V、3.3 V 或 5 V 单端 UART。

特点:

  • 适合板内或短距离连接;
  • 线路简单;
  • 抗干扰和远距离能力较弱。

"TTL 串口"是常用口语。许多 3.3 V MCU 实际使用的是 CMOS 电平。

7.2 RS-232

RS-232 使用单端电压,线路逻辑极性与普通 UART 引脚相反,需要专用收发器进行转换。

它通常用于:

  • 传统电脑串口;
  • 仪器仪表;
  • 工控设备;
  • 点对点通信。

RS-232 不能直接连接 MCU 的 UART 引脚。

7.3 RS-422

RS-422 使用差分信号,典型用途包括:

  • 长距离点对点通信;
  • 一发多收;
  • 使用两对差分线的全双工通信。

7.4 RS-485

RS-485 也使用差分信号,适合多节点总线。

常见两线 RS-485 为半双工:

  • 多个节点共享一对 A/B 线;
  • 同一时刻通常只允许一个节点发送;
  • 需要控制发送使能;
  • 上层协议必须解决地址、应答和总线访问顺序。
接口 信号形式 常见拓扑 典型场景
TTL/CMOS UART 单端 短距离点对点 MCU、GNSS 模块、调试口
RS-232 单端 点对点 传统仪器、工控设备
RS-422 差分 点对点或一发多收 长距离、全双工
RS-485 差分 多点总线 工业现场、多设备组网

A/B 命名在不同厂商资料中可能不一致,接线时应以设备手册为准。


8. RS-485 需要掌握的基础布线原则

推荐使用一条主干总线,节点通过较短分支接入:

text 复制代码
终端电阻                              终端电阻
   |                                     |
---+---------+---------+---------+-------+---
             |         |         |
            节点1     节点2     节点3

基础原则:

  • 终端电阻放在总线物理两端;
  • 终端阻值应与线缆特性阻抗匹配,工程中常见约 120 Ω;
  • 分支线尽量短;
  • 避免长距离星形布线;
  • 总线空闲状态不稳定时,应设置合适的偏置;
  • 远距离或地电位差较大时,要考虑隔离和浪涌保护。

两线半双工 RS-485 的发送方向切换也很重要:

  1. 使能发送器;
  2. 写入数据;
  3. 等待 UART 最后一个停止位真正发完;
  4. 关闭发送器并释放总线。

仅等待软件发送缓冲区为空并不一定表示线路已经发送完成。


9. 电脑怎样连接板卡

9.1 先确认物理接口

连接前先确认板卡使用的是:

  • 1.8 V、3.3 V 或 5 V UART;
  • RS-232;
  • RS-422;
  • RS-485。

不能只根据"串口"名称或连接器外形判断。DB9 不一定永远是 RS-232,排针也不一定永远是 3.3 V UART。

9.2 USB-UART 接线

TTL/CMOS UART 的常见接线为:

text 复制代码
USB-UART TX  → 板卡 RX
USB-UART RX  ← 板卡 TX
USB-UART GND ─ 板卡 GND

注意:

  • TX 和 RX 交叉连接;
  • 双方需要共同参考地;
  • 电压必须兼容;
  • 通信通常只需要 TX、RX、GND,不要在不明确用途时随意连接 VCC。

若对方是 RS-232、RS-422 或 RS-485,应使用对应的 USB 转换器,不能直接使用 USB-UART 模块。

9.3 端口名称

Windows 中常见为:

text 复制代码
COM3、COM4......

Linux 中常见为:

text 复制代码
/dev/ttyUSB0
/dev/ttyACM0

打不开串口时,应检查端口权限、驱动、占用情况和串口参数。


10. GNSS 设备中的串口数据

10.1 NMEA 文本

NMEA 语句通常为 ASCII 文本,例如:

text 复制代码
$GNGGA,...*CS\r\n

其中:

  • $:语句起始;
  • GNGGA:消息类型;
  • *CS:校验字段;
  • \r\n:语句结束。

NMEA 便于人工查看,适合输出位置、时间、卫星数量和定位状态。

10.2 RTCM 与厂商二进制协议

GNSS 接收机还可能通过串口输出:

  • RTCM 改正数据;
  • 原始观测数据;
  • 导航电文;
  • 厂商私有二进制消息;
  • 组合导航或 IMU 数据。

这类协议通常使用:

text 复制代码
帧头 + 消息类型 + 长度 + 负载 + 校验

解析程序必须处理半帧、多帧、错误长度、校验失败和重新同步。

10.3 波特率是否够用

115200 8N1 的理论上限约为 11520 Byte/s。

若同时输出:

  • 多系统多频原始观测;
  • 高频定位结果;
  • RTCM 数据;
  • 多种调试信息;

应估算总数据量,并预留突发和协议开销。带宽不足时可以:

  • 提高波特率;
  • 降低输出频率;
  • 关闭不需要的消息;
  • 改用 USB 或以太网。

NMEA 0183 船舶接口虽然也传输 NMEA 文本,但其物理电气接口通常是差分形式,不能直接等同于 GNSS 模块的 TTL/CMOS UART。


11. 常见错误与排查顺序

11.1 常见 UART 错误

  • 帧错误:停止位位置没有检测到正确电平;
  • 校验错误:奇偶校验结果不匹配;
  • 接收溢出:软件尚未读取旧数据,新数据已经到达;
  • Break:线路保持起始位电平超过一个正常字符时间。

11.2 排查顺序

第一步:接口和电平
  • 是 UART、RS-232、RS-422 还是 RS-485?
  • 电压等级是否匹配?
  • 是否需要电平转换或隔离?
第二步:接线
  • TX 是否连接 RX?
  • 是否共地?
  • RS-485 A/B 是否接反?
  • 是否有多个节点同时发送?
第三步:参数
  • 波特率;
  • 数据位;
  • 校验位;
  • 停止位;
  • 流控。
第四步:软件
  • 端口是否被占用?
  • 接收线程是否及时读取?
  • 缓冲区是否溢出?
  • 是否错误地把一次 read() 当作完整帧?
  • 是否把二进制数据当作文本字符串处理?
第五步:协议
  • 帧头和长度是否正确?
  • 字节序是否一致?
  • CRC 或校验和算法是否一致?
  • 文本结束符是 \r\n\n 还是 \r

必要时使用:

  • 回环测试;
  • 逻辑分析仪;
  • 示波器;
  • 原始十六进制日志。

12. 网络串口是什么

串口本身不依赖网络。串口服务器只是把串口字节流封装成 TCP 或 UDP 数据:
#mermaid-svg-kQRnAezmkOjofcQr{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-kQRnAezmkOjofcQr .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-kQRnAezmkOjofcQr .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-kQRnAezmkOjofcQr .error-icon{fill:#552222;}#mermaid-svg-kQRnAezmkOjofcQr .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-kQRnAezmkOjofcQr .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-kQRnAezmkOjofcQr .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-kQRnAezmkOjofcQr .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-kQRnAezmkOjofcQr .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-kQRnAezmkOjofcQr .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-kQRnAezmkOjofcQr .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-kQRnAezmkOjofcQr .marker{fill:#333333;stroke:#333333;}#mermaid-svg-kQRnAezmkOjofcQr .marker.cross{stroke:#333333;}#mermaid-svg-kQRnAezmkOjofcQr svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-kQRnAezmkOjofcQr p{margin:0;}#mermaid-svg-kQRnAezmkOjofcQr .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-kQRnAezmkOjofcQr .cluster-label text{fill:#333;}#mermaid-svg-kQRnAezmkOjofcQr .cluster-label span{color:#333;}#mermaid-svg-kQRnAezmkOjofcQr .cluster-label span p{background-color:transparent;}#mermaid-svg-kQRnAezmkOjofcQr .label text,#mermaid-svg-kQRnAezmkOjofcQr span{fill:#333;color:#333;}#mermaid-svg-kQRnAezmkOjofcQr .node rect,#mermaid-svg-kQRnAezmkOjofcQr .node circle,#mermaid-svg-kQRnAezmkOjofcQr .node ellipse,#mermaid-svg-kQRnAezmkOjofcQr .node polygon,#mermaid-svg-kQRnAezmkOjofcQr .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-kQRnAezmkOjofcQr .rough-node .label text,#mermaid-svg-kQRnAezmkOjofcQr .node .label text,#mermaid-svg-kQRnAezmkOjofcQr .image-shape .label,#mermaid-svg-kQRnAezmkOjofcQr .icon-shape .label{text-anchor:middle;}#mermaid-svg-kQRnAezmkOjofcQr .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-kQRnAezmkOjofcQr .rough-node .label,#mermaid-svg-kQRnAezmkOjofcQr .node .label,#mermaid-svg-kQRnAezmkOjofcQr .image-shape .label,#mermaid-svg-kQRnAezmkOjofcQr .icon-shape .label{text-align:center;}#mermaid-svg-kQRnAezmkOjofcQr .node.clickable{cursor:pointer;}#mermaid-svg-kQRnAezmkOjofcQr .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-kQRnAezmkOjofcQr .arrowheadPath{fill:#333333;}#mermaid-svg-kQRnAezmkOjofcQr .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-kQRnAezmkOjofcQr .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-kQRnAezmkOjofcQr .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kQRnAezmkOjofcQr .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-kQRnAezmkOjofcQr .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kQRnAezmkOjofcQr .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-kQRnAezmkOjofcQr .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-kQRnAezmkOjofcQr .cluster text{fill:#333;}#mermaid-svg-kQRnAezmkOjofcQr .cluster span{color:#333;}#mermaid-svg-kQRnAezmkOjofcQr div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-kQRnAezmkOjofcQr .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-kQRnAezmkOjofcQr rect.text{fill:none;stroke-width:0;}#mermaid-svg-kQRnAezmkOjofcQr .icon-shape,#mermaid-svg-kQRnAezmkOjofcQr .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kQRnAezmkOjofcQr .icon-shape p,#mermaid-svg-kQRnAezmkOjofcQr .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-kQRnAezmkOjofcQr .icon-shape .label rect,#mermaid-svg-kQRnAezmkOjofcQr .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kQRnAezmkOjofcQr .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-kQRnAezmkOjofcQr .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-kQRnAezmkOjofcQr :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} UART/RS-232/RS-485
TCP 或 UDP
串口设备
串口服务器
IP 网络
远程程序

  • TCP 保证顺序和可靠传输,但仍然是字节流,不提供应用消息边界;
  • UDP 开销小,但可能丢包、重复或乱序。

因此:

本地串口通信不依赖网络;通过串口服务器远程通信时,整体链路才依赖网络质量。


13. 初学者应掌握的核心结论

  1. 串行通信是大类,嵌入式"串口"通常指 UART。
  2. UART 没有独立时钟线,依靠起始位和约定波特率同步。
  3. 8N1 传输 1 Byte 通常需要 10 个比特时间。
  4. 程序看到的是连续字节流,消息边界必须由协议定义。
  5. UART、TTL/CMOS、RS-232、RS-422、RS-485 分属不同层次。
  6. TTL/CMOS UART 接线通常需要 TX、RX 和 GND,且电压必须兼容。
  7. 两线 RS-485 通常为半双工,需要正确的拓扑、终端匹配和方向控制。
  8. GNSS 的 NMEA、RTCM 和厂商二进制协议都需要正确分帧。
  9. 排查问题时,依次检查接口、电平、接线、参数、软件缓冲和协议。

一句话概括:

先保证电气接口安全兼容,再保证 UART 参数一致,最后从连续字节流中正确恢复完整协议帧。

相关推荐
智联物联2 个月前
多台串口设备需要联网?RG3308B16一台解决16路串口通信
串口通信·智能制造·智联物联·工业物联网·串口服务器·工业设备联网·16路串口
啊哈哈哈12 个月前
Modbus 协议官方规范资料包:中文翻译版 / 英文原版 / 中英对照版
串口通信·modbus·嵌入式开发·工业通信·plc通信·上位机开发·协议规范
sanqima2 个月前
mscomm32.ocx串口插件的注册方法
c++·串口通信·ocx插件
嵌入式×边缘AI:打怪升级日志3 个月前
Linux 串口应用编程完全学习笔记(从 API 到 GPS 实战)
串口通信·uart·gps
BackCatK Chen3 个月前
STM32保姆级入门教程|第7章:串口通信(USART)收发数据 + printf重定向打印调试(功能超详细+CubeIDE手把手)
stm32·串口通信·usart·stm32cubeide·printf重定向·嵌入式调试·中断接收
沈跃泉3 个月前
C++串口类实现
c++·windows·串口通信·串口类
小贺儿开发4 个月前
【Arduino与Unity交互探究】03 超声波测距模块
unity·arduino·串口通信·传感器·videoplayer·硬件交互
波特率1152004 个月前
C++当中is-a(继承)与has-a(成员对象)的辨析与使用指南(包含实际工程当中的使用示例)
c++·ros·串口通信
’长谷深风‘4 个月前
51单片机入门(3:串口通信)
单片机·嵌入式硬件·51单片机·串口·串口通信