一、CAN通信----中断简介
STM32F407的CAN通信一共有四个专用中断,分别是:
- 发送中断
- FIFO0 接收中断
- FIFO1 接收中断
- 错误中断
具体如下图所示:
二、CAN通信----中断寄存器
CAN中断使能寄存器(CAN_IER)
偏移地址:0x14
复位值:0x000000000
寄存器位 | 说明 |
---|---|
位31:18 | 保留位,必须保持复位值 |
位17 | SLKIE: 睡眠中断使能 0: 当SLAKI位被置1时,没有中断产生; 1: 当SLAKI位被置1时,产生中断。 |
位16 | WKUIE: 睡眠唤醒中断使能 0: 当WKUI位被置1时,没有中断产生; 1: 当WKUI位被置1时,产生中断。 |
位15 | ERRIE: 错误中断使能 0: 当CAN_ESR寄存器有错误挂号时,没有中断产生; 1: 当CAN_ESR寄存器有错误挂号时,产生中断。 |
位14:12 | 保留位,硬件强制为0。 |
位11 | LECIE: 上次错误号中断使能 0: 当检测到错误从而硬件对LEC[2:0]写入非0值时,不会对ERRI位置1; 1: 当检测到错误从而硬件对LEC[2:0]写入非0值时,对ERRI位置1。 |
位10 | BOFIE: 离线中断使能 0: 当BOFF位被置1时,不会对ERRI位置1; 1: 当BOFF位被置1时,对ERRI位置1。 |
位9 | EOVIE:错误被动中断使能 0: 当EPVF位被置1时,不会对ERRI位置1; 1: 当EPVF位被置1时,对ERRI位置1。 |
位8 | EWGIE: 错误警告中断使能 0: 当EWGF位被置1时,不会对ERRI位置1; 1: 当EWGF位被置1时,对ERRI位置1。 |
位7 | 保留位,硬件强制为0 |
位6 | FOVIE1: FIFO1溢出中断使能 0: 当FIFO1的FOVR位被置1时,没有中断产生; 1: 当FIFO1的FOVR位被置1时,产生中断。 |
位5 | FFIE1: FIFO1满中断使能 0: 当FIFO1的FULL位被置1时,没有中断产生; 1: 当FIFO1的FULL位被置1时,产生中断。 |
位4 | FMPIE1: FIFO1消息挂起中断使能 0: 当FIFO1的FMP[1:0]位被写入非0值时,没有中断产生; 1: 当FIFO1的FMP[1:0]位被写入非0值时,产生中断。 |
位3 | FOVIE0: FIFO0溢出中断使能 0: 当FIFO0的FOVR位被置1时,没有中断产生; 1: 当FIFO0的FOVR位被置1时,产生中断。 |
位2 | FFIE0: FIFO0满中断使能 0: 当FIFO0的FULL位被置1时,没有中断产生; 1: 当FIFO0的FULL位被置1时,产生中断。 |
位1 | FMPIE0: FIFO0消息挂起中断使能 0: 当FIFO0的FMP[1:0]位被写入非0值时,没有中断产生; 1: 当FIFO0的FMP[1:0]位被写入非0值时,产生中断。 |
位0 | TMEIE: 发送邮箱空中断使能 0: 当RQCPx位被置1时,没有中断产生; 1: 当RQCPx位被置1时,产生中断。 |
三、CAN通信----中断配置
1. 在STM32CubeMX上,勾选中断
生成程序后,代码如下:
STM32CubeMX上,关于CAN通信配置的具体操作步骤,请看这篇文章:
【HAL库】STM32CubeMX开发----STM32F407----CAN通信实验
2. 启动中断
需要用中断启动函数启动中断,启动函数如下:
//启动CAN中断函数
HAL_StatusTypeDef HAL_CAN_ActivateNotification(CAN_HandleTypeDef *hcan, uint32_t ActiveITs);
//禁用CAN中断函数
HAL_StatusTypeDef HAL_CAN_DeactivateNotification(CAN_HandleTypeDef *hcan, uint32_t InactiveITs);
启动中断具体如下:
//启动CAN发送中断
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_TX_MAILBOX_EMPTY);
//启动CAN接收中断-FIFO0接收新消息
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
//启动CAN发送中断-FIFO0接收满
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_FULL);
//启动CAN发送中断-FIFO0接收上溢
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_OVERRUN);
//启动CAN接收中断-FIFO1接收新消息
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO1_MSG_PENDING);
//启动CAN发送中断-FIFO1接收满
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO1_FULL);
//启动CAN发送中断-FIFO1接收上溢
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO1_OVERRUN);
//启动CAN-唤醒中断
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_WAKEUP);
//启动CAN-睡眠中断
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_SLEEP_ACK);
//启动CAN-错误告警中断
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_ERROR_WARNING);
//启动CAN-错误被动中断
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_ERROR_PASSIVE);
//启动CAN-总线关闭中断
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_BUSOFF);
//启动CAN-上一个错误代码中断
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_LAST_ERROR_CODE);
//启动CAN-错误中断
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_ERROR);
3. 中断回调函数
当产生对应的中断,就会调用对应的中断回调函数。
//CAN通信-发送完成回调函数
void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan);
void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan);
void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan);
//CAN通信-发送取消回调函数
void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef *hcan);
void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef *hcan);
void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef *hcan);
//CAN通信-FIFO0接收新消息回调函数
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan);
//CAN通信-FIFO0接收满回调函数
void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan);
//CAN通信-FIFO1接收新消息回调函数
void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan);
//CAN通信-FIFO1接收满回调函数
void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan);
//CAN通信-休眠回调函数
void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan);
//CAN通信-唤醒回调函数
void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan);
//CAN通信-错误回调函数
void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan);