最近使用stm32f030c8t6串口,使用DMA的方式接收和发送数据。
DMA使用IDLE中断接收不定长数据
void HAL_UART_IDLEHandler(UART_HandleTypeDef * huartx)
{
uint32_t tmp_flag = 0;
uint32_t temp;
tmp_flag = __HAL_UART_GET_IT(huartx,UART_IT_IDLE);
if((tmp_flag != RESET))
{
__HAL_UART_CLEAR_IT(huartx,UART_CLEAR_IDLEF);
huartx->Instance->ICR |= UART_CLEAR_IDLEF;
temp = huartx->Instance->ISR; // 清除IDLE标志位
temp = huartx->Instance->RDR;
HAL_UART_DMAStop(huartx); //先关闭DMA传输,否则无法修改hdma_usart2_rx.Instance->CNDTR(只读)
if(huartx == &huart2)
{
temp = hdma_usart2_rx.Instance->CNDTR; // 剩余的接收数据
Rec_flg2.rx_len = BUFFER_SIZE - temp; // 求出实际接收到的数据长度
Rec_flg2.recv_end_flag = 1;
inQueueBuff(&u2_rx,(int8_t *)(huartx->pRxBuffPtr),Rec_flg2.rx_len); //将接收到的数据压如栈中
HAL_UART_Receive_DMA(huartx,aRxBuffer2,BUFFER_SIZE);
}
else if(huartx == &huart1)
{
temp = hdma_usart1_rx.Instance->CNDTR; // 剩余的接收数据
Rec_flg1.rx_len = (BUFFER_SIZE - temp) % BUFFER_SIZE;
Rec_flg1.recv_end_flag = 1;
inQueueBuff(&u1_rx,(int8_t *)(huartx->pRxBuffPtr),Rec_flg1.rx_len);
HAL_UART_Receive_DMA(huartx,aRxBuffer1,BUFFER_SIZE);
}
}
}
该方式在stm32f103单片机上使用没有问题,但在stm32f030单片机上无法接收数据,单步调试发现不进入中断。
后检查stm32f0xx的HAL库
/**
* @brief Stops the DMA Transfer.
* @param huart: UART handle
* @retval None
*/
HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)
{
/* Process Locked */
__HAL_LOCK(huart);
/* Disable the UART Tx/Rx DMA requests */
huart->Instance->CR3 &= ~USART_CR3_DMAT;
huart->Instance->CR3 &= ~USART_CR3_DMAR;
/* Abort the UART DMA tx channel */
if(huart->hdmatx != NULL)
{
HAL_DMA_Abort(huart->hdmatx);
}
/* Abort the UART DMA rx channel */
if(huart->hdmarx != NULL)
{
HAL_DMA_Abort(huart->hdmarx);
}
/* Disable UART peripheral */
// __HAL_UART_DISABLE(huart); // 该处直接关闭串口,所以不进入串口中断了
huart->State = HAL_UART_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(huart);
return HAL_OK;
}
把 __HAL_UART_DISABLE(huart); 取消掉,一切就正常了
f10X 和f00x 两个HAL对应的该函数的程序,只有此处不一样,该处的
__HAL_UART_DISABLE(huart);
应该算一个bug了
您怎么看呢