[STM32 HAL]一种可能不错的DMA处理数据方案
原文链接:https://blog.csdn.net/youmeichifan/article/details/51750435?spm=1001.2014.3001.5506
本文配置稍有不同,大体类似。
MX配置
开启USART1,使能USART1全局中断,打开RX,TX的DMA通道,均为normal模式,内存地址自增,使能TX对应DMA的中断,RX不需要。
代码部分
- 在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 */
然后基本就可以了
但这个方案好像有点小问题,具体还没有搞清楚,大体是可以用的,至少可以接收电脑发送的数据并处理且显示,等有空再好好研究一下啦~
标签:DMA,CODE,HAL,UART,USER,串口,usartType1 From: https://www.cnblogs.com/Asaka-QianXiang/p/17539327.html