近一直在搞CAN调试,目前为止基本的CAN通讯没问题了【查询、中断接收,发送中断】,我使用的是STM32F103RB芯片,软件库函数是V3.4.0——2010-10-15,CAN_TX使用的是PB9,CAN_RX使用的是PB8,但是还是还有几个疑问:
关于CAN的发送中断,由于入口函数和使能只有一个【分别为USB_HP_CAN1_TX_IRQHandler和USB_HP_CAN1_TX_IRQn】,故这个好理解。但是关于接收中断函数就不一样了,使能的参数有三个【USB_LP_CAN1_RX0_IRQn、CAN1_RX0_IRQn和CAN1_RX1_IRQn】,当然相关的接收中断函数也有三个【USB_LP_CAN1_RX0_IRQHandler、CAN1_RX0_IRQHandler和CAN1_RX1_IRQHandler】。
在网上查了查区别,目前只有USB_LP_CAN1_RX0_IRQn、CAN1_RX0_IRQn和CAN1_RX1_IRQn的阐述:
一、如果你用的CAN引脚是PA11和PA12,接收中断用USB_LP_CAN1_RX0_IRQn。如果CAN引脚用的是PB8和PB9,也就是用重定义的引脚,接收中
断用CAN1_RX1_IRQn。你可以看下手册中的引脚说明,PA11和PA12也是USB的引脚,所以IAR在起名字时用了USB_LP_CAN1_RX0_IRQn。
二、“如果你用的CAN引脚是PA11和PA12,接收中断用CAN1_RX0_IRQn。如果CAN引脚用的是PB8和PB9,也就是用重定义的引脚,接收中断
用CAN1_RX1_IRQn。由于PA11和PA12也是USB的引脚,所以非互联型且带CAN控制器的微控制器的库文件在起名字时用了USB_LP_CAN1_RX0_IRQn。”
三、STM32有2个3级深度的接收缓冲区:FIFO0和FIFO1,每个FIFO都可以存放3个完整的报文,它们完全由硬件来管理。如果是来自FIFO0的接收中
断,则用CAN1_RX0_IRQn中断来处理。如果是来自FIFO1的接收中断,则用CAN1_RX1_IRQn中断来处理。在CAN的初始化配置过程中,
用CAN_FilterFIFOAssignment来选择要使用FIFO。
注:CAN1_RX0_IRQn只有在STM32F10X_CL【互联型产品stm32f105/107系列】产品中使用。
我目前的中断程序条件是:CAN使用PB口,二中断函数用的是USB_LP_CAN1_RX0_IRQn使能的中断函数USB_LP_CAN1_RX0_IRQHandler;而CAN1_RX0_IRQHandler函数在启动函数内部根本就没有这个函数,相关的使用CAN1_RX0_IRQn也没有定义;CAN1_RX1_IRQn使能的CAN1_RX1_IRQHandler中断函数是进不了中断的。
疑惑:
A、这样的话跟“一”矛盾,我的PB口也能使用USB_LP_CAN1_RX0_IRQn,而却使用不了CAN1_RX1_IRQn;
B、跟“二”也矛盾;
C、跟三也矛盾,我虽然使用的是FIFO0,但是CAN1_RX0_IRQn只在互联型产品中使用;
因此想弄明白:CAN1_RX0_IRQn、CAN1_RX1_IRQn、CAN1_SCE_IRQn和USB_LP_CAN1_RX0_IRQn的区别?
望高人不啬指点!
万分感谢!!!
“如果你用的CAN引脚是PA11和PA12,接收中断用CAN1_RX0_IRQn。如果CAN引脚用的是PB8和PB9,也就是用重定义的引脚,接收中断用CAN1_RX1_IRQn。由于PA11和PA12也是USB的引脚,所以非互联型且带CAN控制器的微控制器的库文件在起名字时用了USB_LP_CAN1_RX0_IRQn。”
以上内容参考于网络,后经证实,以上说法是不正确的,理由如下:
STM32有2个3级深度的接收缓冲区:FIFO0和FIFO1,每个FIFO都可以存放3个完整的报文,它们完全由硬件来管理。如果是来自FIFO0的接收中断,则用CAN1_RX0_IRQn中断来处理。如果是来自FIFO1的接收中断,则用CAN1_RX1_IRQn中断来处理。在CAN的初始化配置过程中,用CAN_FilterFIFOAssignment来选择要使用FIFO。
示例如下:
1. 配置过滤器
CAN_FilterInitStructure.CAN_FilterNumber = 0;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0; //关联FIFO0
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
CAN_FilterInitStructure.CAN_FilterNumber = 14;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 1; //关联FIFO1
CAN_FilterInit(&CAN_FilterInitStructure);
2. 开启CAN中断
CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
CAN_ITConfig(CAN1, CAN_IT_FMP1, ENABLE);
CAN_ITConfig(CAN2, CAN_IT_FMP0, ENABLE);
CAN_ITConfig(CAN2, CAN_IT_FMP1, ENABLE);
3. 中断处理函数
void CAN1_RX0_IRQHandler(void)
{
CAN_Receive(CAN1, CAN_FIFO0, &CAN1_RxMsg);
//
}
void CAN1_RX1_IRQHandler(void)
{
CAN_Receive(CAN1, CAN_FIFO1, &CAN1_RxMsg);
//
}
void CAN2_RX0_IRQHandler(void)
{
CAN_Receive(CAN2, CAN_FIFO0, &CAN2_RxMsg);
//
}
void CAN2_RX1_IRQHandler(void)
{
CAN_Receive(CAN2, CAN_FIFO1, &CAN2_RxMsg);
//
}