【STM32】串口(异步通信部分)

经典的串口接口硬件说实话在现在的电脑上已经很难见到了,而是被USB这种通用的串行接口替代了,哪怕外部设备要以串口连接到电脑,都需要进行各种硬件转换。但不得不说,在工业领域,串口还是一个非常常用的数据传输方式。

大部分图片来源:正点原子HAL库课程

目录

[1 通信的基本知识](#1 通信的基本知识)

[1.1 同步/异步通信](#1.1 同步/异步通信)

[1.2 比特率和波特率](#1.2 比特率和波特率)

[2 串口电平与连接](#2 串口电平与连接)

[2.1 RS232电平](#2.1 RS232电平)

[2.2 CMOS电平(STM32)](#2.2 CMOS电平(STM32))

[2.3 TTL电平(51)](#2.3 TTL电平(51))

[2.4 连接方式](#2.4 连接方式)

[3 U(S)ART](#3 U(S)ART)

[3.1 简介](#3.1 简介)

[3.2 查看芯片U(S)ART数量](#3.2 查看芯片U(S)ART数量)

[3.3 查看U(S)ART对应引脚](#3.3 查看U(S)ART对应引脚)

[3.4 波特率计算公式](#3.4 波特率计算公式)

[3.5 使用寄存器设置波特率的示例](#3.5 使用寄存器设置波特率的示例)

[3.6 HAL库异步通信配置](#3.6 HAL库异步通信配置)

[3.7 详细的解析](#3.7 详细的解析)

[3.8 相关的HAL库文件(可以去这里找用到的函数和宏定义)](#3.8 相关的HAL库文件(可以去这里找用到的函数和宏定义))


1 通信的基本知识

1.1 同步/异步通信

  • 同步通信: 共用同一时钟信号;
  • 异步通信: 没有时钟信号,通过在数据信号中 加入起始位和停止位等同步信号。

1.2 比特率和波特率

**比特率:**每秒钟传送的比特数,单位bit/s

**波特率:**每秒钟传送的码元数,单位Baud

比特率 = 波特率 * log2 M,M表示每个码元承载的信息量(这里M可以直接理解为信息调制后的的进制数)

二进制系统中,波特率数值上等于比特率(我的理解是要是一次性可以发送的数据不是1位,那么波特率就不等于比特率了)。


2 串口电平与连接

2.1 RS232电平

逻辑1:-15 ~ -3V

逻辑0:+3 ~ +15V

2.2 CMOS电平(STM32)

逻辑1:3.3V

逻辑0:0V

2.3 TTL电平(51)

逻辑1:5V

逻辑0:0V

2.4 连接方式

  • 232串口两设备连接:
  • STM32与电脑通信原理:

3 U(S)ART

3.1 简介

  • 都能全双工异步通信;
  • USART多了同步通信功能,但平时用它也比较少用它的同步功能;

3.2 查看芯片U(S)ART数量

《ST MCU选型手册》

3.3 查看U(S)ART对应引脚

芯片数据手册,如《STM32F103ZET6(中文版)》- 引脚定义

3.4 波特率计算公式

其中是串口的时钟,如:USART1的时钟是PCLK2,其他串口都是PCLK1。

注意⚠️:

这个式子其实不是为了计算波特率,而是为了计算USARTDIV的数值,其包括整数部分和小数部分,存储于USART_BRR寄存器中,是为了配置USART发送器时钟的。

3.5 使用寄存器设置波特率的示例

其中,+0.5是为了让其四舍五入,否则因为强制类型转换,小数部分直接会被忽略。

简化计算过程后,通用过程为:

3.6 HAL库异步通信配置

其中根据四步法的逻辑,可以分为:

1. 初始化

(1) 串口参数设置:HAL_UART_Init();

(2) 时钟设置:重写HAL_UART_MspInit(),在其中开启GPIO及UART的时钟;

(3) IO设置:重写HAL_UART_MspInit()中设置GPIO的配置;

(4) 中断设置:重写HAL_UART_MspInit()中使能中断,并设置中断优先级,使用HAL_UART_Receive_IT()函数开启中断,可以理解为开启串口阻塞(实际上并不阻塞);

**2. 定义读函数:**无

**3. 定义写函数:**无

4. 编写中断服务函数:

(1) 重写UARTx_IRQHandler()函数,调用UART的串口公用数据处理函数;

(2) 重写接收完毕的回调函数HAL_UART_RxCpltCallback(),实现自定义的接收完成后动作,并在最后重新调用HAL_UART_Receive_IT()开启串口中断,因为接收完毕后串口中断就用完了(对,一次性的)。

3.7 详细的解析

其中根据四步法的逻辑:

1. 初始化

(1) 串口参数设置:

(2) 时钟设置:

(3) IO设置:其中串口的上下拉状态由芯片串口通信的电平时序图来决定,如下:

由于图中空闲时为高电平,因此就是要设置上拉。

(4) 中断设置:**注意注意⚠️!**HAL_UART_Receive_IT()启用串口不可以写在HAL_UART_MspInit()函数内,因为其执行的条件是串口的状态是Ready,而只有HAL_UART_Init()执行完毕后,串口状态才会从Reset改为Ready。也就是说在HAL_UART_Init函数内部,在执行完HAL_UART_MspInit后,还有一些内容要执行,因此写在HAL_UART_MspInit函数内的HAL_UART_Receive_IT事实上是无法得到执行的。

**2. 定义读函数:**无

**3. 定义写函数:**无

4. 编写中断服务函数:

(1) 中断服务函数中调用的HAL库公共数据处理函数可以将中断的标志位清空,因此在执行完毕后才需要重新调用HAL_UART_Receive_IT()开启阻塞

小思考:在GPIO中断中无需手动开启可能是因为在GPIO配置中就配置了

(2) 在接收完毕回调函数、串口中断服务函数等场合,应首先通过串口外设的句柄对接收的信号进行来源判断,因为有可能多个串口都开启了,但其各自的反应需要定义成不同的逻辑。

  • 注意事项⚠️

在正点原子的相关教程中,在使用HAL_UART_Transmit函数发送串口数据后,会利用__HAL_UART_GET_FLAG函数读取SR寄存器的TX位配合while循环进行阻塞以保证信息的发送完毕,但事实上在HAL_UART_Transmit函数中已有类似的机制,因此是不需要进行手动阻塞的。

3.8 相关的HAL库文件(可以去这里找用到的函数和宏定义)

stm32f1xx_hal_uart.c

相关推荐
ZLG_zhiyuan27 分钟前
灵活连接,无限可能—探索EtherCAT的拓扑艺术
嵌入式硬件
yyqzjw31 分钟前
【STM32】esp8266连接wifi
stm32·单片机·嵌入式硬件
牧码岛3 小时前
物联网之ESP32配网方式、蓝牙、WiFi
嵌入式硬件·物联网·web前端
Q8343158193 小时前
海思SD3403(21AP10, 108DC2910 )4K60 的 ISP 图像处理能力,4Tops INT8算力
linux·图像处理·人工智能·嵌入式硬件·视觉检测·视频编解码
钟剑锋-JeffChong4 小时前
stm32之硬件SPI读写W25Q64存储器应用案例
stm32·单片机·嵌入式硬件·嵌入式开发·spi通信·w25q64存储器
清风徐来Groot4 小时前
STM32L051K8U6-HAL-串口中断控制灯闪烁速度
stm32·单片机·嵌入式硬件
LN花开富贵6 小时前
单片机中为什么要使用5v转3.3v,不直接使用3.3V电压
笔记·单片机·嵌入式硬件·学习·物联网工程
Abaaba+6 小时前
【STM32】VOFA+上位机 PID调参
stm32·单片机·嵌入式硬件
兔帮大人6 小时前
点亮第一盏LED灯 3), LED灯GPIO引脚设置
单片机·嵌入式硬件
极客小张7 小时前
基于OpenCV与MQTT的停车场车牌识别系统:结合SQLite和Flask的设计流程
arm开发·人工智能·单片机·opencv·物联网·flask·毕业设计