目录
各函数的功能及使用方法
1.串口调试输出
2. 串口调试输出 接口设置
3. 串口格式化输出
4.用户串口DMA中断初始化函数
使用方法
1.找到系统的串口初始化函数
2.在结束位置添加我们的串口初始化函数
5.用户中断回调函数
使用方法
1.找到系统的中断服务.c文件 打开
2.找到串口中断服务函数 在结束位置添加我们的中断服务函数
6.校验字符串函数
CubeMx 串口配置
1.配置串口基本参数
2.开启串口DMA
3.打开串口中断
4.在NVIC中配置中断优先级编辑
实际应用
源代码 "usart_dma.c"
源代码 "usart_dma.h"
话不多说,直接上教程
文章末尾附源代码
这是 usart_dma.h 文件,里面都是配置所需功能的宏定义及串口相关的初始化函数和功能函数
![](https://img-blog.csdnimg.cn/de728782a2d84bf5afe6ac3da275cacc.png)
配置的方法都·已经注释说明了,只需要启用需要使用的串口或者禁用不需要使用的串口即可
usart_dma.c 文件不用管 只需要配置该头文件就能使用了
各函数的功能及使用方法
1.串口调试输出
void debug(char* p, ...); //串口调试输出
2. 串口调试输出 接口设置
#define PRINTF 1 // 1: 启用串口1调试输出 2: 启用串口2调试输出
// 3: 启用串口3调试输出 4: 启用串口4调试输出
// 5: 启用串口5调试输出 其他:禁用串口调试输出
3. 串口格式化输出
/******************************************************************************
*方法名称: void User_Printf(UART_HandleTypeDef *huart,char *p,...)
*功能: 使用指定的串口格式化输出
*参数: * huart :用来输出数据的串口句柄
* p, ...:需要输出的数据
*返回: 无
*说明: 无
*******************************************************************************/
void User_Printf(UART_HandleTypeDef *huart,char *p,...); //串口格式化输出
4.用户串口DMA中断初始化函数
/******************************************************************************
*方法名称: void User_USART_UART_Init(UART_HandleTypeDef huart);
*功能: 串口初始化输出
*参数: 串口对应的 huart 句柄
*返回: 无
*说明: 用户串口DMA接收模式初始化函数
需在系统串口初始化函数 MX_USARTx_UART_Init(void) 结束时调用
*******************************************************************************/
void User_USART_UART_Init(UART_HandleTypeDef huart);
// 用户 串口DMA接收模式初始化函数需在 系统初始化函数 MX_USARTX_UART_Init(void) 函数结束时调用
使用方法
1.找到系统的串口初始化函数
![](https://img-blog.csdnimg.cn/b3e98f10d02a4b159e32c714148b376b.png)
2.在结束位置添加我们的串口初始化函数
![](https://img-blog.csdnimg.cn/9fbfe03f791c4bb08c8b97f41e92b56c.png)
我这是在函数内部调用,你们也可在main函数中直接调用,只需保证在系统初始化函数后面就行
5.用户中断回调函数
/******************************************************************************
*方法名称: void User_UART_RxCpltCallback(UART_HandleTypeDef *huart)
*功能: 串口回调函数 重新开启串口DMA接收
*参数: *huart: 串口对应的 huart 句柄
*返回: 无
*说明: 用户串口中断回调函数
需在系统中断函数 USARTx_IRQHandler() 结束时调用
*******************************************************************************/
void User_UART_RxCpltCallback(UART_HandleTypeDef* huart);
//用户 串口中断回调函数 需在系统中断回调函数 USARTx_IRQHandler() 函数结束时调用
使用方法
1.找到系统的中断服务.c文件 打开
![](https://img-blog.csdnimg.cn/10854ed557124c1f8d0f0a36ce364996.png)
2.找到串口中断服务函数 在结束位置添加我们的中断服务函数
![](https://img-blog.csdnimg.cn/6fa39398226b436480e21d366737425d.png)
6.校验字符串函数
/******************************************************************************
*方法名称: unsigned char hand(char* rec_data,char *ptr)
*功能: 校验字符串 rec_data 是否包含字符串 ptr
*参数: rec_data :需要校验的字符串
ptr :需要包含的字符串
*返回: 校验结果 1:包含 0:不包含
*说明: 无
*******************************************************************************/
unsigned char hand(char* rec_data,char *ptr);
//校验字符串 rec_data 是否包含字符串 ptr 校验结果 1:包含 0:不包含
CubeMx 串口配置
1.配置串口基本参数
![](https://img-blog.csdnimg.cn/af4166fc8bc249da8a416f69c9479ecb.png)
2.开启串口DMA
![](https://img-blog.csdnimg.cn/c7c9b803a309465c95e4c37e38681c8f.png)
![](https://img-blog.csdnimg.cn/0228fb6d15b04e1f970d74b4cbe841d3.png)
![](https://img-blog.csdnimg.cn/f4b96e47725b487fab1af2efb8bfe5f4.png)
3.打开串口中断
![](https://img-blog.csdnimg.cn/92e6bd5247df4c18b439131666a5c5d2.png)
4.在NVIC中配置中断优先级
实际应用
void usart3(void)
{
/**************************************** 从这里添加串口3功能代码 ****************************************/
if ( (USART_RX_STA & ~(0x0001Instance == USART4)
{
HAL_UART_Transmit(&huart4, (uint8_t*)temp, strlen(temp), 200); // 串口4格式化输出
}
#endif
#if USART_DMA5
if (huart->Instance == USART5)
{
HAL_UART_Transmit(&huart5, (uint8_t*)temp, strlen(temp), 200); // 串口5格式化输出
}
#endif
}
/******************************************************************************
*方法名称: unsigned char hand(char* rec_data,char *ptr)
*功能: 校验字符串 rec_data 是否包含字符串 ptr
*参数: rec_data :需要校验的字符串
ptr :需要包含的字符串
*返回: 校验结果 1:包含 0:不包含
*说明: 无
*******************************************************************************/
unsigned char hand(char* rec_data, char* ptr)
{
if (strstr(rec_data, ptr) != NULL)
return 1;
else
return 0;
}
/******************************************************************************
*方法名称: void User_USART_UART_Init(UART_HandleTypeDef huart);
*功能: 串口初始化输出
*参数: 串口对应的 huart 句柄
*返回: 无
*说明: 串口DMA接收模式初始化函数
需在 MX_USARTx_UART_Init(void) 函数结束时调用
*******************************************************************************/
void User_USART_UART_Init(UART_HandleTypeDef huart)
{
#if USART_DMA1
if (huart.Instance == USART1)
{
HAL_UART_Transmit(&huart1, (uint8_t*)"\r\nUSART1 Open", 14, 10);
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
HAL_UART_Receive_DMA(&huart1, u1NewBuffer, sizeof(u1NewBuffer));
}
#endif
#if USART_DMA2
if (huart.Instance == USART2)
{
HAL_UART_Transmit(&huart2, (uint8_t*)"\r\nUSART2 Open", 14, 10);
__HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE);
HAL_UART_Receive_DMA(&huart2, u2NewBuffer, sizeof(u2NewBuffer));
}
#endif
#if USART_DMA3
if (huart.Instance == USART3)
{
HAL_UART_Transmit(&huart3, (uint8_t*)"\r\nUSART3 Open", 14, 10);
__HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);
HAL_UART_Receive_DMA(&huart3, u3NewBuffer, sizeof(u3NewBuffer));
}
#endif
#if USART_DMA4
if (huart.Instance == USART4)
{
HAL_UART_Transmit(&huart4, (uint8_t*)"\r\nUSART4 Open", 14, 10);
__HAL_UART_ENABLE_IT(&huart4, UART_IT_IDLE);
HAL_UART_Receive_DMA(&huart4, u4NewBuffer, sizeof(u4NewBuffer));
}
#endif
#if USART_DMA5
if (huart.Instance == USART5)
{
HAL_UART_Transmit(&huart5, (uint8_t*)"\r\nUSART5 Open", 14, 10);
__HAL_UART_ENABLE_IT(&huart5, UART_IT_IDLE);
HAL_UART_Receive_DMA(&huart5, u5NewBuffer, sizeof(u5NewBuffer));
}
#endif
}
/******************************************************************************
*方法名称: void User_UART_RxCpltCallback(UART_HandleTypeDef *huart)
*功能: 串口回调函数 重新开启串口DMA接收
*参数: *huart: 串口对应的 huart 句柄
*返回: 无
*说明: 串口中断回调函数
需在 USARTx_IRQHandler() 函数结束时调用
*******************************************************************************/
void User_UART_RxCpltCallback(UART_HandleTypeDef* huart)
{
int size;
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) != RESET) // 是否接收完一帧数据
{
__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_IDLE | UART_FLAG_RXNE); // 清帧中断标志 UART_FLAG_IDLE 清字节中断标志 UART_FLAG_RXNE
//读寄存器以清除标志
size = huart->Instance->DR; // 清串口数据寄存器
size = huart->Instance->SR; // 清串口状态寄存器
HAL_UART_DMAStop(huart); //停止DMA接收
size = huart->RxXferSize - __HAL_DMA_GET_COUNTER(huart->hdmarx); //计算接收数据帧长度
huart->RxXferCount = size; //存到串口接收结构体成员中
__HAL_UART_ENABLE_IT(huart, UART_IT_IDLE); //重新开启串口接收帧中断
#if USART_DMA1
if (huart->Instance == USART1)
{
HAL_UART_Receive_DMA(huart, u1NewBuffer, sizeof(u1NewBuffer)); //开启串口1DMA接收
}
#endif
#if USART_DMA2
if (huart->Instance == USART2)
{
HAL_UART_Receive_DMA(huart, u2NewBuffer, sizeof(u2NewBuffer)); //开启串口1DMA接收
}
#endif
#if USART_DMA3
if (huart->Instance == USART3)
{
HAL_UART_Receive_DMA(huart, u3NewBuffer, sizeof(u3NewBuffer)); //开启串口1DMA接收
}
#endif
#if USART_DMA4
if (huart->Instance == USART4)
{
HAL_UART_Receive_DMA(huart, u4NewBuffer, sizeof(u4NewBuffer)); //开启串口1DMA接收
}
#endif
#if USART_DMA5
if (huart->Instance == USART5)
{
HAL_UART_Receive_DMA(huart, u5NewBuffer, sizeof(u5NewBuffer)); //开启串口1DMA接收
}
#endif
HAL_UART_RxCpltCallback(huart); // 调用接收回调函数
}
}
/**
* @brief Rx Transfer completed callbacks.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval None
*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef* huart) // 接收回调函数
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
#if USART_DMA1
if (huart->Instance == USART1)
{
USART_RX_STA |= 0x0001; //串口1标志位置1 需手动清0 USART_RX_STA &= ~0x0001;
}
#endif
#if USART_DMA2
if (huart->Instance == USART2)
{
USART_RX_STA |= (0x0001 |