STM32 学习笔记 串口

简介

计算机通信的概念

​ 将计算机技术和通信技术相结合,完成计算机与外部设备或计算机与计算机之间的信息交换。按照数据传输方式的不同,可以分为串行通信和并行通信两类

  • 串行通信:数据逐位传输

  • 并行通信:多位数据同时传输

并行通信的特点

多位数据同时传输,传输控制简单,传输速度快,但是在长距离传输时硬件成本较高。

image-20230107185616094

串行通信的特点

数据逐位传输,传输线少,长距离传输时成本低,但数据的传输控制较复杂。按照实现数据同步的方式,可以分为同步串行和异步串行两种。

image-20230107185701153

同步串行通信的特点

数据传输以数据块(一组字符)为单位,在一个数据块内,字符与字符间无间隔,收发双方依靠独立的时钟线进行信号的同步.适用于大批量的数据传输。

image-20230107190042897

异步串行通信的特点

数据传输以单个字符为单位,字符和字符之间的间隙任意,字符内部每一位持续的时间相同。收发双方没有专门的时钟信号,而是依靠事先约定的字符格式和通信速率来完成通信。

image-20230107190136387

异步串行通信的字符格式

常用字符格式:1位起始位 8位数据位 无奇偶校验 1位停止位

image-20230107190213226
异步串行通信的通信速率
波特率

​ 每秒钟传送二进制数码的位数,以bit/s(bps)为单位。

  • 常用的波特率有:9600、19200、38400、57600和115200;
  • 波特率为115200,表示每秒传输115200位,且每一位数据在数据线上持续时间为Tbit = 1/115200 ≈ 8.68us。

异步串行通信的数据接收过程

  1. 接收过程由起始位的下降沿启动;
  2. 接收端等待8个时钟周期,以便建立一个接近比特周期中间的采样点;
  3. 接收端等待16个时钟周期,使其进入第一个数据位周期的中点;
  4. 第一个数据位被采样并存储在接收寄存器中;
  5. 串口模块在采样第二个数据位之前等待另外16个时钟周期;
  6. 重复此过程,直到所有数据位都被采样和存储;
  7. 由停止位的上升沿使数据线返回到空闲状态。

三种常用的错误校验方式

奇偶校验

​ 奇校验表示数据中“1”的个数与校验位“1”的个数之和为奇数;偶校验表示数据中“1”的个数与校验位“1”的个数之和为偶数。

代码和校验

​ 发送方将所发数据块求和,产生一个字节的校验字符附加到数据块末尾。接收方采用同样方式进行检测。

循环冗余校验

​ 通过某种数学运算实现有效信息与校验位之间的循环校验,常用于磁盘信息的传输、存储区的完整性校验等。

STM32串口通信

image-20230107191214905

串口收发单元主要利用数据寄存器DR,发送引脚TX,接收引脚RX,以及三个通信状态位TXE、TC和RXNE来完成数据的接收和发送。

STM32H750VBT6的串口引脚

串口号 RX TX
USART1 PB15 PB14
USART2 PA3 PA2
USART3 PB11 PB10
USART6 PC7 PC6
UART4 PA1 PA0
UART5 PB12 PB13
UART7 PE7 PE8
UART8 PE0 PE1

串口初始化数据类型

image-20230107192804209

STM32H750 微控制器 HAL 库中常用的串口函数:

HAL_UART_Init():初始化串口设备。

image-20230107192942341

HAL_UART_Transmit():向串口发送数据。

image-20230107193017730

HAL_UART_Receive():从串口接收数据。

image-20230107193037943

HAL_UART_Transmit_IT():启用中断方式向串口发送数据。

image-20230107193110573

HAL_UART_Receive_IT():启用中断方式从串口接收数据。

image-20230107193131370

HAL_UART_IRQHandle: r串口中断通用处理函数

image-20230107193211185

HAL_UART_TxCpltCallback: 串口发送中断回调函数

image-20230107193242696

HAL_UART_RxCpltCallback: 串口接收中断回调函数

image-20230107193327081

__HAL_UART_ENABLE_IT: 串口中断使能函数

image-20230107193610203

__HAL_UART_GET_FLAG: 串口中断标志查询函数

image-20230107193553138

__HAL_UART_CLEAR_IDLEFLAG : 空闲中断标志清除函数

image-20230107193532379

USART_RX_STA 状态标记变量

从零开始,串口中断接收到一个数据(一个字节)自增1,当数据读取全部OK时候,(也就是回车换行符),那么USART_RX_STA的最高位置1 表示串口数据全部接收完毕,然后就可以在main函数里处理数据.

uint16_t USART_RX_STA

image-20230107194302211

任务1:非中断发送接收

要求: 从PC上发送5个字符到开发板,开发板收到后将字符原样发回到PC。

配置串口

使用USART2:

mode为异步模式,无硬件流控

设置通信参数: 波特率115200 8位数据位 无奇偶校验 1位停止位 使能接收和发送 16倍过采样

image-20230107195129799

代码

1
2
3
4
//接收数组定义
/* USER CODE BEGIN PM */
uint8_t Buf[10] ;
/* USER CODE END PM */
1
2
3
4
5
6
7
8
9
10
while (1)
{
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
if(HAL_UART_Receive(&huart2,Buf,5,0xffff) == HAL_OK){ // 接收数据
HAL_UART_Transmit(&huart2,Buf,5,0xffff);//原样发回
}
}
/* USER CODE END 3 */

程序效果

image-20230107210143947

任务2:中断方式发送接收

其他设置和上面一样

需要打开串口中断

image-20230107211624630

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
//定义接收区的大小 使用宏定义方便后续更改

/* USER CODE BEGIN PD */
#define BuffSize 7 //接受区大小
/* USER CODE END PD */


//变量声明
/* USER CODE BEGIN PM */
uint8_t Buf[BuffSize] ; //接收区
uint8_t Rx_Flag = 0; // 接收状态定义
/* USER CODE END PM */

// 初始化
/* USER CODE BEGIN 2 */
HAL_UART_Transmit(&huart2,(uint8_t*)"Hello word\r\n",sizeof ("Hello word\r\n"),0xffff);//单片机上电初始化 输出Helo word

HAL_UART_Receive_IT(&huart2,(uint8_t*)Buf,BuffSize);//使能串口接收中断
/* USER CODE END 2 */


//主函数
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
if(Rx_Flag == 1){
Rx_Flag =0;
HAL_UART_Receive_IT(&huart2,(uint8_t*)"Input data:\r\n",sizeof ("Input data:\r\n"));
HAL_UART_Transmit_IT(&huart2,Buf,BuffSize);

}
}
/* USER CODE END 3 */
}


//接收回调函数
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
if(huart->Instance == USART2){
Rx_Flag = 1;
HAL_UART_Receive_IT(&huart2,Buf,BuffSize);
}
}
/* USER CODE END 4 */