STM32 HAL 使用串口IDLE中断+DMA实现收发
cubeMX配置
mx配置如下(省去系统时钟,烧录口,工程属性配置)
注意:这里关闭 Force DMA channels Interrupts
然后按下面配置即可(TX和RX的DMA都是normal模式)
代码部分
uart_com.h:
#ifndef __UART_COM_H__
#define __UART_COM_H__
#include "main.h"
#include "string.h"
#include "stdarg.h"
#include "stdio.h"
#define DATA_SIZE 255
typedef struct UART_Data_T
{
UART_HandleTypeDef * phuart;
uint8_t pRxData[DATA_SIZE];
uint8_t rxData[DATA_SIZE];
uint16_t rxDataSize;
uint8_t txBuffer[DATA_SIZE];
}UART_Data_T;
extern UART_Data_T myUART1;
void myUART_Init(UART_HandleTypeDef * huart, UART_Data_T * myUART);
void myUART_send_DMA(UART_Data_T * myUART, uint8_t * buffer, uint16_t size);
void myUART_debug_printf(UART_Data_T * myUART, const char * format, ...);
static inline void myUART_copyData(UART_Data_T * myUART, uint16_t size);
static inline void myUART_resumeReceive(UART_Data_T * myUART);
#endif
uart_com.h:
#include "uart_com.h"
UART_Data_T myUART1;
void myUART_Init(UART_HandleTypeDef * huart, UART_Data_T * myUART)
{
myUART->phuart = huart;
HAL_UARTEx_ReceiveToIdle_DMA(huart, myUART->pRxData, sizeof(myUART->pRxData));
}
static inline void myUART_copyData(UART_Data_T * myUART, uint16_t size)
{
strcpy((char*)myUART->rxData, (char*)myUART->pRxData);
myUART->rxDataSize = size;
}
static inline void myUART_resumeReceive(UART_Data_T * myUART)
{
memset(myUART->pRxData, 0x00, sizeof(myUART->pRxData));
HAL_UARTEx_ReceiveToIdle_DMA(myUART->phuart, myUART->pRxData, sizeof(myUART->pRxData));
}
void myUART_send_DMA(UART_Data_T * myUART, uint8_t * buffer, uint16_t size)
{
while(HAL_DMA_GetState(myUART->phuart->hdmatx) != HAL_DMA_STATE_READY);
__HAL_DMA_DISABLE(myUART->phuart->hdmatx);
HAL_UART_Transmit_DMA(myUART->phuart, buffer, size);
}
void myUART_debug_printf(UART_Data_T * myUART, const char * format, ...)
{
uint16_t length = 0;
va_list args;
va_start(args, format);
length = vsnprintf((char*)myUART->txBuffer, sizeof(myUART->txBuffer), (char*)format, args);
myUART_send_DMA(myUART, myUART->txBuffer, length);
}
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if(huart->Instance==myUART1.phuart->Instance)
{
/*Deal with the data*/
myUART_copyData(&myUART1, Size);
//myUART_send_DMA(&myUART1, myUART1.rxData, myUART1.rxDataSize); // This sentence is used for testing.
//myUART_debug_printf(&myUART1, "%s", myUART1.rxData); // This sentence is used for testing.
/*Clear data and restart DMA receive*/
myUART_resumeReceive(&myUART1);
}
}
使用
以uart1为例,进行初始化:
myUART_Init(&huart1, &myUART1);
myUART_debug_printf(&myUART1, "Init OK!\n");
然后就可以在代码里调用发送函数了。
标签:DMA,HAL,UART,void,myUART,myUART1,串口,Data From: https://www.cnblogs.com/Asaka-QianXiang/p/17830635.html