转自:http://blog.csdn.net/flydream0/article/details/8170301
1 前言
bxCAN占用4个专用的中断向量。通过设置CAN中断允许寄存器(CAN_IER),每个中断源都可以单独允许和禁用。
图1
从图1可以看出,最右边共四个中断,中断是可以通过CAN_IER来屏蔽或允许的。
2 CAN中断允许寄存器 (CAN_IER)
地址偏移量: 0x14
复位值: 0x0000 0000
图2
位31:18 | 保留位,硬件强制为0 |
位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 | EPVIE: Error Passive Interrupt Enable 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时,产生中断。 注: 请参考21.5节bxCAN中断。 |
3 固件库中如何用代码配置中断
在startup_stm32f2xx.s文件中可以看到下面四个中断:
- EXPORT CAN1_TX_IRQHandler [WEAK]
- EXPORT CAN1_RX0_IRQHandler [WEAK]
- EXPORT CAN1_RX1_IRQHandler [WEAK]
- EXPORT CAN1_SCE_IRQHandler [WEAK]
如何配置中断?使用CAN_ITConfig函数开启或屏蔽中断,如下:
- CAN_ITConfig(CAN1,CAN_IT_FMP0, ENABLE);//打开FMP0中断 也可写成CAN_ITConfig(CAN1,CAN_IT_FMP0 |CAN_IT_BOF, ENABLE);//打开FMP0和BOF中断
如此,便可打开CAN接收中断了。
从图1可以看出,最右边中断有时有可能是最左边某一个中断引起的,因此,当引起最右边的某一中断时,如果最左边有多个对应的中断源的话,如果程序需要,还需进一步确定是由哪个中断源引起的,此时,需要调用CAN_GetITStatus函数来做进一步确定。
从图1可以看出,最右边中断有时有可能是最左边某一个中断引起的,因此,当引起最右边的某一中断时,如果最左边有多个对应的中断源的话,如果程序需要,还需进一步确定是由哪个中断源引起的,此时,需要调用CAN_GetITStatus函数来做进一步确定。
中断信号罗列如下:
/* Receive Interrupts */
#define CAN_IT_FMP0 ((uint32_t)0x00000002) /*!< FIFO 0 message pending Interrupt*/
#define CAN_IT_FF0 ((uint32_t)0x00000004) /*!< FIFO 0 full Interrupt*/
#define CAN_IT_FOV0 ((uint32_t)0x00000008) /*!< FIFO 0 overrun Interrupt*/
#define CAN_IT_FMP1 ((uint32_t)0x00000010) /*!< FIFO 1 message pending Interrupt*/
#define CAN_IT_FF1 ((uint32_t)0x00000020) /*!< FIFO 1 full Interrupt*/
#define CAN_IT_FOV1 ((uint32_t)0x00000040) /*!< FIFO 1 overrun Interrupt*/
/* Operating Mode Interrupts */
#define CAN_IT_WKU ((uint32_t)0x00010000) /*!< Wake-up Interrupt*/
#define CAN_IT_SLK ((uint32_t)0x00020000) /*!< Sleep acknowledge Interrupt*/
/* Error Interrupts */
#define CAN_IT_EWG ((uint32_t)0x00000100) /*!< Error warning Interrupt*/
#define CAN_IT_EPV ((uint32_t)0x00000200) /*!< Error passive Interrupt*/
#define CAN_IT_BOF ((uint32_t)0x00000400) /*!< Bus-off Interrupt*/ 离线中断信号
#define CAN_IT_LEC ((uint32_t)0x00000800) /*!< Last error code Interrupt*/
#define CAN_IT_ERR ((uint32_t)0x00008000) /*!< Error Interrupt*/
/* Flags named as Interrupts : kept only for FW compatibility */
#define CAN_IT_RQCP0 CAN_IT_TME
#define CAN_IT_RQCP1 CAN_IT_TME
#define CAN_IT_RQCP2 CAN_IT_TME
#define CAN_IT_FMP0 ((uint32_t)0x00000002) /*!< FIFO 0 message pending Interrupt*/
#define CAN_IT_FF0 ((uint32_t)0x00000004) /*!< FIFO 0 full Interrupt*/
#define CAN_IT_FOV0 ((uint32_t)0x00000008) /*!< FIFO 0 overrun Interrupt*/
#define CAN_IT_FMP1 ((uint32_t)0x00000010) /*!< FIFO 1 message pending Interrupt*/
#define CAN_IT_FF1 ((uint32_t)0x00000020) /*!< FIFO 1 full Interrupt*/
#define CAN_IT_FOV1 ((uint32_t)0x00000040) /*!< FIFO 1 overrun Interrupt*/
/* Operating Mode Interrupts */
#define CAN_IT_WKU ((uint32_t)0x00010000) /*!< Wake-up Interrupt*/
#define CAN_IT_SLK ((uint32_t)0x00020000) /*!< Sleep acknowledge Interrupt*/
/* Error Interrupts */
#define CAN_IT_EWG ((uint32_t)0x00000100) /*!< Error warning Interrupt*/
#define CAN_IT_EPV ((uint32_t)0x00000200) /*!< Error passive Interrupt*/
#define CAN_IT_BOF ((uint32_t)0x00000400) /*!< Bus-off Interrupt*/ 离线中断信号
#define CAN_IT_LEC ((uint32_t)0x00000800) /*!< Last error code Interrupt*/
#define CAN_IT_ERR ((uint32_t)0x00008000) /*!< Error Interrupt*/
/* Flags named as Interrupts : kept only for FW compatibility */
#define CAN_IT_RQCP0 CAN_IT_TME
#define CAN_IT_RQCP1 CAN_IT_TME
#define CAN_IT_RQCP2 CAN_IT_TME