STM32的串口通信
数据通信的基础概念
数据通信的分类
串行/并行通信
串行与并行的比较
解释:因为串行的数据传输是单线的而并行有多条线,多条线传输电信号的过程中会相互干扰,所以并行通信的抗干扰能力更弱。
单工/半双工/全双工通信
-
单工通信:数据只能沿一个方向传输
-
半双工通信:数据可以沿两个方向传输,但需要分时进行(两方向,同线,不同时)
- 全双工通信:数据可以同时进行双向传输
同步/异步通信
-
同步通信:共用同一时钟信号
-
异步通信:没有时钟信号,通过在数据信号中加入起始位和停止位等一些同步信号
波特率
- 比特率:每秒钟传送的比特数,单位bit/s
- 波特率:每秒钟传送的码元数,单位Baud
比特率 = 波特率 * [log2 M ],(log2 M取不小于log2 M的整数。M表示每个码元承载的信息量)
二进制系统中,波特率数值上等于比特率
补充——码元
码元(Symbol)是数字通信中的基本单位,它代表着一种离散的信号状态。在数字通信中,信息通常以一系列离散的码元进行传输和表示。
码元可以是二进制的(0和1),也可以是多进制的(例如四进制、八进制等)。每个码元代表着一定的信息,例如一个二进制码元可以表示一个比特(bit),而一个四进制码元可以表示两个比特。
举例
用二进制表示两次抛硬币的结果则有00,01,10,11四种这个结果就是一个码元,在此,一个码元代表2位二进制。
设其波特率为x
比特率 = 波特率 × 每个码元所表示的比特数
所以其比特率就为x*2
相同的,若跑三次硬币,以三次结果为波特率,000,001,010,011,100,101,110,111,一个码元包含8种信息,即3位比特数,所以比特率=x*3.
常见的串行通信接口
=img-4GGJwYEr-1707208040434)
数据帧
- 数据帧:数据帧(Data Frame)是在计算机网络和通信领域中使用的一种数据传输单位。它是将数据分割成一系列固定长度的单元,并添加了一些控制信息和标识符,以便在网络中正确传输和识别数据。
串口的数据帧格式
空闲
起始位
起始位:表示数据帧的开始,实际使用1位低电平表示起始位
数据位
用于传输数据
低电平表示0,高电平表示1
8~9位
LSP First (Least Significant Bit First)先传最低有效位
校验位
校验位:为了检验数据传输是否出错而设立的比特位
校验位和数据位的关系
奇偶校验规则
graph LR
A[奇偶校验(查1的个数)]-->B[奇校验]
B-->B1[控制校验位为0/1,使数据位和校验位1的总数位奇数]
A-->C[偶校验]
C-->C1[控制校验位为0/1,使数据位和校验位1的总数为偶数]
停止位
停止位:表示数据帧的结束,高电平,长度可以是0.5, 1, 1.5, 2
数据发送
单个数据发送
单个数据发送:在单个数据发送中,每个数据单元(如字符或字节)都被独立地发送。发送端将一个数据单元封装成一个数据帧,并通过物理介质将其发送给接收端。接收端收到一个数据单元后,进行处理和分析,然后等待下一个数据单元的到达。
单个数据发送适用于一次性传输独立的数据单元,每个数据单元之间可能存在较长的时间间隔
连续发送
连续发送:在连续发送中,多个数据单元被连续地发送。发送端将多个数据单元组合成一个数据流,并通过物理介质连续地发送给接收端。接收端在接收到数据流后,进行解析和处理,将连续的数据单元还原出来。
连续发送适用于需要高速率传输或实时性要求较高的场景。
e.g.
发送Hello
8位数据位,无校验, 1位停止位
H - 0x48 (0100 1000) e - 0x65(0110 0101) l - 0x6c(0110 1010) o - 0x6f (0110 1111)
硬件流控
流控的概念
数据流控(Flow Control)是在数据通信中使用的一种机制,用于控制发送方和接收方之间的数据传输速率,以避免数据丢失或过载。
产生意义:
在数据通信中,发送方和接收方可能存在传输速率不匹配的情况。如果发送方连续地向接收方发送数据,而接收方的处理能力有限,可能导致接收方无法及时处理所有的数据,从而造成数据丢失或缓冲区溢出。为了解决这个问题,数据流控机制被引入。
就是因收发速度不同,为防止发送端速度过快,接收端未来得及接受数据就被新数据覆盖而导致的数据丢失问题。于是有了“数据流控”来控制发送端的传输速度。
实现流控的方法
-
停止-等待流控:发送方在发送完一个数据包后,等待接收方的确认信号,然后再发送下一个数据包。这种方式可以确保接收方有足够的时间来处理接收到的数据,但会导致发送方的利用率较低。
以听写为例(左为无流控,右为流控结果)
-
滑动窗口流控:发送方和接收方之间维护一个滑动窗口,窗口的大小表示允许发送的未确认数据包数量。发送方根据窗口大小来发送数据包,接收方根据窗口大小来确认已接收的数据包。通过动态调整滑动窗口的大小,可以实现发送方和接收方之间的数据传输速率匹配。
举例
-
缓冲区管理:在接收方使用缓冲区来存储接收到的数据,以便在处理能力不足时,暂时存储数据而不丢失。通过合理管理缓冲区的大小和数据处理能力,可以实现数据流控。
举例
假设你是一位餐厅服务员,负责将菜品送到客人桌上。餐厅的厨房有一个10个盘子的缓冲区,你可以将菜品放到缓冲区中,然后再将其送到客人桌上。然而,客人的用餐速度有限,他们只能及时吃完3个盘子的菜品。当缓冲区中的盘子满时,你会通知厨房停止制作菜品,直到客人吃完一些菜品,腾出空间来。
串口流控的工作原理
串口(以RS-232为例)
-
串口:串行通信接口:指按位发送和接收的接口。如:RS-232/422/485等
-
RS-232接口(DB9):
-
数据:
TXD(pin 3):串口数据输出
RXD(pin 2):串口数据输入
-
握手:
RTS(pin 7):请求发送
CTS(pin 8):清除发送
DSR(pin 6):数据发送就绪
DCD(pin 1):数据载波检测
DTR(pin 4):数据终端就绪
-
地线:
GND(pin 5):信号地
-
其他:
RI(pin 9):振铃指示
-
RS-232电平与COMS/TTL电平对比
RS-232电平 | COMS电平(3.3V) | TTL电平(5V) |
---|---|---|
逻辑1:-15V ~ -3V | 逻辑1:3.3V | 逻辑1:5V |
逻辑0:+3V ~ +15V | 逻辑0:0V | 逻辑0:0V |
由此观之,COMS/TTL电平不能与RS-232电平直接交换信息
设备间的RS-232通信示意图
STM串口与电脑USB口通信示意图
S3-232异步通信协议
- 启动位:必须占1个位长,保持逻辑0电平
- 有效数据位:可选5、6、7、8、9个位长,LSB(最小数据位,在途中表示位位0)在前,MSB(最大数据位,在图中表示为位7)在后
- 校验位:可选占1个位长,也可以没有该位
- 停止位:必须有,可选占0.5、1、1.5、2个位长,保持逻辑1电平
STM32的USART
USART : Universal synchronous asynchronous receiver transmitter,通用同步异步收发器
UART : Universal asynchronous receiver transmitter,通用异步收发器
-
USART/UART都可以与外部设备进行全双工异步通信
-
USART,我们常用的也是异步通信
STM32的主要特征
1,全双工异步通信
2,单线半双工通信
3,单独的发送器和接收器使能位
4,可配置使用DMA的多缓冲器通信
5, 多个带标志的中断源
参考:STM32xxxx参考手册(中文版).pdf USART相关章节
参考:STM32F103ZET6(中文版).pdf
STM32F1USART框图
**注意:框图中灰色的部分(即发送数据寄存器、发送移位寄存器、接接收数据寄存器、收移位寄存器)都是不可直接读取或写入数据的。**要获取输入的数据,必须通过接收数据寄存器将数据传输到数据寄存器中再读取。
现大致将框图分为3部分来讲解
- 发送接收数据的流程
- 相关寄存器的作用
- 设置波特率
发送/接收数据的流程
由图可知,TX和RX引脚用作数据的输入与输出。
当传输数据时,外部输入设备输入串行数据至RX引脚,通过编解码模块再到接收移位寄存器,再传输到接收数据寄存器,最后到CPU处理。
发送数据时通过CPU发送数据至发送数据寄存器,再到发送移位寄存器最后通过编解码模块传输到TX引脚,输出到外部设备。
相关寄存器的作用
-
GTPR 寄存器:用于设置 USART 的守护时间和预分频器值。守护时间是指在停止位和下一个起始位之间的空闲时间。预分频器用于设置通信时钟的分频比,以确定波特率的精确值。
-
CR1 寄存器用于配置 USART 的工作模式和通信参数。其中可能包括以下功能:
- 波特率设置:用于设置 USART 的波特率,包括整数部分和小数部分。
- 数据位数:用于选择发送和接收数据时使用的数据位数,如 8 位、9 位等。
- 奇偶校验:用于选择奇偶校验模式,或者禁用校验。
- 发送和接收使能:用于启用或禁用发送和接收功能
-
CR2 寄存器用于配置 USART 的一些附加参数。其中可能包括以下功能:
- 停止位设置:用于选择发送和接收数据时使用的停止位的数量。
- 数据极性:用于定义数据的电平极性,可以选择正常或反转极性。
- 硬件流控制:用于启用或禁用硬件流控制功能,如 RTS/CTS 流控制。
-
CR3 寄存器用于配置 USART 的一些其他功能。其中可能包括以下功能:
- DMA 控制:用于启用或禁用 DMA(直接内存访问)控制,以实现无需 CPU 干预的数据传输。
- 半双工模式:用于配置 USART 为半双工通信模式。
- 错误中断使能:用于启用或禁用错误中断,以在发生错误时触发相应的中断处理程序。
设置波特率(USART1为例)
(STM32F1USART框图中词部分用于波特率的设置)
计算
(F1)波特率计算公式:baud=“fck” /(16∗USARTDIV)
其中"fck"是串口的时钟,如:USART1的时钟是PCLK2,其他串口都是PCLK1
USARTDIV表示USART波特率分频寄存器的值
例如
波特率为115200时:
115200=72000000/(16*USARTDIV)
//通过查询STM32参考手册可知USART1的时钟最大频数是72M,所以fck填入72*10**6
得USARTDIV=39.0625
将数据写入到寄存器中
波特比率寄存器
把USARTDIV的整数部分写入位[15:4], USARTDIV的小数部分写入[3:0]
uint16_t mantissa;
uint16_t fraction;
mantissa=39;
fraction=0.0625*16+0.5=0x01; /* USARTDIV = DIV_Mantissa + (DIV_Fraction/16) */
USART1->BRR = (mantissa << 4) + fraction;
说明
- 代表写入数据的整数部分39
- mantissa << 4是因为写入数据是整数部分占[15:4],右边的[3:0]要留给小数部分所以整体左移
- fraction=0.0625*16+0.5=0x01;
- 其中*16的功能与<<4相同。因为是小数但填入后是二进制的形式不左移的话超出范围且[3:0]空了所以要左移
- +0.5的目的是实现四舍五入类似Python中int(x+0.5)
至此波特率的设置的理论就基本完成了。为了更加方便接下来讲解波特率设置通用公式的推演。
波特率设置通用公式推演
ion=0.062516+0.5=0x01; / USARTDIV = DIV_Mantissa + (DIV_Fraction/16) */
USART1->BRR = (mantissa << 4) + fraction;
> 说明
>
> + 代表写入数据的整数部分39
> + mantissa << 4是因为写入数据是整数部分占[15:4],右边的[3:0]要留给小数部分所以整体左移
> + fraction=0.0625*16+0.5=0x01;
> + 其中*16的功能与<<4相同。因为是小数但填入后是二进制的形式不左移的话超出范围且[3:0]空了所以要左移
> + +0.5的目的是实现四舍五入类似Python中int(x+0.5)