[STM32 HAL]一种可能不错的DMA处理串口数据方案

1|0[STM32 HAL]一种可能不错的DMA处理数据方案

原文链接:https://blog.csdn.net/youmeichifan/article/details/51750435?spm=1001.2014.3001.5506

本文配置稍有不同,大体类似。

1|1MX配置

开启USART1,使能USART1全局中断,打开RX,TX的DMA通道,均为normal模式,内存地址自增,使能TX对应DMA的中断,RX不需要。

1|2代码部分

  • 在main.c里将MX_DMA的初始化放在MX_UART的初始化之前

usart.h:

/* USER CODE BEGIN Prototypes */ #define RECEIVELEN 1024 #define USART_DMA_SENDING 1//发鿁未完成 #define USART_DMA_SENDOVER 0//发鿁完房 typedef struct { uint8_t receive_flag:1; // 空闲接收标记 uint8_t dmaSend_flag:1; // 发鿁完成标访 uint16_t rx_len; // 接收长度 uint8_t usartDMA_rxBuf[RECEIVELEN]; // DMA接收缓存 }USART_RECEIVETYPE; extern USART_RECEIVETYPE usartType1; void __USART_Receive_IDLE(UART_HandleTypeDef *huart); void __USART_SendData_DMA(uint8_t *pdata, uint16_t Length); /* USER CODE END Prototypes */

usart.c:

/* USER CODE BEGIN 0 */ #include "string.h" #include "main.h" USART_RECEIVETYPE usartType1; /* USER CODE END 0 */
/* USER CODE BEGIN 1 */ void __USART_SendData_DMA(uint8_t *pdata, uint16_t Length) { while(usartType1.dmaSend_flag == USART_DMA_SENDING); usartType1.dmaSend_flag = USART_DMA_SENDING; HAL_UART_Transmit_DMA(&huart1, pdata, Length); } //DMA发鿁完成中断回调函敿 void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { //HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, 1); __HAL_DMA_DISABLE(huart->hdmatx); usartType1.dmaSend_flag = USART_DMA_SENDOVER; //HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, 0); } //串口接收空闲中断 void __USART_Receive_IDLE(UART_HandleTypeDef *huart) { uint32_t temp; if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET)) { __HAL_UART_CLEAR_IDLEFLAG(&huart1); HAL_UART_DMAStop(huart); temp = huart1.hdmarx->Instance->NDTR; usartType1.rx_len = RECEIVELEN - temp; usartType1.receive_flag=1; HAL_UART_Receive_DMA(&huart1,usartType1.usartDMA_rxBuf,RECEIVELEN); } } /* USER CODE END 1 */

stm32f4xxit.c:

/** * @brief This function handles USART1 global interrupt. */ void USART1_IRQHandler(void) { /* USER CODE BEGIN USART1_IRQn 0 */ __USART_Receive_IDLE(&huart1); // 这段代码是自己加进去的 /* USER CODE END USART1_IRQn 0 */ HAL_UART_IRQHandler(&huart1); /* USER CODE BEGIN USART1_IRQn 1 */ /* USER CODE END USART1_IRQn 1 */ }

main.c:

/* USER CODE BEGIN PV */ char rxStr[256]; char drawBuffer1[256]; char drawBuffer2[256]; char drawBuffer3[256]; /* USER CODE END PV */ /* USER CODE BEGIN 2 */ HAL_UART_Receive_DMA(&huart1, usartType1.usartDMA_rxBuf, RECEIVELEN); __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); /* USER CODE END 2 */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ if(usartType1.receive_flag) { usartType1.receive_flag = 0; //printf("%s\r\n", (char*)usartType1.usartDMA_rxBuf); strcpy(rxStr, (char*)usartType1.usartDMA_rxBuf); // 处理数据 get_Data(rxStr, drawBuffer1, 'a', 'b'); get_Data(rxStr, drawBuffer2, 'b', 'c'); get_Data(rxStr, drawBuffer3, 'c', 'd'); memset(usartType1.usartDMA_rxBuf, 0x00, sizeof(usartType1.usartDMA_rxBuf)); } //__USART_SendData_DMA((uint8_t*)sendBuffer1, sizeof(sendBuffer1)); u8g2_FirstPage(&u8g2); do { u8g2_DrawStr(&u8g2, 0, 15, drawBuffer1); u8g2_DrawStr(&u8g2, 0, 30, drawBuffer2); u8g2_DrawStr(&u8g2, 0, 45, drawBuffer3); }while(u8g2_NextPage(&u8g2)); } /* USER CODE END 3 */

然后基本就可以了

但这个方案好像有点小问题,具体还没有搞清楚,大体是可以用的,至少可以接收电脑发送的数据并处理且显示,等有空再好好研究一下啦~


__EOF__

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