有没有小伙伴遇到过相同的CAN通讯波特率,却有好多种不同的配置参数,但在实际测试时,却存在相互通讯不上的情况?我就遇到过……
首先我们先来了解一下CAN的位时序,一个位可分为4个段,分别是同步段(SS)、传播时间段(PTS)、相位缓冲段1(PBS1)和相位缓冲段2(PBS2),这些段又由称为Time Quantum(TQ)最小单位来构成。
根据位段的组成,我们可以确定一个CAN通讯时的采样点,这个位置是固定的,设置在PBS1结束的地方。
在 ACM32F070用户手册上也给出了CAN位时序图:
从上图中它由3段组成,分别为同步段(SYNC_SEG)、时间段1(TSEG1)和时间段2(TSEG1),其中时间段1(TSEG1)包含了CAN标准里的传播时间段和相位缓冲段1。
关于CAN通讯波特率的设置,CAN是挂载在APB总结上的,所以CAN的时钟频率跟APB时钟相关,通过BRP进行分频,再通过TSEG1和TSEG2的设置,来确定最终的通讯波特率,计算公式如下:
Baudrate == PCLK / ((1 + (tTSEG1 + 1) + (tTSEG2 + 1)) * 2 * (BRP + 1))
采样点的计算公式如下:
Sample Point = (1 + (tTSEG1 + 1)) / (1 + (tTSEG1 + 1) + (tTSEG2 + 1)) * 100%
根据用户手册中对于BRP、TSEG1和TSEG2这3个寄存器位的取值范围,我们可以通过函数实现,穷举出满足波特率设定值的所有BRP、TSEG1和TSEG2的值,再通过TSEG1和TSEG2的值计算出相对应的采样点百分比,函数实现如下所示:
/*******************************************************************************
* [url=home.php?mod=space&uid=159083]@brief[/url] * @param
* @retval
* [url=home.php?mod=space&uid=1020061]@attention[/url] *******************************************************************************/
void CAN_ConfigParam(uint32_t Baudrate)
{
char *tTSEG1_Param[16] =
{
"CAN_TSEG1_1tq ", "CAN_TSEG1_2tq ", "CAN_TSEG1_3tq ", "CAN_TSEG1_4tq ",
"CAN_TSEG1_5tq ", "CAN_TSEG1_6tq ", "CAN_TSEG1_7tq ", "CAN_TSEG1_8tq ",
"CAN_TSEG1_9tq ", "CAN_TSEG1_10tq", "CAN_TSEG1_11tq", "CAN_TSEG1_12tq",
"CAN_TSEG1_13tq", "CAN_TSEG1_14tq", "CAN_TSEG1_15tq", "CAN_TSEG1_16tq",
};
char *tTSEG2_Param[8] =
{
"CAN_TSEG2_1tq", "CAN_TSEG2_2tq", "CAN_TSEG2_3tq", "CAN_TSEG2_4tq",
"CAN_TSEG2_5tq", "CAN_TSEG2_6tq", "CAN_TSEG2_7tq", "CAN_TSEG2_8tq",
};
uint32_t PCLK = System_Get_APBClock();
for(uint32_t BRP = 0; BRP < 32; BRP++)
{
for(uint32_t tTSEG1 = 0; tTSEG1 < 16; tTSEG1++)
{
for(uint32_t tTSEG2 = 0; tTSEG2 < 8; tTSEG2++)
{
if(Baudrate == PCLK / ((1 + (tTSEG1 + 1) + (tTSEG2 + 1)) * 2 * (BRP + 1)))
{
printf("\r\nBRP:%02d, tTSEG1: %s, tTSEG2:%s, %0.1f%%", BRP, tTSEG1_Param[tTSEG1], tTSEG2_Param[tTSEG2], (float)(1 + (tTSEG1 + 1)) / (float)(1 + (tTSEG1 + 1) + (tTSEG2 + 1)) * 100.0);
}
}
}
}
}
当我们需要设置500k有通讯波特率时,运行结果如下所示:
再结合我们上篇文中参考官方示例配置的CAN参数得知,当PCLK=64MHz,BRP=7,TSEG1=CAN_TSEG1_3tq,TSEG2=CAN_TSEG2_4tq时,当前CAN的通讯波特率为500kHz,采样点百分比50%
我们回到刚开始的问题,其中一种情况就是相同波特率,不一样的采样点,会导致通讯异常的问题;所以我们在一条CAN总线上,尽量需要保证相同通讯波特率的情况,也设置相同的采样点;另外就是建议将采样点设置在75%左右,采样点设置过早可能会由于通讯不稳定判断错误,设置过后也有可能错过采样点的判断。