STM32F1与STM32F4间CAN通信调试

CAN通信的调试不单是软件上的调试,也需要对硬件进行检查。
原文链接:https://www.cnblogs.com/Cloudcan/p/13358095.html

在调通之前一直有两个疑惑干扰判断:(结论在文末)
1.不同的CAN芯片是否存在不兼容。
2.不同型号的STM32是否CAN通信是否存在差异。

STM32F1与STM32F4之间CAN通信的调试过程(仅以STM32F1作介绍[标准库]):
1.确定引脚与资源

 

这里我们使用PB8、PB9来作为CAN通信引脚,单片机上使用CAN1,注意更改引脚映射。

GPIO_PinRemapConfig(GPIO_Remap1_CAN1,ENABLE);

2.确定波特率
我们需要得到的波特率为1Mbps,用户手册上波特率的计算方法如下:

这里看起来比较复杂,展开后为:BaudRate=1/((BRP[9:0]+1)*(1+TS1[3:0]+1+TS2[2:0] + 1)*tPCLK);
由于CAN1挂在在APB1上,tPCLK1为APB1的外设周期,需要知道其频率fPCLK1。

a.求取频率
如果使用标准库可以采用在main函数加两行代码:

    RCC_ClocksTypeDef get_rcc_clock;
    RCC_GetClocksFreq(&get_rcc_clock);

并在调试界面中查看(右键去掉勾选即可查看10进制数)

PCLK1为36MHz即APB1外设频率为36MHz。

如使用CubeMX生成代码,可以方便查看时钟树配置(强烈建议入门STM32的新人尝试CubeMX,可以直观地理解STM32的时钟树)


b.设定波特率

在标准库中CAN通信初始化中有:

CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1=CAN_BS1_9tq;
CAN_InitStructure.CAN_BS2=CAN_BS2_8tq;
CAN_InitStructure.CAN_Prescaler=2;

其中SJW、BS1、BS2分别对应(BRP[9:0]+1)、(TS[3:0]+1)、(TS2[3:0]+1);

当我们设定BRP[9:0]为0时公式可以简化为,BaudRate=1/((1+TS[3:0]+1+TS2[2:0] + 1)*tPCLK)=1/(1+BS1+BS2)/tPCLK;(这就是为何SJW通常取CAN_SJW_1tq)

考虑分频系数Pre=fPCLK1/fPCLK,fPCLK为CAN1的频率:

BaudRate=fPCLK1/((1+BS1+BS2)*Pre);前提SJW取CAN_SJW_1tq;

例如:系统主频72MHz、APB1外设时钟频率fPCLK1=32MHz,当我取SJW=CAN_SJW_1tq,BS1=CAN_BS1_9tq,BS2=CAN_BS2_8tq时BaudRate=32/((1+9+8)*2)=1MHz;

关于疑惑:

由于STM32F1的板子是自己设计并选了新的CAN芯片(便宜),所以一开始会怀疑是CAN芯片的问题。如果两个CAN都芯片支持我们所需求的波特率,实际上都能够通信的,问题在于我的两个设备CAN芯片都是5V供电,而我在调试时其中一个设备直接使用调试器3.3V供电,导致其无法正常工作,所以一直不能收发信息。当然后来发现这个问题之后,使用电源同时给两个设备供电CAN通信就成功了。

另一个关于不同型号STM32无法进行CAN通信的疑惑主要来源于网上的某帖子,仅仅依据芯片主频不一致而得出这样的结论,完全是无稽之谈。一般多个STM32之间CAN通信,只要硬件没问题,同时保证波特率一致,通信上不会有太大问题。

posted @ 2020-07-22 01:45  Cloudcan  阅读(2536)  评论(0编辑  收藏  举报