stm32 hal can接收大量資料的轟炸後,不能繼續接收(不能再進入中斷);
阿新 • • 發佈:2019-02-19
原因:若在接收的時候傳送資料,
傳送中的處理:
hal_can_transmit()中會進行hal_lock(hcan);然後更改can狀態為HAL_CAN_STATE_BUSY_TX相關的。
再談一下接收中的處理,不用多說肯定是在接收中斷國會開啟下一次接收,即hal_can_receive_it();那麼這裡邊又幹了什麼:
/* Check if CAN state is not busy for RX FIFO0 */ if((FIFONumber == CAN_FIFO0) && ((hcan->State == HAL_CAN_STATE_BUSY_RX0) || \ (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0) || \ (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \ (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1))) { return HAL_BUSY; } /* Check if CAN state is not busy for RX FIFO1 */ if((FIFONumber == CAN_FIFO1) && ((hcan->State == HAL_CAN_STATE_BUSY_RX1) || \ (hcan->State == HAL_CAN_STATE_BUSY_TX_RX1) || \ (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \ (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1))) { return HAL_BUSY; }
這兒會直接返回,也就是說如果此時處於這些狀態說明一定有執行過hal_lock(), 既然我們返回了那相應的中斷標籤並沒有得到相應的處理。
對比後發現hal_can_transmit和hal_can_receive_it中在lock之後都會執行以下語句
不過hal_can_receive_it中在unlock之後還多執行了__HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG | CAN_IT_EPV | CAN_IT_BOF | CAN_IT_LEC | CAN_IT_ERR | CAN_IT_TME);
/* Process unlocked */ __HAL_UNLOCK(hcan); if(FIFONumber == CAN_FIFO0) { /* Enable FIFO 0 overrun and message pending Interrupt */ __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FOV0 | CAN_IT_FMP0); } else { /* Enable FIFO 1 overrun and message pending Interrupt */ __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FOV1 | CAN_IT_FMP1); }
好,那我們是不是如果hal_can_receive_it(&hcan1)== hal_busy時新增執行以上語句就可以了 ,實現證明是可以的。
那在接收中斷中對果hal_can_receive_it作如下處理:
if( HAL_BUSY == HAL_CAN_Receive_IT(hcanx, CAN_FIFO0))//開啟中斷接收
{
/* Enable FIFO 0 overrun and message pending Interrupt */
__HAL_CAN_ENABLE_IT(&hcan1, CAN_IT_FOV0 | CAN_IT_FMP0);
}