在做环回测试时可以正常收发数据并可捕捉到发送报文的波形。现在在做CAN NORMAL模式程序,CAN不能正常收发数据,
关于CAN NORMAL不能正常收发数据
这一个严重的难题,已被卡了好几周了,终于发现问题的关键:
CAN BAUDRATE 没有设置对!!!!!!!!!
过程:根据DATASHEET 要配置成1MBps的CAN BAUDRATE(Pclk
= 48MHZ)以下三个重要参数为:
BS1 = 4 ――CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq
BS2 = 3, ――CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq
prescaler = 6 ―― CAN_InitStructure.CAN_Prescaler = 6;
而实际我的STM板子和USB-CAN之间的CAN BAUDRATE只须要500KBps,我的CAN BAUDRATE设置如下:
CAN_InitStructure.CAN_BS1 =
CAN_BS1_4tq
CAN_InitStructure.CAN_BS2 =
CAN_BS2_3tq
CAN_InitStructure.CAN_Prescaler
= 12;
发现还是不能收发………………
直到用尝试到 以下代码:
CAN_InitStructure.CAN_BS1 =
CAN_BS1_4tq
CAN_InitStructure.CAN_BS2 =
CAN_BS2_3tq
CAN_InitStructure.CAN_Prescaler
= 2;
这时我的STM板子发送的CAN报文便可以在USB-CAN上可以接收的到了(但STM板子接收不到USB-CAN的报文),就在这我很大的疑问啦,根据以下公式:
上图来自DATASHEET,以Pclk = 48MHZ算得CAN BAUDRATE是 3MHZ,被吓一跳,此刻,我就怀疑Pclk != 48MHZ,(查 HES ,没有起振)当我在DATA SHEET 的RCC这一章的HIS中的以下说明
意思是:如果HSE振荡器失效,HIS(8MHZ)时钟就会被作为备用时钟源且RCC_CFGR->HPRE = 0 && RCC_CFGR-> PRE = 0 所以Pclk =8MHZ,此时再以以下代码
CAN_InitStructure.CAN_BS1 =
CAN_BS1_4tq
CAN_InitStructure.CAN_BS2 =
CAN_BS2_3tq
CAN_InitStructure.CAN_Prescaler
= 2;
得 CAN BAUDRATE =500KBps
额外知识:CAN BAUDRATE计算
按以下公式:
设 TS1[3:0] 为 x
设 TS2[2:0] 为 y
设 BRP[9:0] 为 Z;
T = T(Pclk) =
1/f(Pclk);
tq = (z + 1) * T
tBS1 = tq * (x +
1)
tBS2 = tq * (y +
1)
NominalBitTime = tq + tBS1 + tBS2,代入以上等式最终
NominalBitTime =
(3 + x + y) * (z + 1) * T
BaudRate=
1/NominalBitTime= 1/((3 + x + y) * (z + 1) * T) 最终得
BaudRate= f(Pclk)
* 1/((3 + x + y) * (z + 1));
按以上公式 设f(Pclk) = 48 MHZ, 把CAN BAUDRATE配置成1 MHZ, 则
x = 3 &&
y = 2 && z =5 便可, 代码为
CAN_InitStructure.CAN_BS1 =
CAN_BS1_4tq
CAN_InitStructure.CAN_BS2 =
CAN_BS2_3tq
CAN_InitStructure.CAN_Prescaler
= 6;
注:我工程的GPIO配置如下
//CAN RX CONFIG
GPIO_CAN_Input.GPIO_Pin = GPIO_Pin_11;
GPIO_CAN_Input.GPIO_Speed =
GPIO_Speed_Level_2;
GPIO_CAN_Input.GPIO_Mode = GPIO_Mode_AF;
GPIO_CAN_Input.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA,&GPIO_CAN_Input);
//CAN TX CONFIG
GPIO_InitStructure.GPIO_Pin =
GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed =
GPIO_Speed_Level_2;
GPIO_InitStructure.GPIO_Mode =
GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType =
GPIO_OType_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
遗憾的是我STM板还是不能收!!
|