STM32F0C8T6使用空闲中断+DMA,接收数据不正常
问题是这样的:
空闲中断接收,复位后,接收大于1个字节,只能收到第一个字节。
复位后,单次接收一个字节,第一次正常,第二次数据会出现在接收数组的第二位中,第三次及往后都正常,接收多字节也正常。
void DMA_Usart2Init(uint32_t bound)
{
UART2_Handler.Instance = USART2;
UART2_Handler.Init.BaudRate = bound;
UART2_Handler.Init.StopBits = UART_STOPBITS_1;
UART2_Handler.Init.Parity = UART_PARITY_NONE;
UART2_Handler.Init.Mode = UART_MODE_TX_RX;
UART2_Handler.Init.WordLength = UART_WORDLENGTH_8B;
UART2_Handler.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UART2_Handler.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
// UART2_Handler.Init.OneBitSampling =
UART2_Handler.Init.OverSampling = UART_OVERSAMPLING_16;
if(HAL_UART_Init(&UART2_Handler) != HAL_OK)
{
Error_Handler();
}
HAL_NVIC_SetPriority(USART2_IRQn,0,0);//第二个数字,对于Core M0无用
HAL_NVIC_EnableIRQ(USART2_IRQn);
HAL_NVIC_SetPriority(DMA1_Channel4_5_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel4_5_IRQn);
__HAL_UART_ENABLE_IT(&UART2_Handler,UART_IT_IDLE);//使用空闲中断,不用接收中断
// __HAL_UART_CLEAR_IDLEFLAG(&UART2_Handler);
HAL_UART_Receive_DMA(&UART2_Handler,USART2_ReceiveBuf,128);
}
/**
* @brief 串口初始化回调函数.
* @param huart 串口号USART1,USART2
* @retval 无.
* @note 2019/07/31.
*/
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStruct;
if(huart->Instance==USART2)
{
USART2_RX_GPIO_CLK_ENABLE(); //使能GPIOA时钟
USART2_TX_GPIO_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
USART2_CLK_ENABLE(); //使能USART2时钟
GPIO_InitStruct.Alternate = USART2_TX_AF;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pin = USART2_TX_PIN;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(USART2_TX_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Alternate = USART2_RX_AF;
GPIO_InitStruct.Pin = USART2_RX_PIN;
HAL_GPIO_Init(USART2_RX_PORT, &GPIO_InitStruct);
#ifdef DMA_Usart
/* USART2 DMA Init */
/* USART2_RX Init */
hdma_usart2_rx.Instance = DMA1_Channel5;
hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_rx.Init.Mode = DMA_NORMAL;
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);
/* USART2_TX Init */
hdma_usart2_tx.Instance = DMA1_Channel4;
hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_tx.Init.Mode = DMA_NORMAL;
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
if (HAL_DMA_Init(&hdma_usart2_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);
#else
#endif
}
}
/**
* @brief USART2中断服务函数.
* @param 无
* @retval 无.
* @note 2019/07/31.
*/
void USART2_IRQHandler(void)
{
uint32_t timeout = 0;
HAL_UART_IRQHandler(&UART2_Handler); //调用HAL库中断处理公用函数 该函数会清空中断标志,取消中断使能,并间接调用回调函数
if((__HAL_UART_GET_FLAG(&UART2_Handler,UART_FLAG_IDLE) != RESET))
{
__HAL_UART_CLEAR_IDLEFLAG(&UART2_Handler);
__HAL_UART_CLEAR_IT(&UART2_Handler,UART_FLAG_IDLE);
__HAL_DMA_CLEAR_FLAG(hdma_usart2_rx,DMA_FLAG_TC5);
USART2->ICR |= 1<<4;
HAL_UART_DMAStop(&UART2_Handler); //
len = 128 - (__HAL_DMA_GET_COUNTER(&hdma_usart2_rx));
HAL_UART_Receive_DMA(&UART2_Handler,USART2_ReceiveBuf,128);
if(len <= 128)
{
}
}
}
IDLE中断根本没有处理任何接收数据,如果不使用接收中断则无法随时向缓冲区写入接收数据,当IDLE中断到来时数据就不正确。
页:
[1]