stmcubemx生成串口DMA接收中断,无法接收第一次到来的数据

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 */
}
第一次写,可能写的不好。就当做自己学习的一个总结吧。大家多多包涵。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值