硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3277|回复: 0
收起左侧

[客户分享] AT32 MCU关于CAN问题应用说明

[复制链接]

41

主题

1

回帖

124

积分

初级会员

积分
124
发表于 2021-7-22 20:24:28 | 显示全部楼层 |阅读模式
Questions1:CAN接收报文数据错位问题
在使用CAN时,当在接收数据域期间CAN总线上出现异常(该异常通常可能由采样点漂移、或外部干扰等原因导致)时,可能会出现接收数据位填充错误导致整帧数据错位的现象, 且后续帧又自动恢复正常的现象。
Answer
此问题可通过软件进行修正,处理方案如下。
开启CAN的上次错误中断号对应的错误中断,在CAN错误中断的中断函数内检测到出现位填充错误时,复位CAN(可只复位CAN寄存器,其相关的GPIO等、NVIC不需复位),并重新调用CAN初始化函数。以CAN1为例,其典型示例代码如下:
         __IO uint32_t err_index = 0;
void CAN1_SCE_IRQHandler(void)
{
                if(CAN_GetINTStatus (CANx,CAN_INT_LEC) == SET )
                {
                        err_index= CAN1->ESTS;
                            CAN_ClearINTPendingBit(CANx, CAN_INT_LEC);
                                if(err_index& 0x00000010) ///<判定是否出现位填充错误
                                {
                             CAN_Reset(CAN1);
                             /*调用CAN初始化函数*/;
                                }
                }
}

Questions2:CAN报文被异常多发问题
在使用CAN时,若禁止硬件自动重传功能,且又透过软件查询发送状态来达到自动重传效果时,可能会出现某一时刻的某帧报文被异常多发一次的现象。
Answer
造成此问题的根本原因是CAN的“发送完成标志与“发送成功或失败标志非同步置位(间隔一个PCLK)。
此问题可通过使用BSP 1.3.0版本后的CAN驱动(也可按照如下代码方式修改对应的驱动文件),或直接使用硬件自动重传功能来解决:
uint8_t CAN_TransmitStatus(CAN_Type* CANx, uint8_tTransmitMailbox)
{
  uint32_tstate = 0;
  switch (TransmitMailbox)
  {
    case(CAN_TXMAILBOX_0):
     if((CANx->TSTS & CAN_TSTS_RQC0) == CAN_TSTS_RQC0)
      {
       if((CANx->TSTS & CAN_TSTS_TOK0) == CAN_TSTS_TOK0)
        {
         state = CAN_TxStatus_Ok;
        }
        else
        {
         state = CAN_TxStatus_Failed;
        }
      }
      else
      {
        state= CAN_TxStatus_Pending;
      }
      break;

    case(CAN_TXMAILBOX_1):
     if((CANx->TSTS & CAN_TSTS_RQC1) == CAN_TSTS_RQC1)
      {
       if((CANx->TSTS &  CAN_TSTS_TOK1)== CAN_TSTS_TOK1)
        {
         state = CAN_TxStatus_Ok;
        }
        else
        {
         state = CAN_TxStatus_Failed;
        }
      }
      else
      {
        state= CAN_TxStatus_Pending;
      }
      break;

    case (CAN_TXMAILBOX_2):
     if((CANx->TSTS & CAN_TSTS_RQC2) == CAN_TSTS_RQC2)
      {
       if((CANx->TSTS & CAN_TSTS_TOK2) == CAN_TSTS_TOK2)
        {
         state = CAN_TxStatus_Ok;
        }
        else
        {
         state = CAN_TxStatus_Failed;
        }
      }
      else
      {
        state= CAN_TxStatus_Pending;
      }
      break;

    default:
      state =CAN_TxStatus_Failed;
      break;
  }
  return(uint8_t) state;
}

类型:MCU应用
适用型号AT32F403AT32F413AT32F415AT32F403AAT32F407
主功能:CAN
次功能:无

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-6-8 21:05 , Processed in 0.156456 second(s), 23 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表