欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

STM32 Notes - CAN 采样点设置和错误报告

最编程 2024-04-16 09:09:01
...

STM32笔记---CAN采样点设置和报错

    • 采样点设置
      • 再同步补偿宽度(SJW)设置
    • 报错分析
      • CAN中断使能寄存器
      • CAN错误状态寄存器

采样点设置

以前配置CAN参数的BS1BS2参数时认为总线波特率符合要求就可以了,其实同一个波特率可能对应多组参数设置的情况,这时就要从采样点的角度来考虑了。
采样点计算: ( 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)设置

再同步补偿宽度(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);

CAN中断使能寄存器

在这里插入图片描述
在这里插入图片描述
这里我们要搞清楚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错误状态寄存器

在这里插入图片描述
在这里插入图片描述
这个位置就是发生CAN错误时,实际要重点关注的位置,这个位置描述了具体是什么错误状态,然后寻找对应的解决办法。