STM32 HAL 使用串口IDLE中断+DMA实现收发

1|0STM32 HAL 使用串口IDLE中断+DMA实现收发

1|1cubeMX配置

mx配置如下(省去系统时钟,烧录口,工程属性配置)

注意:这里关闭 Force DMA channels Interrupts

image

然后按下面配置即可(TX和RX的DMA都是normal模式)

image

image

1|2代码部分

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); } }

1|3使用

以uart1为例,进行初始化:

myUART_Init(&huart1, &myUART1); myUART_debug_printf(&myUART1, "Init OK!\n");

然后就可以在代码里调用发送函数了。


__EOF__

本文作者Asaka
本文链接https://www.cnblogs.com/Asaka-QianXiang/p/17830635.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Akasa  阅读(369)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示