STM32--HAL库中CAN的接收和发送函数

时间:2024-03-26 07:32:23

先来看看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接收中断,哪些寄存器的改变会产生相应的中断,也就是中断的产生关系是什么样的,接下来看图:

STM32--HAL库中CAN的接收和发送函数

发送中断可由以下事件产生:
— 发送邮箱 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里实现。