STM32官方库bxCAN初始化流程
该文档翻译自stm32f4xx_hal_can.c的自述文档,基于我个人的理解,把HAL库初始化CAN总线的流程整理了一下。
MCU Specific Package: MSP、单片机的具体方案
- 添加Drv_Stm32F40xCAN1_BASE。
- 通过HAL_CAN_MspInit()初始化CAN低级资源:
2.1.使能CAN interface clock,__HAL_RCC_CANx_CLK_ENABLE()。 2.2.配置CAN引脚, 使能CAN引脚时钟。 把CAN引脚使能为复用开漏输出。 2.3.如果使用中断, 使用HAL_NVIC_SetPriority()配置CAN中断优先级。 使用HAL_NVIC_EnableIRQ()启用中断处理程序。 在中断处理程序中调用HAL_CAN_IRQHandler()。 - 通过HAL_CAN_Init()初始化CAN外设。
- 使用HAL_CAN_ConfigFilter()配置接收筛选器。
- 使用HAL_CAN_Start()启动CAN模块,到这里节点激活,节点接收消息,并且可以发送消息。
- 使用以下函数管理信息发送
HAL_CAN_AddTxMessage()请求发送新消息。 HAL_CAN_AbortTxRequest()取消一个挂起的发送请求。 HAL_CAN_GetTxMailboxesFreeLevel()获取空的发送邮箱数。 HAL_CAN_IsTxMessagePending()判断信息是否在发送邮箱里处于挂起状态。 HAL_CAN_GetTxTimestamp()获取发送的信息的时间戳,使用在TTC模式下。 - 当消息被接接收进Rx FIFO,可以使用HAL_CAN_GetRxMessage()获取消息,还可以使用
HAL_CAN_GetRxFifoFillLevel()获取Rx FIFO里面存储的消息数量。 - 调用HAL_CAN_Stop()函数禁用CAN模块。
- 在HAL_CAN_DeInit()里面实现去初始化。
轮询模式
- 接收
使用HAL_CAN_GetRxFifoFillLevel()监控接收邮箱的占用情况,直到接收到至少一条消息。 然后使用HAL_CAN_GetRxMessage()获取消息。 - 发送
使用HAL_CAN_GetTxMailboxesFreeLevel()监控发送邮箱的占用情况,直到至少一个邮箱是空的。 然后使用HAL_CAN_AddTxMessage()请求发送消息。
中断模式
- 通知可以使用HAL_CAN_ActivateNotification()来激活,这个过程可以通过回调函数HAL_CAN_xxxCallback()
来控制,使用的API是HAL_CAN_GetRxMessage()和HAL_CAN_AddTxMessage()。 - 通知可以使用HAL_CAN_DeactivateNotification()来禁用。
- 需要特别注意CAN_IT_RX_FIFO0_MSG_PENDING和CAN_IT_RX_FIFO1_MSG_PENDING的通知,这两个通知
会触发回调函数HAL_CAN_RxFIFO0MsgPendingCallback()和HAL_CAN_RxFIFO1MsgPendingCallback(), 用户在这里有两张选择: 3.1 在回调函数里面直接使用HAL_CAN_GetRxMessage()获取消息。 3.2 在回调函数里面禁用通知,后面使用HAL_CAN_GetRxMessage()获取消息,当读取完消息之后, 再把通知激活。
睡眠模式
- 可以使用HAL_CAN_RequestSleep()使CAN进入睡眠状态。
- 可以激活通知,以通知何时会进入睡眠状态。
- 可以使用HAL_CAN_IsSleepActive()获取CAN的睡眠状态,如果提交了睡眠请求但是还没有睡眠,CAN处于
HAL_CAN_STATE_SLEEP_PENDING状态,如果已经睡眠,CAN处于HAL_CAN_STATE_SLEEP_ACTIVE状态(通过 API HAL_CAN_GetState()获得)。 - 有两种方法把CAN从睡眠状态唤醒:
4.1 使用HAL_CAN_WakeUp(),该函数返回HAL_OK。 4.2 当CAN外设检测到接收信息的SOF时,如果启用了自动激活,就会自动唤醒CAN。
回调函数注册
只有当预编译宏定义USE_HAL_CAN_REGISTER_CALLBACKS被定义为1时,才允许用户动态配置回调。 使用HAL_CAN_RegisterCallback()注册中断回调。当没有定义或定义为0时,回调注册功能不可用, 所有的回调都被重置为相应的weak函数。 HAL_CAN_RegisterCallback()允许注册的回调包括: (+) TxMailbox0CompleteCallback : Tx Mailbox 0 Complete Callback. (+) TxMailbox1CompleteCallback : Tx Mailbox 1 Complete Callback. (+) TxMailbox2CompleteCallback : Tx Mailbox 2 Complete Callback. (+) TxMailbox0AbortCallback : Tx Mailbox 0 Abort Callback. (+) TxMailbox1AbortCallback : Tx Mailbox 1 Abort Callback. (+) TxMailbox2AbortCallback : Tx Mailbox 2 Abort Callback. (+) RxFifo0MsgPendingCallback : Rx Fifo 0 Message Pending Callback. (+) RxFifo0FullCallback : Rx Fifo 0 Full Callback. (+) RxFifo1MsgPendingCallback : Rx Fifo 1 Message Pending Callback. (+) RxFifo1FullCallback : Rx Fifo 1 Full Callback. (+) SleepCallback : Sleep Callback. (+) WakeUpFromRxMsgCallback : Wake Up From Rx Message Callback. (+) ErrorCallback : Error Callback. (+) MspInitCallback : CAN MspInit. (+) MspDeInitCallback : CAN MspDeInit. HAL_CAN_RegisterCallback()以HAL外设句柄、回调ID和指向回调的指针作为参数。
使用HAL_CAN_UnRegisterCallback()把回调函数重置回weak函数状态。 HAL_CAN_UnRegisterCallback()允许注销的回调包括: (+) TxMailbox0CompleteCallback : Tx Mailbox 0 Complete Callback. (+) TxMailbox1CompleteCallback : Tx Mailbox 1 Complete Callback. (+) TxMailbox2CompleteCallback : Tx Mailbox 2 Complete Callback. (+) TxMailbox0AbortCallback : Tx Mailbox 0 Abort Callback. (+) TxMailbox1AbortCallback : Tx Mailbox 1 Abort Callback. (+) TxMailbox2AbortCallback : Tx Mailbox 2 Abort Callback. (+) RxFifo0MsgPendingCallback : Rx Fifo 0 Message Pending Callback. (+) RxFifo0FullCallback : Rx Fifo 0 Full Callback. (+) RxFifo1MsgPendingCallback : Rx Fifo 1 Message Pending Callback. (+) RxFifo1FullCallback : Rx Fifo 1 Full Callback. (+) SleepCallback : Sleep Callback. (+) WakeUpFromRxMsgCallback : Wake Up From Rx Message Callback. (+) ErrorCallback : Error Callback. (+) MspInitCallback : CAN MspInit. (+) MspDeInitCallback : CAN MspDeInit. HAL_CAN_UnRegisterCallback()以HAL外设句柄和回调ID作为参数。
默认情况下,当HAL_CAN_Init()执行完并且状态为HAL_CAN_STATE_RESET时, 所有的回调都处于相应的若函数状态。但是有例外,只有当MspInit和MspDeInit回调为空(事先未注册)时, HAL_CAN_DeInit()/HAL_CAN_Init()才会把他们重置为传统的weak函数。如果MspInit和MspDeInit回调不为空(事先注册了), HAL_CAN_DeInit()/HAL_CAN_Init()会保持并使用用户注册的回调。
回调只能在HAL_CAN_STATE_READY状态注册或注销。 例外的是MspInit/MspDeInit可以在HAL_CAN_STATE_READY或HAL_CAN_STATE_RESET状态下 注册或注销,因此用户注册的MspInit/MspDeInit回调可以在Init/DeInit里使用。在这种情况下, 先使用HAL_CAN_RegisterCallback()注册用户MspInit/MspDeInit回调,再调用HAL_CAN_DeInit() 或HAL_CAN_Init()函数。
|