STM32CubeMx 串口通信(下)串口接收

工作环境:
STM32CubeMXv6
Keil5
串口调试助手
串口接收相对串口发送而言比较复杂,HAL_UART_Receive是阻塞式的发送,但是我们不可能让一块单片机一直进行监听,通常而言我们都会采用终端的方法完成串口接收。
Cube的基本配置和串口发送是一致的,但最后要添加终端的勾选。
首先打开左侧的下拉框Connectivity,点击USART1选项;

在打开的选单中点击Mode的下拉框,选中Asynchronous;

在下方的配置框中选中Parameter Settings进行配置:
Baud Rate:波特率
Word Length:字长
Parity: 奇偶校验
Stop Bits:停止位
Data Directon:数据方向
Over Sampling:超采样
Auto Baudrate: 自动波特率
TX Pin Active Level Inversion:输出引脚有效电平反转
RX Pin Active Level Inversion:输入引脚有效电平反转
Data Inversion:数据反转
TX and RX Pin Swapping:输出和输入引脚交换
DMA on RX Error:DMA接收错误
MSB First:MSB优先(大端优先)

再打开左侧的下拉框System,点击NVIC选项;

可以在Priority Group中选择中断优先级组

勾选USART1 global interrupt开启中断

设置完成后
点击Project Manager页面,输入工程名和工程位置,选择工具链和IDE为MDK-ARM,版本为5.27;

打开左侧Code Generater菜单勾选Generate peripheral initialization as a pair of'.c/.h'file per peripheral;

最后点击右上角的GENERATE CODE按钮后生成代码。
生成代码后打开工程文件夹,用Keil5打开工程。

为了使得我们的代码尽可能解耦合,所以我们在工程文件夹中新建一个user_uart.c和对应的user_uart.h文件,在这个.c文件中我们写入以下函数
/* Includes ------------------------------------------------------------------*/
#include "user_uart.h"
unsigned char UART1_Rx_Buf[Max_Rec_Long] = {0}; // 串口1存储接收数据
unsigned char UART1_Rx_flg = 0; // 串口1接收完成标志
unsigned int UART1_Rx_cnt = 0; // 串口1接受数据计数器
unsigned char UART1_temp[Rec_Long] = {0}; // 串口1接收数据缓存
/**
* 函数名称:串口中断回调函数
* 函数功能:调用回调函数的串口
* 形 参:串口名
* 返回值 :无
*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance==USART1)
{
UART1_Rx_Buf[UART1_Rx_cnt] = UART1_temp[0];
UART1_Rx_cnt++;
if(0x0a == UART1_temp[0])
{
UART1_Rx_flg = 1;
}
HAL_UART_Receive_IT(&huart1,(uint8_t *)UART1_temp,Rec_Long); // 重新开启串口接收中断
}
}
在对应头函数user_uart.h中写入以下函数
#ifndef __USER_UART_H
#define __USER_UART_H
#ifdef __cplusplus
extern "C" {
#endif
#define Rec_Long 1
#define Max_Rec_Long 64
extern unsigned char UART1_Rx_Buf[Max_Rec_Long];
extern unsigned char UART1_Rx_flg ;
extern unsigned int UART1_Rx_cnt ;
extern unsigned char UART1_temp[Rec_Long];
#ifdef __cplusplus
}
#endif
#endif
在主函数的include中加入include
#include "user_uart.h"
再在主循环的初始化阶段加入中断初始化
HAL_UART_Receive_IT(&huart1,(uint8_t *)UART1_temp,REC_LENGTH);
然后再在主循环里加入中断标志位检测
if(UART1_Rx_flg)
{
// 业务代码开始
// 业务代码结束
for(int i = 0; i < UART1_Rx_cnt; i++) // 清空接收数组
{
UART1_Rx_Buf[i] = 0;
}
UART1_Rx_cnt = 0; // 清空接收计数器
UART1_Rx_flg = 0; // 清空接收完成标志位
}
好了,现在我们就可以在main里调用接收到的数组了
参考资料:
STM32F7开发指南-HAL库版本_V1.1
HAL库教程6:串口数据接收 https://blog.csdn.net/geek_monkey/article/details/89165040