-【问题背景】-
在使用CAN交互过程中,如果短接CAN_H和CAN_L,或者CAN_H接地,或者CAN总线上有较大的干扰,接收方STM32出现了无法触发CAN数据接收中断,则程序无法再接收数据,MCU本身未死机。复位后能正常收发。

-【解决】-
CAN初始化时开启自动离线管理功能即可
CAN_InitStructure.CAN_ABOM=ENABLE; //开启自动离线管理
以上是标准库的情况,使用HAL库同理。

-【分析】-
根据ISO11898有如下几个重要的与CAN相关的定义:

  • Fault confinement(错误界定)
    CAN nodes shall be able to distinguish short disturbances from permanent failures. Defective transmitting nodes shall be switched off. Switched off means a node is logically disconnected from the bus, so that it can neither send nor receive any frames.

CAN节点可以区分常规错误和永久故障。有故障的发送节点将切换到离线状态。离线意味着在逻辑上与总线断开,既不能发送也不能接收。

  • Error-active(主动错误)
    An error-active node shall normally take part in bus communication and send an active error flag when an error has been detected. The active error flag shall consist of six (6) consecutive dominant bits and shall violate the rule of bit stuffing and all fixed formats appearing in a regular frame .

处于主动错误状态的节点能正常参与总线通信的收发和当检测到错误时将发送错误标志,错误标志由6个连续的显示位组成(这种连续的6个显示位与常规的填充位和其它帧固定格式不相同,正因为如此,硬件才容易区别)。

  • Error-passive(被动错误)
    An error-passive node shall not send an active error flag. It takes part in bus communication, but when an error has been detected a passive error flag shall be sent. The passive error flag shall consist of six (6) consecutive recessive bits. After transmission, an error-passive node shall wait some additional time before initiating a further transmission .

处于被动错误状态的节点不能发送主动错误标志。它能参与正常通信,但当检测到错误时发送的是被动错误标志。被动错误标志由6个连续的隐性位组成。当发送结束后,处于被动错误状态的节点在下一次再次发送时之前需要等待一些额外时间。

  • Bus-off(离线)
    A node shall be in the bus-off state when it is switched off from the bus due to a request of FCE. In the bus-off state, a node shall neither send nor receive any frames. A node shall start the recovery from bus-off state only upon a user request.

由于错误界定规则,一个节点可能处于离线状态,当处于此状态时,这个节点既不发送也不接收。至于何时离线恢复取决于何时用户请求。

ISO11898中错误界定的规则

1.描述
当涉及到错误界定,一个节点必须处于下述三个错误状态中的其中一个,至于具体是哪种错误状态取决于节点的错误计数值:

主动错误状态(Error-active)
被动错误状态(Error-passive)
离线状态(Bus-off)

2.错误计数
错误计数器当检测下下述事件时将修改错误计数值:

当一接收节点检测到一个错误时,错误计数器将加1.有一种情况可以排外,即当检测到发送一主动错误标志或者重载标志时出现一位错误时除外。
当一接收节点发送一错误标志时,检测到首位为显性位时,错误计数器加8.
当一发送节后发送错误标志时,错误计数器加8,这时有两种情况除外:1:当这个发送节点处于主动错误状态下,且检测到由于ACK域未有显性位而造成的ACK错误,但是在发送时未检测到被动错误标志;2:当发送节点发送一错误标志时,在仲裁时检测到填充位错误(这些填充位原来应该是隐性,但检测结果为显性)。以上两种异常错误计数值保留原值不变。
当发送节点发送一主动错误标志或重载标志时,检测到位错误时,错误计数器加8.
当接收节点娄送一主动错误标志或重载标志时,检测到位错误时,错误计数器加8.
任何节点在发送主动错误标志,被动错误标志,或重载标志时都应都忍受连续7个显示位。当检测到连接14个显示位,或者被动错误标志后紧跟着连接8个显示位,或者8个连续显性位后紧跟着被动错误标志时,所有发送节点发送错误计数器加8,所有接收节点接收错误计数器加8.
发成功发送一帧报文后,发送计数器应减1,除非当前已经为0.
当成功接收一帧报文后,如果当前接收计数器的值大于1且小于127,则接收计数器减1;如果接收计数器的值为0,则保持为0;如果在于127,则接收计数器的值应设置 为119~127之间的值。

