1. 程式人生 > >stm32f0xx 的HAL 庫 HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart) 函式異常

stm32f0xx 的HAL 庫 HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart) 函式異常


最近使用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了

您怎麼看呢