应当初始化之前加入这个函数,退出休眠模型

  CAN1_RecoverHwState();
  MX_CAN1_Init();

CAN1_RecoverHwState()函数定义如下,有多个can通信使用就多个退出休眠模式函数:

/**
  * @brief  清除睡眠/初始化残留,避免 MCR 中 INRQ+SLEEP 与 MSR.SLAK 卡死
  */
static void CAN1_RecoverHwState(void)
{    
  //开启CAN1外设时钟,寄存器访问前提(时钟关闭无法读写MCR/MSR)
  __HAL_RCC_CAN1_CLK_ENABLE();

  if ((CAN1->MSR & CAN_MSR_SLAK) != 0U)//判断:硬件确认当前处于睡眠SLAK=1
  {
    CLEAR_BIT(CAN1->MCR, CAN_MCR_SLEEP);//软件清SLEEP=0:发起退出睡眠请求
    uint32_t tickstart = HAL_GetTick();

    //循环等待硬件应答SLAK硬件自动清零,100ms超时防死锁
    while ((CAN1->MSR & CAN_MSR_SLAK) != 0U)
    {
      if ((HAL_GetTick() - tickstart) > 100U)
      {
        break;
      }
    }
  }
  //清除残留初始化请求INRQ=1(解除初始化锁定)
  if ((CAN1->MCR & CAN_MCR_INRQ) != 0U)//判断:寄存器残留INRQ=1(上次异常退出卡在初始化模式)
  {
    CLEAR_BIT(CAN1->MCR, CAN_MCR_INRQ);//清INRQ=0:退出初始化请求
    uint32_t tickstart = HAL_GetTick();

    //等待硬件应答INAK=0(硬件确认退出初始化模式),100ms超时保护
    while ((CAN1->MSR & CAN_MSR_INAK) != 0U)
    {
      if ((HAL_GetTick() - tickstart) > 100U)
      {
        break;
      }
    }
  }
}

#can2
static void CAN2_RecoverHwState(void)
{    
  //开启CAN1外设时钟,寄存器访问前提(时钟关闭无法读写MCR/MSR)
  __HAL_RCC_CAN2_CLK_ENABLE();

  if ((CAN2->MSR & CAN_MSR_SLAK) != 0U)//判断:硬件确认当前处于睡眠SLAK=1
  {
    CLEAR_BIT(CAN2->MCR, CAN_MCR_SLEEP);//软件清SLEEP=0:发起退出睡眠请求
    uint32_t tickstart = HAL_GetTick();

    //循环等待硬件应答SLAK硬件自动清零,100ms超时防死锁
    while ((CAN2->MSR & CAN_MSR_SLAK) != 0U)
    {
      if ((HAL_GetTick() - tickstart) > 100U)
      {
        break;
      }
    }
  }
  //清除残留初始化请求INRQ=1(解除初始化锁定)
  if ((CAN2->MCR & CAN_MCR_INRQ) != 0U)//判断:寄存器残留INRQ=1(上次异常退出卡在初始化模式)
  {
    CLEAR_BIT(CAN2->MCR, CAN_MCR_INRQ);//清INRQ=0:退出初始化请求
    uint32_t tickstart = HAL_GetTick();

    //等待硬件应答INAK=0(硬件确认退出初始化模式),100ms超时保护
    while ((CAN2->MSR & CAN_MSR_INAK) != 0U)
    {
      if ((HAL_GetTick() - tickstart) > 100U)
      {
        break;
      }
    }
  }
}

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