3.主动错误状态和被动错误状态之间的转变
当发送错误计数器或者接收错误计数器的值大于127时,该节点变成被动错误状态。

当节点从主动错误状态变为被动错误状态时,节点将发送一主动错误标志。

当被动错误节点的发送错误计数器和接收错误计数器的值都小于且等于127时,将再次变为主动错误状态。

4.离线管理
如果一个节点的发送错误计数器的值超过255时,那么此节点将会处于离线状态。处于离线状态的节点不会对总线产生任何影响,它将不会发送消息帧,ACK,错误帧,过载帧等,至于会不会接收总线上的数据,取消于此节点的实现。

当一个处于离线状态下的节点接收到128次连接11位隐性位时,将变成主动错误状态,且同时设置发送错误计数器和接收错误计数器为0.

STM32的CAN错误管理机制详见参考手册:

从上图可以看出,STM32的CAN错误管理机制与ISO11898基本一致。只是进入离线模式后,在STM32是有一开关来设置是否会自动还原到主动错误状态,如果此功能禁止了,那么当处于离线状态下的节点接收到128次连接11连隐性位时也不会不还原成主动错误状态。

设置自动离线管理开关的寄存器在CAN_MCR中:

下面在STM32F103VET6上测试CAN总线正常通讯时读取相关的寄存器状态:

LEC=0
REC=0
TEC=0
CAN1->ESR=00000000
CAN1->TSR=1C000000
CAN1->RF0R=00000000
CAN1->RF1R=00000000

该段测试代码是:

printf("LEC=%d\r\n",CAN_GetLastErrorCode(CAN1));
printf("REC=%d\r\n",CAN_GetReceiveErrorCounter(CAN1));
printf("TEC=%d\r\n",CAN_GetLSBTransmitErrorCounter(CAN1));
printf("CAN1->ESR=%08X\r\n",CAN1->ESR);
printf("CAN1->TSR=%08X\r\n",CAN1->TSR);
printf("CAN1->RF0R=%08X\r\n",CAN1->RF0R);
printf("CAN1->RF1R=%08X\r\n",CAN1->RF1R);

将CAN_H接地一段时间,使其进入离线状态,读取到相关的寄存器状态:

LEC=80
REC=255
TEC=248
CAN1->ESR=FFF80057
CAN1->TSR=19000008
CAN1->RF0R=00000000
CAN1->RF1R=00000000

LEC=80是十进制,右移4位对应的是101错误代码,即显性位错。

根据ISO11898定义,TEC>255则CAN控制器进入离线模式,测试发现TEC是248,由于248+8=256,已经超过了255,所以停在了248。

由CAN1->ESR=FFF80057可见,低三位都置位了,如下图所示,而这几位按时间顺序应该是首先EWGF置位,然后是EPVF,最后是BOFF。

【关于CAN错误中断】

CAN_IER中的ERRIE位是一个CAN出错中断总开关,只有当它被使能的前提下,EWG、EPV、BOF、LEC四个中的一个或几个出错事件配合各自的中断使能位才能产生出错中断,并统一将CAN_MSR中的错误中断请求ERRI位置1,从而申请CAN错误中断。显然,CAN错误中断的请求标志位是ERRI@CAN_MSR,而不是CAN_ESR中的EWGF\EPVF\BOFF的任一位。


且注意,ERRI出错中断挂号标志需要软件清除,否则会不停触发中断。
清中断示例:

void USB_LP_CAN1_RX0_IRQHandler(void)
{if(SET == CAN_GetITStatus(CAN1, CAN_IT_ERR))//出错中断挂号 {CAN_ClearITPendingBit(CAN1, CAN_IT_ERR);//可以在这里重新初始化CAN}
}

参考:
https://blog.csdn.net/flydream0/article/details/8161418
stm32_can错误中断
https://blog.csdn.net/TOUGH_JIN/article/details/91345597

