文章目录
1. 通信接口概述
通信的目的:将一个设备的数据传送到另一个设备,扩展硬件系统
通信协议:制定通信的规则,通信双方按照协议规则进行数据收发
名称 | 引脚 | 双工 | 时钟 | 电平 | 设备 |
USART | TX, RX | 全双工 | 异步 | 单端 | 点对点 |
I2C | SCL, SDA | 半双工 | 同步 | 单端 | 多设备 |
SPI | SCLK, MOSI, MISO,CS | 全双工 | 同步 | 单端 | 多设备 |
CAN | CAN_H, CAN_L | 半双工 | 异步 | 差分 | 多设备 |
USB | DP, DM | 半双工 | 异步 | 差分 | 点对点 |
2. 串口通信
串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信,单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信,极大地扩展了单片机的应用范围,增强了单片机系统的硬件实力。
3. 硬件电路
使用单片机和电脑连接时,需要一个转换器。
双向串口通信有两根通信线(发送端TX和接收端RX),并且TX与RX要交叉连接,当只需单向的数据传输时,可以只接一根通信线。
当电平标准不一致时,需要加电平转换芯片。
4. 电平标准
电平标准是数据1和数据0的表达方式,是传输线缆中人为规定的电压与数据的对应关系,串口常用的电平标准有如下三种:
TTL电平:+3.3V或+5V表示1,0V表示0
RS232电平:-3~-15V表示1,+3~+15V表示0
RS485电平:两线压差+2~+6V表示1,-2~-6V表示0(差分信号)
5. 串口参数及时序
5.1 数据帧的组成
在串口通信中,每一个字节的数据都装载在一个数据帧中。每个数据帧由以下几个部分组成:
- 起始位:标志数据帧的开始。
- 数据位:实际传输的数据,通常为8位。
- 校验位(可选):用于错误检测。
- 停止位:标志数据帧的结束。
5.2 起始位
- 作用:标志一个数据帧的开始。
- 电平:固定为低电平(0)。
- 机制:串口的空闲状态是高电平(1),没有数据传输时,信号线处于高电平。发送数据时,起始位通过从高电平跳变到低电平,产生一个下降沿,通知接收设备数据传输的开始。
5.3 数据位
- 组成:数据帧的有效载荷。
- 长度:通常为8位,代表一个字节的8位二进制数据。
- 传输顺序:低位先行(LSB first)。
- 电平表示:1为高电平,0为低电平。
5.4 校验位
- 作用:用于数据验证,检测数据传输中的错误。
- 类型:奇校验和偶校验。
- 奇校验:确保数据帧中的1的数量是奇数。
- 偶校验:确保数据帧中的1的数量是偶数。
- 计算:根据数据位计算得来,并添加到数据位的最后。例如,数据为00001111,有4个1(偶数),奇校验位为1,使1的数量变为奇数(000011111)。
5.5 停止位
- 作用:标志一个数据帧的结束,同时为下一个数据帧的起始位做准备。
- 电平:固定为高电平(1)。
- 机制:在一个字节数据发送完成后,必须有一个停止位,用于数据帧间隔。如果没有停止位,当数据的最后一位是0时,下一个起始位的低电平无法形成下降沿,接收设备无法识别数据帧的开始。
5.6 波特率
- 定义:规定串口通信的速率,即每秒传输的码元数,单位是波特(Baud)。
- 比特率:每秒传输的比特数,单位是比特每秒(bps)。
- 在二进制调制情况下,1个码元等于1个比特,所以波特率等于比特率。
- 设定:发送和接收设备必须约定相同的波特率,以确保数据正确接收。
- 例如,波特率为1000bps,表示1秒传输1000位,每位的时间间隔为1毫秒(ms)。发送设备每隔1ms发送一位,接收设备也每隔1ms接收一位。
5.7 数据帧传输过程示例
- 发送端:发送数据帧01100110(8位数据位)。
- 起始位:0
- 数据位:01100110
- 校验位(奇校验):0(因数据位有4个1,补0保持奇数个1)
- 停止位:1
- 接收端:收到数据帧后,验证奇校验位,若1的个数为奇数,则数据正确,否则数据错误。
校验过程
- 发送端:计算数据位的校验位,并附加到数据后发送。
- 接收端:接收数据后,验证校验位,确保数据的奇偶性一致,否则认为数据传输出错。
数据位表示
- 方法一:校验位作为数据位的一部分,总共9位。
- 方法二:校验位和数据位分开描述,数据位8位,校验位独立1位。
6. 串口时序
第一个波形解释
该波形展示了在发送数据 0x55
时,STM32 的 TX 引脚上输出的信号。以下是详细的解释:
-
波特率和时间间隔
在此波特率下,每发送一位数据的时间间隔约为 104 微秒。
- 波特率:9600 bps(比特每秒)
- 每位时间:1 / 9600 ≈ 104 微秒(us)
-
空闲状态
- 在没有数据传输时,TX 引脚处于空闲状态,保持高电平(1)。
-
数据帧结构
- 起始位:低电平(0)
- 起始位标志数据帧的开始,产生一个从高电平到低电平的下降沿。
- 数据位:发送的数据
0x55
转换为二进制是01010101
。- 数据位按照低位先行(LSB first)的顺序发送,即:
10101010
。
- 数据位按照低位先行(LSB first)的顺序发送,即:
- 停止位:高电平(1)
- 停止位标志数据帧的结束,将引脚恢复为高电平。
- 校验位:无
- 起始位:低电平(0)
整个数据帧的波形顺序为:
- 起始位(0) -> 数据位(10101010) -> 停止位(1)
-
波形生成
- 在 STM32 中,这些波形由 USART 外设自动生成和处理。
- USART 外设会自动根据设定的波特率和数据内容翻转 TX 引脚的高低电平。
-
软件模拟
- 也可以通过软件模拟生成类似的波形。具体步骤如下:
- 使用定时器设定 104 微秒的时间间隔。
- 每到一个时间间隔,根据数据帧的要求,通过调用
GPIO_WriteBit
函数设置引脚的高低电平,产生与硬件相同的波形。
- 发送过程
- 在 TX 引脚上,按照设定的时间间隔和数据帧的要求,依次设置高低电平,完成数据发送。
- 接收过程
- 在 RX 引脚上,通过读取引脚的高低电平来接收数据。具体步骤如下:
- 设定一个外部中断,在检测到起始位的下降沿时触发接收状态。
- 对接收时钟进行采样,根据设定的波特率每 104 微秒采样一次。
- 依次采样 8 次,读取每一位数据,并将其组合成完整的数据字节。
- 在 RX 引脚上,通过读取引脚的高低电平来接收数据。具体步骤如下:
- 也可以通过软件模拟生成类似的波形。具体步骤如下:
通过观察和分析其他波形,可以理解不同数据和配置下的波形特征。例如:
-
第二个波形
- 发送数据:
0x0A
,二进制为00001010
。 - 数据帧顺序:起始位(0) -> 数据位(01010000) -> 停止位(1)
- 发送数据:
-
第三个波形
- 发送数据:
0xFF
,二进制为11111111
。 - 数据帧顺序:起始位(0) -> 数据位(11111111) -> 停止位(1)
- 发送数据:
-
第四个波形
- 发送数据:
0x00
,二进制为00000000
。 - 数据帧顺序:起始位(0) -> 数据位(00000000) -> 停止位(1)
- 发送数据:
每一个数据帧的生成和传输过程都是一致的,通过控制起始位、数据位和停止位的顺序和电平,可以确保数据的正确传输和接收。
7. USART概述
USART(Universal Synchronous/Asynchronous Receiver/Transmitter)是STM32微控制器内部集成的一个硬件外设,用于串行数据通信。它能够根据数据寄存器中的一个字节数据自动生成数据帧时序,并通过TX引脚发送出去,同时也可以自动接收RX引脚的数据帧时序,将其拼接成一个字节数据并存放在数据寄存器中。
波特率生成器
- 功能:USART内置波特率发生器,最高支持4.5 Mbps的速率。
- 工作原理:波特率发生器通过对输入时钟频率进行分频来生成所需的波特率时钟。例如,如果APB2总线提供72 MHz的频率,波特率发生器将对其进行分频,生成所需的波特率时钟。在这个时钟下进行数据的收发,即为指定的通信波特率。
配置选项
- 数据位长度:可配置为8位或9位数据长度。
- 停止位长度:可选0.5、1、1.5或2个停止位。
- 校验位:可选无校验、奇校验或偶校验。
- 模式支持:
- 同步模式:用于需要时钟信号的通信。
- 硬件流控制:用于避免数据丢失的问题。
- DMA(直接存储器访问):用于大量数据传输,减轻CPU负担。
- 智能卡模式:支持智能卡通信。
- IrDA(红外数据协会):用于红外通信。
- LIN(局域网络接口):用于汽车通信网络。
硬件流控制
- 问题:当A设备通过TX向B设备的RX发送数据,如果A发送太快,B处理不过来,就可能导致数据丢失。
- 解决方案:硬件流控制在硬件电路上多出一根线,用于反馈B设备的准备状态。
- 当B设备没有准备好接受数据时,发送高电平信号。
- 当B设备准备好接受数据时,发送低电平信号。
- A设备根据B设备的反馈信号决定是否发送数据。
- 作用:避免数据丢失的问题,确保数据传输的可靠性。
- 使用:STM32支持硬件流控制,但一般情况下不常用。
DMA支持
- 功能:USART支持DMA(直接存储器访问)用于数据传输。
- 优势:在进行大量数据收发时,DMA可以直接将数据从存储器传输到USART外设或从USART外设传输到存储器,减轻了CPU的负担,提高了数据传输效率。
STM32F103C8T6的USART资源
- USART1:连接在APB2总线上。
- USART2、USART3:连接在APB1总线上。
8. USART框图
引脚功能
- SW_RX、IRDA_OUT/IN:这些引脚用于智能卡和红外(IrDA)通信。
数据寄存器
- 发送数据寄存器(TDR,Transmit Data Register):用于存储待发送的数据,是只写寄存器。
- 接收数据寄存器(RDR,Receive Data Register):用于存储接收到的数据,是只读寄存器。
- 数据寄存器(DR,Data Register):在程序中表现为一个寄存器,但在硬件中实际分为TDR和RDR。当进行写操作时,数据写入TDR;当进行读操作时,数据从RDR读取。
移位寄存器
- 发送移位寄存器:用于将一个字节的数据一位一位地通过TX引脚发送出去。例如,当TDR中写入数据
0x55
(二进制:0101 0101)时,硬件会检测到数据写入,并检查发送移位寄存器是否空闲。如果空闲,则数据立即移动到发送移位寄存器。然后,TXE(Transmit Data Register Empty)标志位置1,表示可以写入新的数据。 - 接收移位寄存器:用于从RX引脚接收数据。一位一位地读取RX引脚的电平,并将数据依次存入接收移位寄存器。数据移位完成后,整个字节数据转移到RDR中,同时RXNE(Receive Data Register Not Empty)标志位置1,表示RDR中有数据可以读取。
数据发送过程
- 写入TDR:将数据写入发送数据寄存器TDR。
- 数据转移:数据从TDR转移到发送移位寄存器,并置位TXE标志。
- 数据移位:发送移位寄存器在波特率控制下,一位一位地通过TX引脚发送数据。
- 连续发送:当一个字节数据发送完毕,新的数据从TDR自动转移到发送移位寄存器,确保数据连续发送。
数据接收过程
- 接收数据:RX引脚接收数据,一位一位存入接收移位寄存器。
- 数据移位:接收移位寄存器将数据移位,并在移位完成后将整个字节数据转移到RDR中。
- 读取RDR:RXNE标志置位后,程序从RDR读取数据。
硬件数据流控制
- nRTS(Request To Send):输出引脚,指示设备是否可以接收数据。
- nCTS(Clear To Send):输入引脚,指示对方设备是否可以发送数据。
- 使用步骤:
- 请求发送:当设备准备好接收数据时,nRTS置低电平,请求对方发送数据。
- 清除发送:对方设备检测到nCTS低电平后,开始发送数据;当接收数据寄存器满时,nRTS置高电平,指示对方暂停发送。
波特率发生器
- 工作原理:
- 通过对APB时钟进行分频,生成发送和接收移位寄存器所需的时钟信号。
- USARTDIV:分频系数,包含整数和小数部分,支持更精确的波特率配置。
中断控制
- 中断申请位:由状态寄存器的各种标志位(如TXE、RXNE)触发。
- 中断处理:通过中断服务程序(ISR)处理数据的发送和接收,提高效率。
唤醒单元
- 功能:实现多设备通信,通过地址唤醒特定设备。
- 工作原理:
- 为每个设备分配一个地址。
- 发送设备发送目标设备地址,目标设备检测到地址匹配后唤醒,开始通信。
同步时钟模块
- 用途:
- 兼容其他协议,如SPI。
- 实现自适应波特率,接收设备通过测量同步时钟周期计算波特率。
9. USART基本结构
最左边的是波特率发生器,它用于产生约定的通信速率。时钟来源可以是PCLK2或PCLK1,通过波特率发生器进行分频后,生成的时钟信号被送到发送控制器和接收控制器。
发送部分
- 发送控制器和接收控制器负责控制发送和接收的数据移位。
- 发送数据寄存器(TDR)和发送移位寄存器配合工作,将数据一位一位地移出。
- 数据通过GPIO的复用功能输出到TX引脚,生成符合串口协议的波形。发送移位寄存器按低位先行的顺序向右移位。
- 当数据从TDR转移到移位寄存器时,会置位一个标志位TXE(Transmit Data Register Empty)。通过检查这个标志位,可以知道是否可以写入下一个数据。
接收部分
- RX引脚接收的波形通过GPIO输入,在接收控制器的控制下,一位一位地移入接收移位寄存器。
- 完整接收一帧数据后,数据会转移到接收数据寄存器(RDR)。
- 转移过程中,会置位一个标志位RXNE(Receive Data Register Not Empty)。通过检查这个标志位,可以知道是否收到了数据。同时,该标志位也可以触发中断,快速读取和保存数据。
数据寄存器
- 软件层面只有一个数据寄存器(DR)用于读写。当写入DR时,数据走发送路径进行发送;当读取DR时,数据走接收路径进行接收。
10. 数据帧
STM32的串口可以配置停止位为0.5、1、1.5、2,这四种参数的区别,就是停止位的时长不一样,1位停止位,这时停止位的时长就和数据位的一位,时长一样,1.5停止位就是数据位一位,时长的1.5倍,2个停止位,那停止位时长就是2倍,0.5个停止位,时长就是0.5倍,一般选择1位停止位。
输出(TX)部分
串口的输出(TX)相对简单,只需按照设定的波特率定时翻转TX引脚的高低电平即可。
输入(RX)部分
输入(RX)比输出复杂得多,需要满足以下条件:
- 采样频率与波特率一致:必须确保输入采样频率与设定的波特率相一致。
- 精确的采样位置:每次采样必须正好位于每一位数据的正中间位置。只有在正中间采样,才能确保读取的高低电平是最可靠的。如果采样点偏前或偏后,电平可能正在翻转且不稳定,导致采样错误。
噪声处理
输入电路还需要一定的噪声判断能力。如果检测到噪声,应设置标志位以提醒存在噪声干扰。STM32的USART输入电路设计具备这种功能。
起始位侦测
- 检测起始位:输入电路检测到一个数据帧的起始位后,会以波特率的频率连续采样一帧数据。采样位置必须从起始位开始对齐到位的正中间。只要第一位对齐,后面的位也会对齐。
- 16倍采样率:为了实现精确采样,输入电路以波特率的16倍频率进行采样,即在一位的时间内可以进行16次采样。
采样策略
- 初始采样:在空闲状态下,采样结果一直为高电平(1)。一旦在某个位置采集到低电平(0),说明出现了下降沿,可能是起始位。
- 连续采样:在起始位期间进行16次连续采样。如果没有噪声,这16次采样结果应全为0。
- 噪声处理:实际电路中可能存在噪声。因此,在检测到下降沿后,额外进行几次采样:
- 第3、5、7次采样。
- 第8、9、10次采样。
- 噪声判断:在两批采样中,每批3次采样中至少有2个0,才能确认是起始位。如果采样结果满足条件但有噪声,状态寄存器会设置NE(Noise Error)标志位,提醒数据有噪声。如果3次采样中只有一个0,则认为不是起始位,电路忽略前面的数据,重新捕捉下降沿。
起始位确认
如果通过了起始位检测,接收状态从空闲变为接收状态,并且第8、9、10次采样的位置正好是起始位的正中间。之后的数据位也在第8、9、10次进行采样,确保采样位置在每个位的正中间。
11. 波特率发生器
发送器和接收器的波特率由波特率寄存器BRR里的DIV确定
计算公式:波特率 = f(PCLK2/1) / (16 * DIV)
12. 数据模式(数据包)
HEX模式/十六进制模式/二进制模式:以原始数据的形式显示
文本模式/字符模式:以原始数据编码后的形式显示
数据包的作用
数据包的作用是将单独的数据打包在一起,方便进行多字节的数据通信。例如,在将陀螺仪传感器的数据通过串口发送到STM32时,陀螺仪的数据包括X轴、Y轴和Z轴,每个轴的数据为一个字节,总共需要连续不断地发送三个字节的数据。当数据以XYZXYZXYZ的形式连续发送时,接收方可能无法区分哪个字节对应X轴,哪个字节对应Y轴,哪个字节对应Z轴,因为接收方可能从任意位置开始接收数据,这就可能导致数据错位。
为了解决这个问题,需要一种方式将数据分割开来,将XYZ这批数据打包成一个个数据包。这样在接收时,就可以明确数据包的第一个字节是X,第二个字节是Y,第三个字节是Z。数据包的任务就是将同一批的数据进行打包和分割,确保接收方能够正确解析数据。
实现串口数据包
串口数据包通常通过在数据前后额外添加包头和包尾来实现。
防止包头包尾和数据重复的方法
- 限制载荷数据的范围:在发送数据时,对数据进行限幅,确保数据不会与包头和包尾相同。
- 使用固定长度的数据包:尽量使用固定长度的数据包,使接收方能够按照固定长度解析数据。
- 增加包头包尾的数量:在数据包中增加包头和包尾的数量,使其呈现出载荷数据不会出现的状态,进一步确保数据包的唯一性。
13. HEX数据包
固定包长,含包头包尾
可变包长,含包头包尾
HEX数据包接收
状态说明
-
等待包头状态(S = 0)
- 初始状态,等待接收数据包的包头(0xFF)。
- 如果接收到的数据不是包头,则继续等待。
-
接收数据状态(S = 1)
- 当接收到包头(0xFF)后,进入此状态。
- 开始接收数据,并记录接收到的数据个数。
- 如果接收到的数据不足4个,则继续接收数据。
- 当接收满4个数据后,状态转为等待包尾。
-
等待包尾状态(S = 2)
- 接收到4个数据后,进入此状态,等待接收包尾(0xFE)。
- 如果接收到的数据不是包尾,则继续等待包尾。
- 当接收到包尾(0xFE)后,重置状态机回到初始状态,准备接收下一个数据包。
状态机执行流程
-
初始状态:S = 0,等待包头
- 收到一个数据,进入中断处理。
- 根据S的值判断当前状态:
- 如果S = 0,检查数据是否为包头(0xFF)。
- 是包头,设置S = 1,退出中断。
- 不是包头,继续等待包头,S保持为0。
- 如果S = 0,检查数据是否为包头(0xFF)。
-
接收数据:S = 1,接收数据。
- 再次进入中断处理,根据S的值判断当前状态:
- 如果S = 1,接收数据并记录接收的数据个数。
- 如果接收的数据不足4个,继续接收数据。
- 如果接收满4个数据,设置S = 2,退出中断。
- 再次进入中断处理,根据S的值判断当前状态:
-
等待包尾:S = 2,等待包尾。
- 再次进入中断处理,根据S的值判断当前状态:
- 如果S = 2,检查数据是否为包尾(0xFE)。
- 是包尾,设置S = 0,回到初始状态,准备下一个数据包。
- 不是包尾,继续等待包尾。
- 如果S = 2,检查数据是否为包尾(0xFE)。
- 再次进入中断处理,根据S的值判断当前状态:
14. 文本数据包
固定包长,含包头包尾
可变包长,含包头包尾
文本数据包接收
参考HEX数据包的状态说明,流程类似。
15. 代码示例
STM32单片机USART串口打印和收发数据
STM32单片机USART串口收发数据包