這里只記錄注意要點:
1,要開啟串口 全局中斷 和對應的接收DMA 中斷,兩個中斷必須同時開
2,裸機程序需要在主循環外調用一次 這個函數
HAL_UARTEx_ReceiveToIdle_DMA(&huart2, rx_buff, BUFF_SIZE);
3,要在串口中斷處理函數中 添加這個函數?
HAL_UARTEx_ReceiveToIdle_DMA(&huart2, rx_buff, BUFF_SIZE);
4,重寫空閑中斷回調函數 ,它是個弱函數,需要程序員自己實現
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef * huart, uint16_t Size)
在這個函數中,可以做一些事情,比如記錄收到了多少個字節數據,或者對接收數據處理。
5,HAL_UARTEx_ReceiveToIdle_DMA 函數的作用:
?? ??? ?1,把接收類型設置成HAL_UART_RECEPTION_TOIDLE,
?? ??? ?2,調用開啟DMA接收函數;
?? ??? ?3,調用完再清除一次IDLEF標志位
?? ??? ?4,然后再設置IDLEIE標志位
6,上面第5點可以看出,這個函數需要反復調用,一般放在串口中斷函數里面就可以了,不能放在回調函數里,因為一旦出現異常沒有進中斷,那么在沒有其它地方調用HAL_UARTEx_ReceiveToIdle_DMA的話 ,就再也不進空閑中斷了,DMA 也不接收了
7,如果是了 OS , 那么可以用這種辦法:在任務中反復調用這個函數:HAL_UARTEx_ReceiveToIdle_DMA?,而無需在中斷函數里調用 ,不過本質上還是一樣的 :
while(1)
{status = HAL_UARTEx_ReceiveToIdle_DMA(&huart4, uart4_rx_buffer, UART_BUFFER_SIZE);while (status != HAL_OK) {osDelay(1);status = HAL_UARTEx_ReceiveToIdle_DMA(&huart4,uart4_rx_buffer,UART_BUFFER_SIZE);}osSemaphoreAcquire(sem_uart4_rxHandle, osWaitForever); //這里是等待空閑中斷到來HAL_UART_AbortReceive(&huart4);//do sometings }...可以在 空閑中斷函數中添加 發送信號量if(huart->Instance == UART4) {uart4_rx_len = Size;osSemaphoreRelease(sem_uart4_rxHandle);}