你真的懂吗
文章目录
- 你真的懂吗
- 前言
- 二、什么是串口通信
- 二、STM32的串口
- 三、什么是数据通信
前言
串口通信是一种设备间常用的串行通信方式,串口按位(bit)发送和接收字节。尽管比字节(byte)的串行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。串口通信协议是指规定了数据包的内容,内容包含了起始位、主体数据、校验位及停止位,双方需要约定一致的数据包格式才能正常收发数据的有关规范。
二、什么是串口通信
串行通讯是指仅用一根接收线和一根发送线就能将数据以位进行传输的一种通讯方式。尽管串行通讯的比按字节传输的并行通信慢,但是串口可以在仅仅使用两根线的情况下就能实现数据的传输。典型的串口通信使用3根线完成,分别是地线、发送、接收。由于串口通信是异步的,所以端口能够在一根线上发送数据同时在另一根线上接收数据。串口通信最重要的参数是波特率、数据位、停止位和奇偶的校验。对于两个需要进行串口通信的端口,这些参数必须匹配,这也是能够实现串口通讯的前提。
先来看串口的数据结构图
起始位: 起始位必须是持续一个比特时间的逻辑0电平,标志传输一个字符的开始,接收方可用起始位使自己的接收时钟与发送方的数据同步。数据位: 数据位紧跟在起始位之后,是通信中的真正有效信息。数据位的位数可以由通信双方共同约定。传输数据时先传送字符的低位,后传送字符的高位。奇偶校验位: 奇偶校验位仅占一位,用于进行奇校验或偶校验,奇偶检验位不是必须有的。如果是奇校验,需要保证传输的数据总共有奇数个逻辑高位;如果是偶校验,需要保证传输的数据总共有偶数个逻辑高位。
假设数据字节为 01010101(二进制形式),其1的个数是4(偶数)。
偶校验:
校验位应为0,使得总的1的个数(4 + 0)保持偶数。
奇校验:
校验位应为1,使得总的1的个数(4 + 1)变成奇数。
停止位: 停止位可以是是1位、1.5位或2位,可以由软件设定。它一定是逻辑1电平,标志着传输一个字符的结束。
二、STM32的串口
先来看框图
编号1区域是时钟和波特率
可以看到有两个时钟域,usart_pclk 时钟域和usart_ker_ck 内核时钟域。
usart_pclk 是外设总线时钟,需要访问 USART 寄存器时,该信号必须有效。usart_ker_ck 是USART 时钟源,独立于 usart_pclk,由 RCC 提供。因此,即使 usart_ker_ck 时钟停止,也可以连续对 USART 寄存器进行读/写操作。
__HAL_RCC_USART1_CLK_ENABLE() 串口时钟使能
波特率寄存器 USART_BRR通过设置该寄存器就可以配置不同波特率
USART 保护时间和预分频器寄存器 (USART_GTPR)
USART 预分频器寄存器 (USART_PRESC)
波特率,即每秒钟传输的码元个数,在二进制系统中(串口的数据帧就是二进制的形式),波特率与波特率的数值相等,所以可以把串口波特率理解为每秒钟传输的二进制位数。(假设波特率设置为 9600 波特,这意味着每秒钟传输 9600 个符号。如果每个符号等于一个比特,那么比特率也就是 9600 比特每秒(bps)。在这种情况下,波特率的数值与比特率的数值相等,因为每个符号传输一个比特,没有其他编码方式。)
再来看编号2 是收发数据
有两个寄存器两个fifo
USART 双向通信需要的两个引脚:
TX:发送数据输出引脚。
RX:接收数据输入引脚。
USART_TDR 是 USART 发送数据寄存器,要发送什么数据,往这个寄存器里写即可,低 9位有效。如下图所示
USART_RDR 是 USART 接收数据寄存器,要接收什么数据,读这个寄存器里写即可,低 9位有效。
从上面两张图可以看出,USART_TDR和RDR 虽然是一个 32 位寄存器,但是只用了低 9 位(DR[8:0]),其他都是保留,TDR[8:0]为串口数据,具体多少位,由M[1:0]决定。
当我们需要发送数据的时候,往 USART_TDR 寄存器写入你想要发送的数据,就可以通过串口发送出去了。而当有串口数据接收到,需要读取出来的时候,我们则必须读取 USART_RDR寄存器,USART_RDR 寄存器使用与 USART_TDR 是完全一样的,只是一个用来接收,一个用来发送。
当使能校验位(USART_CR1 中 PCE 位被置位)进行发送时,写到 MSB 的值(根据数据的长度不同,MSB 是第 7 位或者第 8 位)会被后来的校验位取代。
当使能校验位进行接收时,读到的 MSB 位是接收到的校验位。)
这就是有时候大家使用串口助手的时候不小心点到了奇偶校验数据会乱码的原因。
USART_TDR和USART_RDR的低9位是否有效,通过USART 控制寄存器1(USART_CR1)的 M 位(M0:位 12,M1:位 28)设置:
7 位字符长度:M[1:0] =“10”
8 位字符长度:M[1:0] =“00”
9 位字符长度:M[1:0] =“01”
基本都是使用 8 位数据字长。这些在数据手册中其实都有写
再来看编号3控制寄存器
通过控制寄存器控制 USART 数据的发送、数据接收、各种通信模式的设置、中断、DMA 模式还有唤醒单元等
STM32H7的每个串口都有 3 个控制寄存器 USART_CR1~3,串口的很多配置都是通过这3 个寄存器来设置的。USART_CR1 寄存器如图所示:
M[1:0]位(位 28 和 12),用于设置字长,我们一般设置为:00 表示 1 个起始位,8 个数据位,n 个停止位(n 的个数,由 USART_CR2 的[13:12]位控制)。OVER8 为过采样模式设置位,我们一般设置位 0,即 16 倍过采样已获得更好的容错性;UE 为串口使能位,通过该位置 1,以使能串口;PCE 为校验使能位,设置为 0,则禁止校验,否则使能校验;PS 为校验位选择位,设置为 0 则为偶校验,否则为奇校验;TXEIE 为发送缓冲区空中断使能位,设置该位为 1,当 USART_ISR 中的 TXE 位为 1时,将产生串口中断;TCIE 为发送完成中断使能位,设置该位为 1,当 USART_ISR 中的 TC 位为 1 时,将产生串口中断;RXNEIE 为接收缓冲区非空中断使能,设置该位为 1,当 USART_ISR 中的 ORE 或者RXNE 位为 1 时,将产生串口中断;TE 为发送使能位,设置为 1,将开启串口的发送功能;RE为接收使能位,用法同 TE。
这些在数据手册中都有提到
状态寄存器 USART_ISR
RXNE(读数据寄存器非空),当该位被置 1 的时候,就是提示已经有数据被接收到了,并且可以读出来了。这时候我们要做的就是尽快去读取USART_RDR,通过读 USART_RDR 可以将该位清零,也可以向该位写 0,直接清除。
TC(发送完成),当该位被置位的时候,表示 USART_TDR 内的数据已经被发送完成了。
如果设置了这个位的中断,则会产生中断。该位也有两种清零方式:
1)读 USART_ISR,写 USART_TDR。
2)向 ICR 寄存器的 TCCF 位写 1。
再来看编号4 DMA 和中断功能
USART 支持 DMA 传输,可以实现高速数据传输
在 USART 通信过程中,中断可由不同事件生成,同时支持 USART 模块生成唤醒中断。常用的中断比如:发送数据寄存器为空、发送 FIFO 未满、发送完成、接收 FIFO 非空、接收 FIFO 已满等。关于串口DMA可以看后面的文章。
最后看一下编号5USART 信号引脚
直接看数据手册中的描述即可,这些在232和485的文章会具体讲到
三、什么是数据通信
数据通信的方式一共有两种,串行通信和并行通信
串行通信的基本特征是数据逐位顺序依次传输,优点是传输线少成本低,抗干扰能力强可用于远距离传输,缺点就是传输速率低。而并行通信是数据各位可以通过多条线同时传输,优点是传输速率高,缺点就是线多成本就高了,抗干扰能力差因而适用于短距离、高速率的通信。
数据传输方向一共有三种 单工 半双工 全双工
单工是指数据传输仅能沿一个方向,不能实现反方向传输。
半双工是指数据传输可以沿着两个方向,但是需要分时进行。
全双工是指数据可以同时进行双向传输。
这里注意全双工和半双工通信的区别:半双工通信是共用一条线路实现双向通信,而全双工是利用两条线路,一条用于发送数据,另一条用于接收数据。
数据同步方式有两种 同步通信和异步通信
同步通信要求通信双方共用同一时钟信号,在总线上保持统一的时序和周期完成信息传输。
优点:可以实现高速率、大容量的数据传输,以及点对多点传输。缺点:要求发送时钟和接收时钟保持严格同步,收发双方时钟允许的误差较小,同时硬件复杂。
异步通信不需要时钟信号,而是在数据信号中加入开始位和停止位等一些同步信号,以便使接收端能够正确地将每一个字符接收下来,某些通信中还需要双方约定传输速率。优点:没有时钟信号硬件简单,双方时钟可允许一定误差。缺点:通信速率较低,只适用点对点传输。
通信速率
在数字通信系统中,通信速率(传输速率)指数据在信道中传输的速度,它分为两种:传信率和传码率。
传信率:每秒钟传输的信息量,即每秒钟传输的二进制位数,单位为 bit/s(即比特每秒),因而又称为比特率。
传码率:每秒钟传输的码元个数,单位为 Baud(即波特每秒),因而又称为波特率。
比特率和波特率这两个概念常常被混淆。比特率很好理解,我们来看看波特率,波特率被传输的是码元,码元是信号被调制后的概念,每个码元都可以表示一定 bit 的数据信息量。举个例子,在 TTL 电平标准的通信中,用 0V 表示逻辑 0,5V 表示逻辑 1,这时候这个码元就可以表示两种状态。如果电平信号 0V、2V、4V 和 6V 分别表示二进制数 00、01、10、11,
这时候每一个码元就可以表示四种状态。
由上述可以看出,码元携带一定的比特信息,所以比特率和波特率也是有一定的关系的。
比特率 = 波特率 * log2M
举个例子:波特率为 100 Baud,即每秒传输 100 个码元,如果码元采用十六进制编码(即M=16,代入上述式子),那么这时候的比特率就是 400 bit/s。如果码元采用二进制编码(即 M=2,代入上述式子),那么这时候的比特率就是 100 bit/s。(这个时候再来回顾一下前面讲的波特率就很明白了,采用二进制的时候,波特率和比特率数值上相等。)