stmcubemx生成串口DMA接收中断,无法接收第一次到来的数据## 标题
使用cubemx生成工程的过程就暂时不写了,如果有需要的小伙伴可以评论,后续会根据需要写一版。之所以写这个是因为自己在这里困了好久,想记录一下,也给正在学习的小伙伴们一点帮助。可能说的不是很好,希望大家理解。废话不多说直接看图。
cubemx生成的配置代码如下。先看.h里的代码。这里我使用的是空闲中断的方法,所以在初始化时一定要加入__HAL_UART_ENABLE_IT(&huart8, UART_IT_IDLE);这句代码。详情见下面代码。
#include "usart.h"
/* USER CODE BEGIN 0 */
/*****USBͨÐÅ USART6******/
uint8_t USB_Rx_Buf[USB_Rx_SIZE];
uint8_t USB_Rx_Finished=0;
uint8_t USB_Rx_Len=0;
uint8_t USB_Tx_Buf[USB_Tx_SIZE];
/*****USBͨÐÅ UART8******/
uint8_t Wifi_Rx_Buf[Wifi_Rx_SIZE];
uint8_t Wifi_Rx_Finished=0;
uint8_t Wifi_Rx_Len;
uint8_t Wifi_Tx_Buf[Wifi_Tx_SIZE];
/* USER CODE END 0 */
UART_HandleTypeDef huart8;
UART_HandleTypeDef huart6;
DMA_HandleTypeDef hdma_uart8_rx;
DMA_HandleTypeDef hdma_uart8_tx;
DMA_HandleTypeDef hdma_usart6_rx;
DMA_HandleTypeDef hdma_usart6_tx;
/* UART8 init function */
void MX_UART8_Init(void)
{
huart8.Instance = UART8;
huart8.Init.BaudRate = 115200;
huart8.Init.WordLength = UART_WORDLENGTH_8B;
huart8.Init.StopBits = UART_STOPBITS_1;
huart8.Init.Parity = UART_PARITY_NONE;
huart8.Init.Mode = UART_MODE_TX_RX;
huart8.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart8.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart8) != HAL_OK)
{
Error_Handler();
}
}
void MX_USART6_UART_Init(void)
{
huart6.Instance = USART6;
huart6.Init.BaudRate = 115200;
huart6.Init.WordLength = UART_WORDLENGTH_8B;
huart6.Init.StopBits = UART_STOPBITS_1;
huart6.Init.Parity = UART_PARITY_NONE;
huart6.Init.Mode = UART_MODE_TX_RX;
huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart6.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart6) != HAL_OK)
{
Error_Handler();
}
}
//这里我配置了两个串口,大家看任何一个都是可以的
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(uartHandle->Instance==UART8)
{
/* USER CODE BEGIN UART8_MspInit 0 */
/* USER CODE END UART8_MspInit 0 /
/ UART8 clock enable */
__HAL_RCC_UART8_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
/**UART8 GPIO Configuration
PE0 ------> UART8_RX
PE1 ------> UART8_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_UART8;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/* UART8 DMA Init */
/* UART8_RX Init */
hdma_uart8_rx.Instance = DMA1_Stream6;
hdma_uart8_rx.Init.Channel = DMA_CHANNEL_5;
hdma_uart8_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_uart8_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_uart8_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_uart8_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_uart8_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_uart8_rx.Init.Mode = DMA_NORMAL;
hdma_uart8_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_uart8_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_uart8_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmarx,hdma_uart8_rx);
/* UART8_TX Init */
hdma_uart8_tx.Instance = DMA1_Stream0;
hdma_uart8_tx.Init.Channel = DMA_CHANNEL_5;
hdma_uart8_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_uart8_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_uart8_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_uart8_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_uart8_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_uart8_tx.Init.Mode = DMA_NORMAL;
hdma_uart8_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_uart8_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_uart8_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmatx,hdma_uart8_tx);
/* UART8 interrupt Init */
HAL_NVIC_SetPriority(UART8_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(UART8_IRQn);
/* USER CODE BEGIN UART8_MspInit 1 */
__HAL_UART_ENABLE_IT(&huart8, UART_IT_IDLE);
/* USER CODE END UART8_MspInit 1 /
}
else if(uartHandle->Instance==USART6)
{
/ USER CODE BEGIN USART6_MspInit 0 */
/* USER CODE END USART6_MspInit 0 /
/ USART6 clock enable */
__HAL_RCC_USART6_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/**USART6 GPIO Configuration
PC6 ------> USART6_TX
PC7 ------> USART6_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_USART6;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* USART6 DMA Init */
/* USART6_RX Init */
hdma_usart6_rx.Instance = DMA2_Stream1;
hdma_usart6_rx.Init.Channel = DMA_CHANNEL_5;
hdma_usart6_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart6_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart6_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart6_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart6_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart6_rx.Init.Mode = DMA_NORMAL;
hdma_usart6_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart6_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart6_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart6_rx);
/* USART6_TX Init */
hdma_usart6_tx.Instance = DMA2_Stream6;
hdma_usart6_tx.Init.Channel = DMA_CHANNEL_5;
hdma_usart6_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart6_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart6_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart6_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart6_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart6_tx.Init.Mode = DMA_NORMAL;
hdma_usart6_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart6_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart6_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmatx,hdma_usart6_tx);
/* USART6 interrupt Init */
HAL_NVIC_SetPriority(USART6_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(USART6_IRQn);
/* USER CODE BEGIN USART6_MspInit 1 */
__HAL_UART_ENABLE_IT(&huart6, UART_IT_IDLE);
/* USER CODE END USART6_MspInit 1 /
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef uartHandle)
{
if(uartHandle->Instance==UART8)
{
/* USER CODE BEGIN UART8_MspDeInit 0 */
/* USER CODE END UART8_MspDeInit 0 /
/ Peripheral clock disable */
__HAL_RCC_UART8_CLK_DISABLE();
/**UART8 GPIO Configuration
PE0 ------> UART8_RX
PE1 ------> UART8_TX
*/
HAL_GPIO_DeInit(GPIOE, GPIO_PIN_0|GPIO_PIN_1);
/* UART8 DMA DeInit */
HAL_DMA_DeInit(uartHandle->hdmarx);
HAL_DMA_DeInit(uartHandle->hdmatx);
/* UART8 interrupt Deinit */
HAL_NVIC_DisableIRQ(UART8_IRQn);
/* USER CODE BEGIN UART8_MspDeInit 1 */
/* USER CODE END UART8_MspDeInit 1 /
}
else if(uartHandle->Instance==USART6)
{
/ USER CODE BEGIN USART6_MspDeInit 0 */
/* USER CODE END USART6_MspDeInit 0 /
/ Peripheral clock disable */
__HAL_RCC_USART6_CLK_DISABLE();
/**USART6 GPIO Configuration
PC6 ------> USART6_TX
PC7 ------> USART6_RX
*/
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_6|GPIO_PIN_7);
/* USART6 DMA DeInit */
HAL_DMA_DeInit(uartHandle->hdmarx);
HAL_DMA_DeInit(uartHandle->hdmatx);
/* USART6 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART6_IRQn);
/* USER CODE BEGIN USART6_MspDeInit 1 */
/* USER CODE END USART6_MspDeInit 1 /
}
}
然后就是中断函数里的代码了,
void USART6_IRQHandler(void)
{
/ USER CODE BEGIN USART6_IRQn 0 */
if(__HAL_UART_GET_FLAG(&huart6,UART_FLAG_IDLE)!=RESET)
{
__HAL_UART_CLEAR_IDLEFLAG(&huart6);//清除中断标志
__HAL_DMA_DISABLE(&hdma_usart6_rx);//关闭串口的接收中断,防止后来数据影响
HAL_UART_DMAStop(&huart6);
USB_Rx_Len = USB_Rx_SIZE-__HAL_DMA_GET_COUNTER(&hdma_usart6_rx);//计算接收到的数据长度
__HAL_DMA_GET_COUNTER(&hdma_usart6_rx)=USB_Rx_SIZE;
__HAL_DMA_ENABLE(&hdma_usart6_rx);
HAL_UART_Receive_DMA(&huart6,USB_Rx_Buf,USB_Rx_SIZE);
USB_Rx_Finished=1;
}
/* USER CODE END USART6_IRQn 0 /
HAL_UART_IRQHandler(&huart6);
/ USER CODE BEGIN USART6_IRQn 1 */
/* USER CODE END USART6_IRQn 1 */
}
/**
-
@brief This function handles UART8 global interrupt.
/
void UART8_IRQHandler(void)
{
/ USER CODE BEGIN UART8_IRQn 0 */if(__HAL_UART_GET_FLAG(&huart8,UART_FLAG_IDLE)!=RESET) { __HAL_UART_CLEAR_IDLEFLAG(&huart8);//Çå³ýÖжϱêÖ¾ __HAL_DMA_DISABLE(&hdma_uart8_rx);//¹Ø±Õ´®¿Ú1DMA½ÓÊÕ£¬·ÀÖ¹ºóÀ´Êý¾ÝÓ°ÏìÊý¾Ý´¦Àí HAL_UART_DMAStop(&huart8); Wifi_Rx_Len = Wifi_Rx_SIZE-__HAL_DMA_GET_COUNTER(&hdma_uart8_rx);// »ñÈ¡½ÓÊÕµ½µÄÊý¾Ý³¤¶È£¬µ¥Î»£º×Ö½Ú __HAL_DMA_GET_COUNTER(&hdma_uart8_rx)=Wifi_Rx_SIZE; __HAL_DMA_ENABLE(&hdma_uart8_rx); HAL_UART_Receive_DMA(&huart8,Wifi_Rx_Buf,Wifi_Rx_SIZE); Wifi_Rx_Finished=1; }
/* USER CODE END UART8_IRQn 0 /
HAL_UART_IRQHandler(&huart8);
/ USER CODE BEGIN UART8_IRQn 1 */
/* USER CODE END UART8_IRQn 1 /
}
至此已经可以完成基本的串口数据接受了,但是每次接受的第一个数据就莫名其妙的不见了。所以关键点来了。主函数中在完成串口初始化后一定要调用 HAL_UART_Receive_DMA(&huart6,USB_Rx_Buf,USB_Rx_SIZE);和HAL_UART_Receive_DMA(&huart8,Wifi_Rx_Buf,Wifi_Rx_SIZE);
int main(void)
{
/ USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals /
MX_GPIO_Init();
MX_DMA_Init();
MX_USART6_UART_Init();
MX_UART8_Init();
HAL_UART_Receive_DMA(&huart6,USB_Rx_Buf,USB_Rx_SIZE);
HAL_UART_Receive_DMA(&huart8,Wifi_Rx_Buf,Wifi_Rx_SIZE);
MX_TIM2_Init();
/ USER CODE BEGIN 2 */
delay_init(180);
AT24CXX_Init();
//ESP8266_Init(1);
//Esp8266_Connect_Alilot();
/* USER CODE END 2 */
/* Call init function for freertos objects (in freertos.c) */
MX_FREERTOS_Init();
/* Start scheduler */
osKernelStart();
/* We should never get here as control is now taken by the scheduler */
/* Infinite loop /
/ USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
第一次写,可能写的不好。就当做自己学习的一个总结吧。大家多多包涵。