目录
概述
1 认识STM32F4XX的USART
1.1 USART 功能说明
1.2 USART的中断
1.3 USART 模式配置
1.4 USART的寄存器
2 使用STM32CubeMX 生成工程
2.1 配置参数
2.2 生成工程代码
3 实现软件功能
3.1 软件功能介绍
3.2 认识USART Hal库
3.2.1 初始化函数组
3.2.2 发送/接收函数组
3.2.3 中断和callback函数组
4 实现串口发送和接收功能接口
4.1 发送函数
4.2 接收函数
4.3 实现printf打印功能
4.4 完整程序
5 测试
5.1 测试代码功能介绍
5.2 测试代码实现
5.3 测试发送和接收功能
5.3.1 测试发送功能
5.3.2 测试接收数据功能
源代码下载地址:stm32f4xxx-USART串口中断收发例程资源-CSDN文库
HAL 库版本: STM32Cube_FW_F4_V1.27.1
概述
本文主要介绍STM32F4XX 通用同步异步收发器 (USART) 的相关知识,详细介绍了USART的特征,寄存器组。还介绍如何使用STM32CubeMX配置USART的相关的参数,并生成项目文件。还使用Hal库函数实现USART1的发送和接收功能,其中接收功能使用中断来实现的。
1 认识STM32F4XX的USART
通用同步异步收发器 (USART) 能够灵活地与外部设备进行全双工数据交换,满足外部设备对工业标准 NRZ 异步串行数据格式的要求。 USART 通过小数波特率发生器提供了多种波特率。它支持同步单向通信和半双工单线通信;还支持 LIN( 局域互连网络)、智能卡协议与 IrDA(红外线数据协会) SIR ENDEC 规范,以及调制解调器操作 (CTS/RTS)。而且,它还支持多处理器通信。通过配置多个缓冲区使用 DMA 可实现高速数据通信。
1.1 USART 功能说明
接口通过三个引脚从外部连接到其它设备。任何 USART 双向通信均需要至少两个引脚:接收数据输入引脚 (RX) 和发送数据引脚输出 (TX):
RX:接收数据输入引脚就是串行数据输入引脚。过采样技术可区分有效输入数据和噪声,从而用于恢复数据。
TX: 发送数据输出引脚。如果关闭发送器,该输出引脚模式由其 I/O 端口配置决定。如果使能了发送器但没有待发送的数据,则 TX 引脚处于高电平。在单线和智能卡模式下,该 I/O用于发送和接收数据( USART 电平下,随后在 SW_RX 上接收数据)。
正常 USART 模式下,通过这些引脚以帧的形式发送和接收串行数据:
● 发送或接收前保持空闲线路
● 起始位
● 数据(字长 8 位或 9 位),最低有效位在前
● 用于指示帧传输已完成的 0.5 个、 1 个、 1.5 个、 2 个停止位
● 该接口使用小数波特率发生器 - 带 12 位尾数和 4 位小数
● 状态寄存器 (USART_SR)
● 数据寄存器 (USART_DR)
● 波特率寄存器 (USART_BRR) - 12 位尾数和 4 位小数。
● 智能卡模式下的保护时间寄存器 (USART_GTPR)
1.2 USART的中断
发送期间:发送完成、清除以发送或发送数据寄存器为空中断。 接收期间:空闲线路检测、上溢错误、接收数据寄存器不为空、奇偶校验错误、 LIN 断路检测、噪声标志(仅限多缓冲区通信)和帧错误(仅限多缓冲区通信)。
1.3 USART 模式配置
1.4 USART的寄存器
这是一张非常完美的图,介绍整个USART的工作原理,以及各个寄存器的功能。了解这张图,就会对STM32的USART模块有一个很深刻的认识。
和USART相关的寄存器的列表,具体每个寄存器表示什么意思,参考文档: STM32F40xxx、STM32F41xxx、STM32F42xxx、STM32F43xxx参考手册(中文).pdf
2 使用STM32CubeMX 生成工程
2.1 配置参数
1)选择串口工作模式
2)Parameter Settings
3)NVIC Settings
2.2 生成工程代码
选择合适的IDE和Hal库,然后点击GENERATE CODE,生成项目文件。打开工程可以看见,和硬件相关的代码STM32CubeMX 已经生成,且这些函数已经在main()函数中初始化,所以user只需编写和应用相关的代码。
3 实现软件功能
3.1 软件功能介绍
1)实现串口发送字符串功能
2)实现中断接收字符串功能
3.2 认识USART Hal库
3.2.1 初始化函数组
这部分函数会在STM32CubeMX自动生成代码时,自动调用。
3.2.2 发送/接收函数组
3.2.3 中断和callback函数组
4 实现串口发送和接收功能接口
本程序使用UART0来实现串口的发送和接收功能。
4.1 发送函数
参数介绍:
1)huart: 串口配置参数指针
2)databuff: 发送数据的存储buff
3) datalen : 发送数据的字节长度
串口配置参数指针位置:
4.2 接收函数
这部分函数在stm32f4_drv_uart.c文件中实现
接收参数采用中断方式实现,Hal库的中断程序实现和很早以前ST提供的drviver的实现方式有很大的不同,先看代码:
使用Hal库实现接收数据功能,有如下3个步骤:
step-1: 代码18~19行, 定义接收数据buff,具体数据长度,可根据实现项目特性确定
step-2: 代码21~24行,调用HAL_UART_Receive_IT,实现数据接收,这个函数必须被连续执行,才能使中断程序不间断接收数据。
step-3: 代码26~32行,重新HAL_UART_RxCpltCallback函数,该函数在收到step-1传入的接收数据长度个数据之后,会进入该函数。其作用是,实现数据处理逻辑。
4.3 实现printf打印功能
在函数中添加如下代码:
代码介绍
222-行: 使用USART1接口,传递一个数据,超时时间为1000ms
注意:
使用printf功能时,必须在头文件中包含:stdio.h
#include <stdio.h>
4.4 完整程序
/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name : stm32f4_drv_uart.c
* Description : Code for board uart driver
******************************************************************************
* @attention
*
* Copyright (c) mingfei.tang
* All rights reserved.
*
******************************************************************************
*/
/* USER CODE END Header */
#include "can.h"
#include "stm32f4_drv_uart.h"
static uint8 recevBuff[10];
static const uint8 RECEV_LEN = sizeof(recevBuff);
void UART_Drv_Receive( UART_HandleTypeDef *huart)
{
HAL_UART_Receive_IT( huart, recevBuff, RECEV_LEN);
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if( huart->Instance == USART1)
{
printf(" %s ", recevBuff);
}
}
void UART_Drv_SendString(UART_HandleTypeDef *huart, uint8 *databuff, uint8 datalen)
{
HAL_UART_Transmit( huart, databuff , datalen, 1000 );
}
5 测试
5.1 测试代码功能介绍
1)使用UART_Drv_SendString发送字符串
2)使用printf发送字符串
3)使用中断函数接收程序
5.2 测试代码实现
源代码
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
// UART RECEIVE
UART_Drv_SendString(&huart1, "this is a test!\r\n", sizeof("this is a test!\r\n"));
printf("CAN bus test example: \r\n " ); //使用printf打印log
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
UART_Drv_Receive( &huart1 ); //触发接收中断函数
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
5.3 测试发送和接收功能
5.3.1 测试发送功能
下载程序到板卡,将USART1对应的串口端和PC之间,使用串口线连接起来,打开串口工具,重新上电或者复位板卡可以看见:
5.3.2 测试接收数据功能
在接收函数中,定义的接收数据缓冲buff的长度为10,所以,当中断程序接收到10个数据之后,就会调用HAL_UART_RxCpltCallback函数.
在HAL_UART_RxCpltCallback函数中,会将接收到的数据通过printf打印到终端:
运行程序后,使用串口调试助手发送数据: