赞
踩
以前配置CAN参数的BS1
和BS2
参数时认为总线波特率符合要求就可以了,其实同一个波特率可能对应多组参数设置的情况,这时就要从采样点的角度来考虑了。
采样点计算:
(
1
+
B
S
1
)
/
(
1
+
B
S
1
+
B
S
2
)
(1+BS1) / (1 + BS1 + BS2)
(1+BS1)/(1+BS1+BS2)
CiA推荐的采样点设置:当波特率 > 800K采样点75%,当波特率 > 500K采样点80%, 当波特率 <= 500K采样点87.5% 。
再同步补偿宽度(SJW)的设置范围位1-4TQ,相当于CAN总线的采样点可以根据实际情况在1-4个TQ范围内进行调整,这个值大可以增大CAN波特率的容错范围。
可以参考参考手册中位时序部分的描述。
参考连接:https://zhuanlan.zhihu.com/p/38299092
参考文章:
http://www.zlgcan.com/cancaiyang/68/
之前使用CAN总线一直没详细搞清楚,使能的错误中断都具体对应的是什么,使用的时候一下把所有的CAN错误中断都使能上,正好今天遇到的CAN总线的一些问题,详细看了下。
使能所有的CAN错误中断:
/* 使能CAN错误中断 */
HAL_CAN_ActivateNotification(&hcan, CAN_IT_ERROR | CAN_IT_BUSOFF | CAN_IT_ERROR_PASSIVE | CAN_IT_ERROR_WARNING | CAN_IT_LAST_ERROR_CODE);
这里我们要搞清楚ERRIE
和后面LCEIE
,BOFIE
,EPVIE
,EWGIE
几个中断使能的关系:ERRIE相当于错误使能的总开关,其它的错误中断使能相当于分开关,这里我们可以在HAL库的CAN中断处理的部分找到依据,ERRIE中断使能后出错时会将主状态寄存器(MSR)中的ERRI位置位,然后再依次判断有哪些分开关管理的错误中断触发了。
/* Error interrupts management *********************************************/ if ((interrupts & CAN_IT_ERROR) != 0U) { if ((msrflags & CAN_MSR_ERRI) != 0U) { /* Check Error Warning Flag */ if (((interrupts & CAN_IT_ERROR_WARNING) != 0U) && ((esrflags & CAN_ESR_EWGF) != 0U)) { /* Set CAN error code to Error Warning */ errorcode |= HAL_CAN_ERROR_EWG; /* No need for clear of Error Warning Flag as read-only */ } /* Check Error Passive Flag */ if (((interrupts & CAN_IT_ERROR_PASSIVE) != 0U) && ((esrflags & CAN_ESR_EPVF) != 0U)) { /* Set CAN error code to Error Passive */ errorcode |= HAL_CAN_ERROR_EPV; /* No need for clear of Error Passive Flag as read-only */ } /* Check Bus-off Flag */ if (((interrupts & CAN_IT_BUSOFF) != 0U) && ((esrflags & CAN_ESR_BOFF) != 0U)) { /* Set CAN error code to Bus-Off */ errorcode |= HAL_CAN_ERROR_BOF; /* No need for clear of Error Bus-Off as read-only */ } /* Check Last Error Code Flag */ if (((interrupts & CAN_IT_LAST_ERROR_CODE) != 0U) && ((esrflags & CAN_ESR_LEC) != 0U)) { switch (esrflags & CAN_ESR_LEC) { case (CAN_ESR_LEC_0): /* Set CAN error code to Stuff error */ errorcode |= HAL_CAN_ERROR_STF; break; case (CAN_ESR_LEC_1): /* Set CAN error code to Form error */ errorcode |= HAL_CAN_ERROR_FOR; break; case (CAN_ESR_LEC_1 | CAN_ESR_LEC_0): /* Set CAN error code to Acknowledgement error */ errorcode |= HAL_CAN_ERROR_ACK; break; case (CAN_ESR_LEC_2): /* Set CAN error code to Bit recessive error */ errorcode |= HAL_CAN_ERROR_BR; break; case (CAN_ESR_LEC_2 | CAN_ESR_LEC_0): /* Set CAN error code to Bit Dominant error */ errorcode |= HAL_CAN_ERROR_BD; break; case (CAN_ESR_LEC_2 | CAN_ESR_LEC_1): /* Set CAN error code to CRC error */ errorcode |= HAL_CAN_ERROR_CRC; break; default: break; } /* Clear Last error code Flag */ CLEAR_BIT(hcan->Instance->ESR, CAN_ESR_LEC); } } /* Clear ERRI Flag */ __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_ERRI); }
这个位置就是发生CAN错误时,实际要重点关注的位置,这个位置描述了具体是什么错误状态,然后寻找对应的解决办法。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。