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_t TransmitMailbox) { uint32_t state = 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应用 适用型号:AT32F403、AT32F413、AT32F415、AT32F403A、AT32F407 主功能:CAN 次功能:无
|