目录
各函数的功能及使用方法
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 文件,里面都是配置所需功能的宏定义及串口相关的初始化函数和功能函数
配置的方法都·已经注释说明了,只需要启用需要使用的串口或者禁用不需要使用的串口即可
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.找到系统的串口初始化函数
2.在结束位置添加我们的串口初始化函数
我这是在函数内部调用,你们也可在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文件 打开
2.找到串口中断服务函数 在结束位置添加我们的中断服务函数
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.配置串口基本参数
2.开启串口DMA
3.打开串口中断
4.在NVIC中配置中断优先级
实际应用
void usart3(void)
{
/**************************************** 从这里添加串口3功能代码 ****************************************/
if ( (USART_RX_STA & ~(0x0001<<2)) != 0) //串口3接收到数据
{
USART_RX_STA &= ~(0x0001<<2); //串口3清标志位
if (hand((char *)u3NewBuffer, "QRcode")) //串口收到的数据是否包含 "QRcode"
{
destination=My_Atoi((char *)u3NewBuffer); //如果包含则执行这条代码
}
User_Printf(&huart1, "usart3:%s \n ", u3NewBuffer); //使用串口1发送串口3接收到的数据
memset(u3NewBuffer, '\0', strlen((char *)u3NewBuffer)); // 清除串口3缓存数据
}
}
源代码 "usart_dma.c"
/**
******************************************************************************
* @file usart_dma.c
* @brief This file provides code for the configuration
* of the USART_DMA instances.
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usart_dma.h"
#include <stdarg.h> // 标准头文件
#include <stdio.h>
#include <string.h>
uint16_t USART_RX_STA;//串口接收状态标记
#if USART_DMA1
unsigned char u1NewBuffer[USART1_REC_LEN]; //串口1接收缓存
#endif
#if USART_DMA2
unsigned char u2NewBuffer[USART2_REC_LEN]; //串口2接收缓存
#endif
#if USART_DMA3
unsigned char u3NewBuffer[USART3_REC_LEN]; //串口3接收缓存
#endif
#if USART_DMA4
unsigned char u4NewBuffer[USART4_REC_LEN]; //串口4接收缓存
#endif
#if USART_DMA5
unsigned char u5NewBuffer[USART5_REC_LEN]; //串口5接收缓存
#endif
void debug(char* p, ...)
{
char temp[64]; //格式化字符串缓存
/* 格式化数据 */
va_list ap;
va_start(ap, p);
vsprintf(temp, p, ap);
va_end(ap);
// 信息输出接口
#if PRINTF == 1 && USART_DMA1
HAL_UART_Transmit(&huart1, (uint8_t*)temp, strlen(temp), 200);
#endif
#if PRINTF == 2 && USART_DMA2
HAL_UART_Transmit(&huart2, (uint8_t*)temp, strlen(temp), 200);
#endif
#if PRINTF == 3 && USART_DMA3
HAL_UART_Transmit(&huart3, (uint8_t*)temp, strlen(temp), 200);
#endif
#if PRINTF == 4 && USART_DMA4
HAL_UART_Transmit(&huart4, (uint8_t*)temp, strlen(temp), 200);
#endif
#if PRINTF == 5 && USART_DMA5
HAL_UART_Transmit(&huart5, (uint8_t*)temp, strlen(temp), 200);
#endif
}
/******************************************************************************
*方法名称: void User_Printf(UART_HandleTypeDef *huart,char *p,...)
*功能: 使用指定的串口格式化输出
*参数: * huart :用来输出数据的串口句柄
* p, ...:需要输出的数据
*返回: 无
*说明: 无
*******************************************************************************/
void User_Printf(UART_HandleTypeDef* huart, char* p, ...)
{
char temp[64]; //格式化字符串缓存
/* 格式化数据 */
va_list ap;
va_start(ap, p);
vsprintf(temp, p, ap);
va_end(ap);
#if USART_DMA1
if (huart->Instance == USART1)
{
HAL_UART_Transmit(&huart1, (uint8_t*)temp, strlen(temp), 200); // 串口1格式化输出
}
#endif
#if USART_DMA2
if (huart->Instance == USART2)
{
HAL_UART_Transmit(&huart2, (uint8_t*)temp, strlen(temp), 200); // 串口2格式化输出
}
#endif
#if USART_DMA3
if (huart->Instance == USART3)
{
HAL_UART_Transmit(&huart3, (uint8_t*)temp, strlen(temp), 200); // 串口3格式化输出
}
#endif
#if USART_DMA4
if (huart->Instance == 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<<1); //串口2标志位置1 需手动清0 USART_RX_STA &= ~(0x0001 << 1);
}
#endif
#if USART_DMA3
if (huart->Instance == USART3)
{
USART_RX_STA |= (0x0001 << 2); //串口3标志位置1 需手动清0 USART_RX_STA &= ~(0x0001 << 2);
}
#endif
#if USART_DMA4
if (huart->Instance == USART4)
{
USART_RX_STA |= (0x0001 << 3); //串口4标志位置1 需手动清0 USART_RX_STA &= ~(0x0001 << 3);
}
#endif
#if USART_DMA5
if (huart->Instance == USART5)
{
USART_RX_STA |= (0x0001 << 4); //串口5标志位置1 需手动清0 USART_RX_STA &= ~(0x0001 << 4);
}
#endif
}
源代码 "usart_dma.h"
/**
******************************************************************************
* @file usart_dma.h
* @brief This file contains all the function prototypes for
* the usart_dma.c file
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USART_DMA_H__
#define __USART_DMA_H__
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/********************************* 配置所需要的功能 *********************************/
#define USART_DMA1 1 // 1: 启用串口1 0:禁用串口1
#define USART_DMA2 1 // 1: 启用串口2 0:禁用串口2
#define USART_DMA3 1 // 1: 启用串口3 0:禁用串口3
#define USART_DMA4 0 // 1: 启用串口4 0:禁用串口4
#define USART_DMA5 0 // 1: 启用串口5 0:禁用串口5
#define PRINTF 1 // 1: 启用串口1调试输出 2: 启用串口2调试输出 3: 启用串口3调试输出
// 4: 启用串口4调试输出 5: 启用串口5调试输出 其他:禁用串口调试输出
/********************************* 需要用到的函数 *********************************/
void debug(char* p, ...); //串口调试输出
void User_Printf(UART_HandleTypeDef *huart,char *p,...); //串口格式化输出
void User_USART_UART_Init(UART_HandleTypeDef huart); //串口DMA接收模式初始化函数 需在 MX_USARTX_UART_Init(void) 函数结束时调用
void User_UART_RxCpltCallback(UART_HandleTypeDef* huart); //串口中断回调函数 需在 USART1_IRQHandler() 函数结束时调用
unsigned char hand(char* rec_data,char *ptr); //校验字符串 rec_data 是否包含字符串 ptr 校验结果 1:包含 0:不包含
/**********************************************************************************/
extern uint16_t USART_RX_STA;//串口接收状态标记
/*
* USART_RX_STA & ~0x0001 != 0 串口1接收到数据 清状态标记 USART_RX_STA &= ~0x0001
* USART_RX_STA & ~(0x0001<<1) != 0 串口2接收到数据 清状态标记 USART_RX_STA &= ~(0x0001 << 1)
* USART_RX_STA & ~(0x0001<<2) != 0 串口3接收到数据 清状态标记 USART_RX_STA &= ~(0x0001 << 2)
* USART_RX_STA & ~(0x0001<<3) != 0 串口4接收到数据 清状态标记 USART_RX_STA &= ~(0x0001 << 3)
* USART_RX_STA & ~(0x0001<<4) != 0 串口5接收到数据 清状态标记 USART_RX_STA &= ~(0x0001 << 4)
*/
#if USART_DMA1
#define USART1_REC_LEN 200 //定义USART1最大接收字节数
extern unsigned char u1NewBuffer[USART1_REC_LEN]; //串口1接收缓存
extern UART_HandleTypeDef huart1;
#endif
#if USART_DMA2
#define USART2_REC_LEN 200 //定义USART2最大接收字节数
extern unsigned char u2NewBuffer[USART2_REC_LEN]; //串口2接收缓存
extern UART_HandleTypeDef huart2;
#endif
#if USART_DMA3
#define USART3_REC_LEN 200 //定义USART2最大接收字节数
extern unsigned char u3NewBuffer[USART3_REC_LEN]; //串口3接收缓存
extern UART_HandleTypeDef huart3;
#endif
#if USART_DMA4
#define USART4_REC_LEN 200 //定义USART2最大接收字节数
extern unsigned char u4NewBuffer[USART4_REC_LEN]; //串口4接收缓存
extern UART_HandleTypeDef huart4;
#endif
#if USART_DMA5
#define USART5_REC_LEN 200 //定义USART2最大接收字节数
extern unsigned char u5NewBuffer[USART5_REC_LEN]; //串口5接收缓存
extern UART_HandleTypeDef huart5;
#endif
#endif /* __USART_DMA_H__ */
觉得博主写的还不错的话 还请一键三连支持一下喔文章来源:https://www.toymoban.com/news/detail-703114.html
文章来源地址https://www.toymoban.com/news/detail-703114.html
到了这里,关于STM32串口通信——DMA中断 (简单配置即可直接使用)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!