STM32--HAL庫中CAN的接收和發送函數

先來看看can外設相關的中斷向量表:

          EXPORT  CAN1_TX_IRQHandler                [WEAK]                                               

          EXPORT  CAN1_RX0_IRQHandler               [WEAK]                                              

          EXPORT  CAN1_RX1_IRQHandler               [WEAK]                                               

          EXPORT  CAN1_SCE_IRQHandler               [WEAK]  

這是can1的還有can2的,這裏就不再列出, 

CAN1_TX_IRQHandler:can1的發送中斷。

CAN1_RX0_IRQHandler:can1的FIFO0接收中斷。

CAN1_RX1_IRQHandler:can1的FIFO1接收中斷。

CAN1_SCE_IRQHandler:can1的狀態改變錯誤中斷。

你可能要問那什麼情況下會進發送中斷,什麼情況下會進FIFO0接收中斷,哪些寄存器的改變會產生相應的中斷,也就是中斷的產生關係是什麼樣的,接下來看圖:

發送中斷可由以下事件產生:
— 發送郵箱 0 變爲空, CAN_TSR 寄存器的 RQCP0 位置 1。
— 發送郵箱 1 變爲空, CAN_TSR 寄存器的 RQCP1 位置 1。
— 發送郵箱 2 變爲空, CAN_TSR 寄存器的 RQCP2 位置 1。 

FIFO 0 中斷可由以下事件產生:
— 接收到新消息, CAN_RF0R 寄存器的 FMP0 位不是「 00」。
— FIFO0 滿, CAN_RF0R 寄存器的 FULL0 位置 1。
— FIFO0 上溢, CAN_RF0R 寄存器的 FOVR0 位置 1。

 

FIFO 1 中斷可由以下事件產生:
— 接收到新消息, CAN_RF1R 寄存器的 FMP1 位不是「 00」。
— FIFO1 滿, CAN_RF1R 寄存器的 FULL1 位置 1。
— FIFO1 上溢, CAN_RF1R 寄存器的 FOVR1 位置 1。  

 

錯誤和狀態改變中斷可由以下事件產生:
— 錯誤狀況,有關錯誤狀況的更多詳細信息,請參見 CAN 錯誤狀態寄存器(CAN_ESR)。
— 喚醒狀況, CAN Rx 信號上監測到 SOF。
— 進入睡眠模式。

當然如果你好好看了,參考手冊會發現上面的內容好熟悉,哈哈。這當然是爲了保持講解完整性。   

 

接下來就要分析下STM32F4中的can 外設驅動裏的六個函數的功能,以及相關自定義函數的調用關係。

相關文件:stm32f4xx_hal.h 、stm32f4xx_hal.c

相關主函數:HAL_CAN_Transmit、HAL_CAN_Transmit_IT、HAL_CAN_Receive、HAL_CAN_Receive_IT、CAN_Transmit_IT、CAN_Receive_IT、HAL_CAN_IRQHandler。

相關回調函數:HAL_CAN_RxCpltCallback、HAL_CAN_TxCpltCallback、HAL_CAN_ErrorCallback 。

 

首先要從HAL_CAN_IRQHandler函數說起,不要問我爲什麼,它特別像中斷服務函數是嗎?

HAL_CAN_IRQHandler:

1、  如果已經使能了CAN_IT_TME(發送郵箱空中斷) 且有空閒郵箱 則調用CAN_Transmit_IT 來傳輸數據 ,而 CAN_Transmit_IT 則會在禁用CAN_IT_TME、以及相關的錯誤中斷後,調用HAL_CAN_TxCpltCallback,而HAL_CAN_TxCpltCallback就是我們需要自己填寫的發送回調函數。

2、  如果FIFOx(x = 0/1)有消息掛起並且開啓了FIFO消息掛起中斷CAN_IT_FMP0/ CAN_IT_FMP1,則會啓用CAN_Receive_IT來接收數據,而CAN_Receive_IT在接收完數據後會調用HAL_CAN_RxCpltCallback,這也是我們DIY的函數。

3、  接下來就是些錯誤處理,如果 有錯誤則會調用 HAL_CAN_ErrorCallback這也是我們DIY的函數。

好了,到這 HAL_CAN_IRQHandler 的介紹就結束了。需要注意的是這個並不是真正的中斷回調函數 !!!

HAL_CAN_Transmit:是非中斷模式下的API,初始化CAN_HandleTypeDef* hcan後調用即可。可設定錯誤重發。

HAL_CAN_Transmit_IT:中斷模式下的API,無錯誤重發功能。

HAL_CAN_Receive:是非中斷模式下的API

HAL_CAN_Receive_IT: 中斷模式下的API,只對中斷進行了設置,錯誤中斷、FIFOx消息掛起中斷,數據的真正接收,好像還得在CANx_RX0_IRQHandler 或 CANx_RX1_IRQHandler裏實現。