(一)CAN初始化失败原因
(1)Check acknowledge error
CAN收发器在CAN初始化之前,STB引脚接地,CAN收发器要正常供电状态。
如果CAN收发器没有正常供电,任何一路没有供电都会会造成CAN初始化失败。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /* Wait the acknowledge */ wait_ack = 0; while (((CANx->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) && (wait_ack != INAK_TIMEOUT)) { wait_ack++; } /* ...and check acknowledged */ if ((CANx->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { InitStatus = CAN_InitStatus_Failed; printf("Check acknowledge error 2\n"); } else { InitStatus = CAN_InitStatus_Success ; } |
CAN收发器在CAN初始化之前,没有供电,会造成INAK位,CAN_Rx引脚无法检测到连续11位的隐形电平,使得硬件无法清零,导致CAN初始化失败。
(2)boot0引脚是否默认接地,启动模式为:选择主 Flash 作为自举空间
(3)CAN因波特率不同导致初始化失败
CAN因波特率不同导致初始化失败
(4)CAN的Rx和Tx引脚外接上拉电阻导致初始化失败
外接上拉电阻初始化失败
(5) 检查CAN收发器的STB引脚是否正常接地
STB引脚低电平有效,默认接地:此时为正常工作状态
STB引脚拉高时:此时为低功耗工作状态
(6)电源电压不足:BAT-12V,电源电压不足或者电源电压不稳定,导致CAN初始化失败,内部晶振无法工作、
(7)CAN引脚复用重映射,导致GPIO引脚的初始化参数不对
重映射CAN引脚需要打开RCC_AFIO时钟:以stm32f10x为例
注意:复用为默认引脚时,不需要开启此RCC_AFIO时钟。
1 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, EABLE); |
(二)CAN2 (Slave CAN)通信失败原因
没有在初始化CAN2之前,先打开主CAN:CAN1的RCC时钟。因为CAN2通信依赖于CAN1片上器件的使能。
经测试,在使用CAN2之前,一般只需要打开主CAN1的RCC时钟,CAN2即可正常工作。
1 2 3 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1 | RCC_APB1Periph_CAN2, ENABLE); // void CAN_SlaveStartBank(uint8_t CAN_BankNumber); CAN_SlaveStartBank(14); |
(三)CAN收发器供电不正常,造成的初始化问题
(四)过滤器初始化过程中,出现初始化卡死,停止不动问题
(1)设备刚上电,CAN过滤器初始化进行中程序卡住阻塞,现象:
(2)设备刚上电,CAN和过滤器初始化也都完成,但是在CAN_TEST_TOOL测试上位机发送 id 时,主程序继续卡住阻塞,CAN_TEST_TOOL测试上位机停止发送id时,主进程仍然退不出来。添加打印信息也无法检测出问题所在的地方。
原因分析:经过检查发现,CAN初始化过程中,打开了CAN中断,但是并没有写CAN的中断处理函数,导致程序一直: B . (查看汇编时发现),即在当时现场一直跳转到当前位置,无法退出。
(五)发送邮箱出现 No Mail
如果软件配置没有问题,则需要用示波器检查CAN收发器的Rx和Tx引脚是否有数据波形,其次还需要检查CAN收发器的VCC供电电压是否开启,以及不同CAN收发器芯片的VCC供电电压不同(一般是3.3V,但是也有5V供电的),需要查看一下数据手册是否满足其要求。
(六)CAN时钟分析
STM32系统时钟 CAN时钟配置分析:参考 CAN时钟配置.