STM32学习笔记四
STM32 学习笔记 串口
简介
计算机通信的概念
将计算机技术和通信技术相结合,完成计算机与外部设备或计算机与计算机之间的信息交换。按照数据传输方式的不同,可以分为串行通信和并行通信两类
串行通信:数据逐位传输
并行通信:多位数据同时传输
并行通信的特点
多位数据同时传输,传输控制简单,传输速度快,但是在长距离传输时硬件成本较高。
串行通信的特点
数据逐位传输,传输线少,长距离传输时成本低,但数据的传输控制较复杂。按照实现数据同步的方式,可以分为同步串行和异步串行两种。
同步串行通信的特点
数据传输以数据块(一组字符)为单位,在一个数据块内,字符与字符间无间隔,收发双方依靠独立的时钟线进行信号的同步.适用于大批量的数据传输。
异步串行通信的特点
数据传输以单个字符为单位,字符和字符之间的间隙任意,字符内部每一位持续的时间相同。收发双方没有专门的时钟信号,而是依靠事先约定的字符格式和通信速率来完成通信。
异步串行通信的字符格式
常用字符格式:1位起始位 8位数据位 无奇偶校验 1位停止位
异步串行通信的通信速率
波特率
每秒钟传送二进制数码的位数,以bit/s(bps)为单位。
- 常用的波特率有:9600、19200、38400、57600和115200;
- 波特率为115200,表示每秒传输115200位,且每一位数据在数据线上持续时间为Tbit = 1/115200 ≈ 8.68us。
异步串行通信的数据接收过程
- 接收过程由起始位的下降沿启动;
- 接收端等待8个时钟周期,以便建立一个接近比特周期中间的采样点;
- 接收端等待16个时钟周期,使其进入第一个数据位周期的中点;
- 第一个数据位被采样并存储在接收寄存器中;
- 串口模块在采样第二个数据位之前等待另外16个时钟周期;
- 重复此过程,直到所有数据位都被采样和存储;
- 由停止位的上升沿使数据线返回到空闲状态。
三种常用的错误校验方式
奇偶校验
奇校验表示数据中“1”的个数与校验位“1”的个数之和为奇数;偶校验表示数据中“1”的个数与校验位“1”的个数之和为偶数。
代码和校验
发送方将所发数据块求和,产生一个字节的校验字符附加到数据块末尾。接收方采用同样方式进行检测。
循环冗余校验
通过某种数学运算实现有效信息与校验位之间的循环校验,常用于磁盘信息的传输、存储区的完整性校验等。
STM32串口通信
串口收发单元主要利用数据寄存器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 |
串口初始化数据类型
STM32H750 微控制器 HAL 库中常用的串口函数:
HAL_UART_Init():初始化串口设备。
HAL_UART_Transmit():向串口发送数据。
HAL_UART_Receive():从串口接收数据。
HAL_UART_Transmit_IT():启用中断方式向串口发送数据。
HAL_UART_Receive_IT():启用中断方式从串口接收数据。
HAL_UART_IRQHandle: r串口中断通用处理函数
HAL_UART_TxCpltCallback: 串口发送中断回调函数
HAL_UART_RxCpltCallback: 串口接收中断回调函数
__HAL_UART_ENABLE_IT: 串口中断使能函数
__HAL_UART_GET_FLAG: 串口中断标志查询函数
__HAL_UART_CLEAR_IDLEFLAG : 空闲中断标志清除函数
USART_RX_STA 状态标记变量
从零开始,串口中断接收到一个数据(一个字节)自增1,当数据读取全部OK时候,(也就是回车换行符),那么USART_RX_STA的最高位置1 表示串口数据全部接收完毕,然后就可以在main函数里处理数据.
uint16_t USART_RX_STA
任务1:非中断发送接收
要求: 从PC上发送5个字符到开发板,开发板收到后将字符原样发回到PC。
配置串口
使用USART2:
mode为异步模式,无硬件流控
设置通信参数: 波特率115200 8位数据位 无奇偶校验 1位停止位 使能接收和发送 16倍过采样
代码
1 | //接收数组定义 |
1 | while (1) |
程序效果
任务2:中断方式发送接收
其他设置和上面一样
需要打开串口中断
代码
1 | //定义接收区的大小 使用宏定义方便后续更改 |