Bootstrap

【HAL库】STM32F407----CAN通信----中断详解

CAN通信----基本原理
CAN通信----电路图

一、CAN通信----中断简介

STM32F407的CAN通信一共有四个专用中断,分别是:

  1. 发送中断
  2. FIFO0 接收中断
  3. FIFO1 接收中断
  4. 错误中断

具体如下图所示:

在这里插入图片描述

二、CAN通信----中断寄存器

CAN中断使能寄存器(CAN_IER)

偏移地址:0x14
复位值:0x000000000

在这里插入图片描述

寄存器位说明
位31:18保留位,必须保持复位值
位17SLKIE: 睡眠中断使能
0: 当SLAKI位被置1时,没有中断产生;
1: 当SLAKI位被置1时,产生中断。
位16WKUIE: 睡眠唤醒中断使能
0: 当WKUI位被置1时,没有中断产生;
1: 当WKUI位被置1时,产生中断。
位15ERRIE: 错误中断使能
0: 当CAN_ESR寄存器有错误挂号时,没有中断产生;
1: 当CAN_ESR寄存器有错误挂号时,产生中断。
位14:12保留位,硬件强制为0。
位11LECIE: 上次错误号中断使能
0: 当检测到错误从而硬件对LEC[2:0]写入非0值时,不会对ERRI位置1;
1: 当检测到错误从而硬件对LEC[2:0]写入非0值时,对ERRI位置1。
位10BOFIE: 离线中断使能
0: 当BOFF位被置1时,不会对ERRI位置1;
1: 当BOFF位被置1时,对ERRI位置1。
位9EOVIE:错误被动中断使能
0: 当EPVF位被置1时,不会对ERRI位置1;
1: 当EPVF位被置1时,对ERRI位置1。
位8EWGIE: 错误警告中断使能
0: 当EWGF位被置1时,不会对ERRI位置1;
1: 当EWGF位被置1时,对ERRI位置1。
位7保留位,硬件强制为0
位6FOVIE1: FIFO1溢出中断使能
0: 当FIFO1的FOVR位被置1时,没有中断产生;
1: 当FIFO1的FOVR位被置1时,产生中断。
位5FFIE1: FIFO1满中断使能
0: 当FIFO1的FULL位被置1时,没有中断产生;
1: 当FIFO1的FULL位被置1时,产生中断。
位4FMPIE1: FIFO1消息挂起中断使能
0: 当FIFO1的FMP[1:0]位被写入非0值时,没有中断产生;
1: 当FIFO1的FMP[1:0]位被写入非0值时,产生中断。
位3FOVIE0: FIFO0溢出中断使能
0: 当FIFO0的FOVR位被置1时,没有中断产生;
1: 当FIFO0的FOVR位被置1时,产生中断。
位2FFIE0: FIFO0满中断使能
0: 当FIFO0的FULL位被置1时,没有中断产生;
1: 当FIFO0的FULL位被置1时,产生中断。
位1FMPIE0: FIFO0消息挂起中断使能
0: 当FIFO0的FMP[1:0]位被写入非0值时,没有中断产生;
1: 当FIFO0的FMP[1:0]位被写入非0值时,产生中断。
位0TMEIE: 发送邮箱空中断使能
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);

;