STM32 CAN错误管理相关推荐

  1. STM32中断优先级的管理(NVIC)

    STM32 NVIC 中断优先级管理 CM3 内核支持 256 个中断,其中包含了 16 个内核中断和 240 个外部中断,并且具有 256级的可编程中断设置. STM32 并没有使用 CM3 内核的 ...

  2. FlexRay网络唤醒、启动和错误管理

    之前给大家深度剖析了实时传输网络FlexRay协议的基本原理.节点经典结构设计以及在主动安全域控制器中的应用示例,今天给大家介绍一下FlexRay网络唤醒.启动和错误管理.

  3. STM32笔记--电源管理

    为什么STM32需要电源管理: 在很多应用场合,对电子设备的功耗要求非常苛刻.如某些传感器信息采集设备,仅靠小型的电池提供电源,要求工作长达数年之久,且期间不需要任何维护.为此,大多数 MCU 都会提 ...

  4. STM32通用FLASH管理软件包——SFUD/FAL

    本次介绍的两个软件包SFUD/FAL都与FLASH有关,并且都可以独立使用或者结合在一起使用,两个软件包都对操作系统无依赖,可以使用裸机移植,也很方便移植到各种系统. 这两个软件包的作者都是armin ...

  5. STM32硬件错误HardFault_Handler的处理方法

    在用Keil对STM32的程序进行仿真时程序有时会跑飞,停止仿真程序会停在HardFault_Handler函数里的死循环while(1)中.这说明STM32出现了硬件错误. STM32出现硬件错误可 ...

  6. stm32 常见错误及原因【持续更新】

    stm32 开发中,经常会出现一些错误,下面总结一些常见错误及可能原因: 1,Default_Handler 出一这个错误 最常见的原因是 开启了中断,但没有对应的中断响应函数 2,HardFault ...

  7. stm32之电源管理(实现低功耗)

    目录 1.硬件原理 2.低功耗模式 3.睡眠模式实验 4.停止模式实验 5.待机模式实验 前言:STM32F10xxx系列产品都有电源管理模块,芯片功耗会影响到一个产品的续航能力:比如在一些终端传感器 ...

  8. MDK KEIL 烧录STM32下载错误:Flash Timeout.Reset the Target and try it again.解决办法(芯片解锁 解除读报护)

    使用keil开发STM32点下载时出现下面的报错: 点确定后: 出现如上情况很可能是该芯片锁死,即设置了读写保护. 解决方法是想办法解锁芯片,可以使用ST-Link配合stlink utility软件 ...

  9. stm32编译错误error: #20: identifier “USART_IT_RXNE“ is undefined

    基于stm32搭建好keil工程框架,编译时出现几十个error,然后仔细看了下,都是些未定义错误. 想到可能时头文件问题,然后重新检查了下头文件的包含关系,仍然存在错误: 然后百度了下类似的问题,发 ...

最新文章

  1. 百度:2020年十大科技趋势
  2. Python常见编译错更新
  3. Linux系统中安装nodejs的步骤教程
  4. spring图片转视频_一直在用的 Spring,你知道它的加载原理吗?
  5. 前端学习(914):offerset和style区别
  6. 【Beta阶段】第四次Scrum Meeting
  7. 小熊的人生回忆(八)
  8. 真香 | 谁说的 StringJoiner 不好!真香警告……
  9. 创建mysql用户并在单个数据库上赋权
  10. 安卓系统车牌离线识别,优秀的车牌识别算法
  11. 怎么打不开电脑计算机呢,双击我的电脑打不开怎么办
  12. Eclipse使用Log4j2的详细教程
  13. 微信公众请求config php,微信公众平台开发之配置与请求_PHP
  14. 关于Navicat 连接 RDS数据库
  15. Unity编写Shader内置各种矩阵和方法介绍
  16. 步进电机控制Proteus仿真
  17. 欧贝通和工行e卡(虚拟visa卡)
  18. mongodb 常用语法
  19. RESTful接口介绍与实现
  20. UML设计系列(6):活动图

热门文章

  1. 海外弱网下的在线视频平台优化实践​
  2. AWS发布低延迟互动直播服务
  3. 关于RTP和SRT之间的互操作性,你需要了解什么?
  4. 数据结构与算法之快速排序
  5. 云计算十年 腾讯新一代企业安全助力云化之路
  6. CORD 4.1:打造实现边缘计算的最佳平台
  7. Kafka史上最详细总结
  8. 《Dream(梦想)》,无力的我,想放弃的我,深深的问自己,什么是梦想!!!
  9. 浅析NameNode/DataNode/SecondaryNameNode源码注释
  10. 使用基本工具类和预编译进行对数据库的增删改查