1. 概述
通信方式 | 说明 | 示例 |
---|---|---|
全双工 (Full-duplex) | 同一时刻,数据可以在两个方向上同时传输。 | 电话、以太网 |
半双工 (Half-duplex) | 数据可以在两个方向上传输,但同一时刻只能在一个方向上传输。 | 对讲机、RS485 (两线制) |
单工 (Simplex) | 数据只能在一个固定的方向上传输。 | 广播、电视 |
定时方式 | 说明 | 示例 |
---|---|---|
同步 (Synchronous) | 通信双方使用同一根时钟信号线来协调数据传输。发送方在时钟信号的特定边沿发送数据,接收方在相同边沿接收数据。 | I2C, SPI |
异步 (Asynchronous) | 通信双方没有共用的时钟线,而是通过数据帧中的起始位和停止位来实现同步。双方需要预先约定好相同的波特率。 | UART (串口) |
2. 各种通讯协议
2.1 串口通信协议 (UART)
物理层电平标准对比:
协议 | 特点 | 电平标准 (逻辑) | 通信方式 | 应用场景 |
---|---|---|---|---|
TTL | 微控制器常用的电平标准,抗干扰能力弱,传输距离短。 | 1: 2V ~ 5V 0: 0V ~ 0.8V | 全双工 | 板级通信、模块调试 |
RS232 | 使用负逻辑和高电压摆幅,抗干扰能力较强,传输距离中等 (约15米)。 | 1: -3V ~ -15V 0: +3V ~ +15V | 全双工 | 工业设备、老式PC串口 |
RS485 | 使用差分信号,抗干扰能力极强,传输距离远 (可达1200米以上),支持多节点组网。 | 1: A-B > +200mV 0: A-B < -200mV | 两线制:半双工 四线制:全双工 | 工业自动化、长距离数据采集 |
数据帧格式:
- 空闲状态: 总线处于高电平。
- 起始位 (Start Bit): 1位低电平,标志着一个新数据帧的开始。
- 数据位 (Data Bits): 5-8位有效数据,低位先行 (LSB First)。
- 校验位 (Parity Bit): (可选) 用于数据校验,有奇校验、偶校验、无校验等方式。
- 停止位 (Stop Bit): 1、1.5或2位高电平,标志着数据帧的结束。
波特率与比特率:
这是一个常见的混淆点,准确定义如下:
- 波特率 (Baud Rate):指码元的传输速率,即每秒传输多少个码元(或称符号)。单位是波特 (Baud)。一个码元可以携带一或多位信息。
- 比特率 (Bit Rate):指信息的传输速率,即每秒传输多少个二进制位。单位是bps (bits per second)。
在串口通信中,一个码元只表示一位二进制信息(高/低电平),因此数值上,波特率 = 比特率。 例如,9600波特率意味着比特率也是9600 bps。
有效数据传输速率计算: 我们通常更关心有效数据(不含起始/停止/校验位)的传输速率。
- 例如: 波特率为9600,数据格式为8位数据位、无校验位、1位停止位 (常表示为 8-N-1)。
- 传输一个字节 (8位) 的数据,实际需要发送
1 (起始位) + 8 (数据位) + 1 (停止位) = 10
位。 - 每秒传输的位数 = 9600 bps。
- 每秒传输的字节数 =
9600 / 10 = 960
字节/秒。
- 传输一个字节 (8位) 的数据,实际需要发送
STM32中配置波特率的计算
- f_CK 为该USART外设的时钟频率 (例如,USART1挂在APB2上,通常为72MHz)。
- USARTDIV 是一个无符号定点数,由整数部分 (DIV_Mantissa) 和小数部分 (DIV_Fraction) 组成。
- OVER8 是过采样率,0表示16倍过采样,1表示8倍过采样。
示例: f_CK = 72MHz
,BaudRate = 115200
,16倍过采样 (OVER8=0)。
USARTDIV = 72,000,000 / (16 * 115200) = 39.0625
- 整数部分
DIV_Mantissa = 39
(即0x27
)。 - 小数部分
0.0625
。因为小数部分用4位表示,所以乘以16:0.0625 * 16 = 1
(即0x1
)。 - 写入
USART_BRR
寄存器的值 =(DIV_Mantissa << 4) | DIV_Fraction
=(0x27 << 4) | 0x1
=0x271
。
3. I2C协议 (Inter-Integrated Circuit)
I2C是一种同步、半双工、多主多从的串行总线。
3.1 物理层
- 两根线:
- SCL (Serial Clock): 串行时钟线,由主机产生,用于同步数据传输。
- SDA (Serial Data): 串行数据线,用于传输数据。
- 开漏输出 (Open-Drain): SCL和SDA线都是开漏/开集电极结构,只能输出低电平,不能主动输出高电平。
- 上拉电阻: 因此,SCL和SDA线必须外接上拉电阻到VCC,以形成高电平。总线空闲时,SCL和SDA都处于高电平。
3.2 协议层 (关键时序)
- 起始信号 (Start Condition): SCL为高电平时,SDA由高电平跳变为低电平。
- 停止信号 (Stop Condition): SCL为高电平时,SDA由低电平跳变为高电平。
- 数据传输: SCL为低电平时,SDA上的数据才允许变化;SCL为高电平时,SDA上的数据必须保持稳定,以供接收方采样。
- 应答信号 (ACK): 发送方每发送完8位数据 (一个字节) 后,接收方会在第9个时钟周期将SDA拉低,表示成功接收,称为ACK。如果接收方未拉低SDA(保持高电平),则为非应答信号 (NACK)。
- 基本通信流程 (主机写):
Start
->从机地址(7位) + 写(0)
->ACK
->寄存器地址
->ACK
->数据
->ACK
-> ... ->Stop
3.3 硬件I2C和软件I2C的区别
特性 | 硬件I2C | 软件I2C (GPIO模拟) |
---|---|---|
实现方式 | 使用MCU内部集成的I2C外设模块。 | 使用通用IO口 (GPIO),手动控制电平高低和时序。 |
CPU占用 | 低。数据收发由硬件处理,完成后通过中断通知CPU。 | 高。CPU需要全程参与,模拟时序,占用大量CPU时间。 |
速度/可靠性 | 高。时序精准,支持标准速率和高速率。 | 较低。速度受CPU主频和代码效率影响,易受中断干扰。 |
灵活性 | 低。只能使用指定的I2C引脚。 | 高。任意GPIO引脚都可以用作SCL/SDA。 |
4. SPI通讯协议 (Serial Peripheral Interface)
SPI是一种高速、全双工、同步的通信总线,采用主从模式工作。
4.1 物理层
通常使用4根线:
- SCK (Serial Clock): 时钟线,由主机产生。
- MOSI (Master Out Slave In): 主机输出、从机输入线,数据从主机流向从机。
- MISO (Master In Slave Out): 主机输入、从机输出线,数据从从机流向主机。
- CS/SS (Chip Select / Slave Select): 片选线,由主机控制,用于选择与之通信的从机。通常为低电平有效。
4.2 协议层
- 工作原理: SPI的核心是两个连接在一起的移位寄存器(一个在主机,一个在从机)。SCK的每个时钟周期,数据从MOSI移入从机,同时从MISO移入主机,实现全双工数据交换。
- 无协议开销: SPI没有起始/停止位,也没有应答机制,协议非常简单高效。数据的意义由上层应用定义。
注意:
- MOSI与MISO的信号只在NSS为低电平的时候才有效,在SCK的每个时钟周期MOSI和MISO传输一位数据。数据的输入和输出是同时进行的,在 SCK下降沿 进行数据 采样 ,SPI每次数据传输可以 以8位或16位为单位 ,每次传输单位数不受限制。
4.3 SPI通讯模式 (4种)
由时钟极性 (CPOL) 和 时钟相位 (CPHA) 组合决定。
- CPOL (Clock Polarity): 定义SCK空闲时的电平状态。
CPOL=0
: 空闲时为低电平。CPOL=1
: 空闲时为高电平。
- CPHA (Clock Phase): 定义数据采样的时钟边沿。
CPHA=0
: 在第1个时钟边沿采样。CPHA=1
: 在第2个时钟边沿采样。
模式 | CPOL | CPHA | 描述 |
---|---|---|---|
0 | 0 | 0 | SCK空闲为低,第一个边沿(上升沿)采样 |
1 | 0 | 1 | SCK空闲为低,第二个边沿(下降沿)采样 |
2 | 1 | 0 | SCK空闲为高,第一个边沿(下降沿)采样 |
3 | 1 | 1 | SCK空闲为高,第二个边沿(上升沿)采样 |
4.4 主从控制逻辑
- 主机在通信前,将目标从机的CS线拉低。
- 主机通过SCK线产生时钟信号。
- 主机将要发送的数据放到MOSI线上,同时从MISO线读取数据。
- 通信结束后,主机将CS线拉高,取消对该从机的选择。
主模式收发流程及事件说明如下:
- 控制NSS信号线,产生起始信号(图中没有画出);
- 把要发送的数据写入到“数据寄存器“DR”中,该数据会被存储到发送缓冲区;
- 通讯开始,SCK时钟开始运行。MOSI 把发送缓冲区中的数据一位一位地传输出去;MISO 则把数据一位一位地存储进接收缓冲区中;
- 当发送完一帧数据的时候,“ 状态寄存器 SR ”中的“TXE 标志位”会被置 1,表示传输完一 帧,发送缓冲区已空;类似地,当接收完一帧数据的时候,“RXNE 标志位”会被置 1,表示传输完一帧,接收缓冲区非空;
- 等待到“TXE 标志位”为 1 时,若还要继续发送数据,则再次往“数据寄存器 DR”写入数据 即可;等待到“RXNE 标志位”为 1 时,通过读取“数据寄存器 DR”可以获取接收缓冲区中的 内容。
- 假如我们使能了 TXE 或 RXNE 中断,TXE 或 RXNE 置 1 时会产生 SPI 中断信号,进入同一个中断服务函数,到 SPI 中断服务程序后,可通过检查寄存器位来了解是哪一个事件,再分别进行处理。也可以使用 DMA 方式来收发“数据寄存器 DR”中的数据。
5. CAN协议 (Controller Area Network)
CAN是一种基于消息的串行通信协议,以其高可靠性和实时性著称,广泛应用于汽车电子和工业自动化领域。
5.1 物理层
- 差分信号: 使用两根线 CAN_H 和 CAN_L 进行差分传输,抗干扰能力极强。
- 总线拓扑: 典型的总线结构,所有节点都挂在同一对双绞线上。
- 终端电阻: 总线的两端必须各接一个120Ω的终端电阻,用于防止信号反射和保证阻抗匹配。
- 电平状态:
- 显性 (Dominant) - 逻辑'0':
CAN_H
和CAN_L
之间有电压差 (约2V)。 - 隐性 (Recessive) - 逻辑'1':
CAN_H
和CAN_L
之间无电压差 (约0V)。 - 特性: 显性位可以覆盖隐性位。如果一个节点发送显性位,另一个发送隐性位,总线上表现为显性位。
- 显性 (Dominant) - 逻辑'0':
5.2 核心特点
- 基于消息,而非地址: CAN网络中没有主从概念,也没有设备地址。节点发送的是带有消息ID (Identifier) 的报文。所有节点都能接收到报文,但会根据ID自行判断是否需要处理。
- 冲突仲裁机制 (CSMA/CA):
- 载波侦听 (CSMA): 节点在发送前会检查总线是否空闲。
- 冲突仲裁 (CA): 如果多个节点同时发送,它们会逐位比较自己发送的位和总线上的实际位。当节点发送一个隐性位('1')却在总线上检测到显性位('0')时,它就知道有更高优先级的消息在发送(因为ID值更小),于是立即停止发送,转为接收模式。
- 优先级:消息ID越小,优先级越高。 这个机制保证了总线永远不会被冲突搞瘫痪。
- 强大的错误处理: CAN协议内置了多种错误检测机制,如CRC校验、位填充、ACK校验、帧格式检查等,确保了极高的通信可靠性。
- CAN数据帧 (标准帧为例):
SOF (1位)
->ID (11位)
->RTR
->控制场
->数据场(0-8字节)
->CRC(15位)
->ACK
->EOF