笔者来聊一下CAN协议帧的认识和错误处理。
CAN 差分信号,是经过CAN收发器转成差分信号的,CAN RX和TX是逻辑电平。CAN的基础知识,可参考笔者这边文章:ARM学习(21)STM32 外设Can的认识与驱动编写。
CAN总线上面要接120欧姆的电阻,形成闭环。
CAN的总线电平:
CAN的协议帧主要有:
下面是:帧起始,ID,控制段
中间是:数据段和CRC段
最后是:ACK段和帧结束
CAN异常处理,首先得知道CAN有哪些异常,LEC 可以指示错误信息:
如果CAN总线异常,那么可以增加相关寄存器打印,可以知道CAN的错误。
printf("CAN_TX_TIMEOUT, ESR=0x%x, TSR=0x%x, IER=0x%x\r\n",CAN2->ESR,CAN2->TSR,CAN2->IER);
当然也可以通过中断触发,但是中断触发有个问题,如果总线一直异常,那么会一直触发,导致持续进中断,程序无法正常运行。
关于CAN异常中断的配置,首先需要知道异常会触发哪个中断,然后需要使能相应的中断源,以及中断函数。
CAN共计四个中断,前三个中断很容易理解,就是下图的三个中断
......
CAN_ITConfig(CAN2, CAN_IT_ERR);
CAN_ITConfig(CAN2, CAN_IT_EWG);
CAN_ITConfig(CAN2, CAN_IT_EPV);
CAN_ITConfig(CAN2, CAN_IT_BOF);
CAN_ITConfig(CAN2, CAN_IT_LEC);
NVIC_InitStructure.NVIC_IRQChannel = CAN2_SCE_IRQn;
NVIC_InitStructure.IRQChannelCmd =ENABLE;
NVIC_Init(&NVIC_InitStructure);
void CAN2_SCE_IRQHandler(void)
{
printf("CAN ESR=0x%x\r\n",CAN2->ESR);
CAN_ClearITPendingBit(CAN2, CAN_IT_ERR);
CAN_ClearITPendingBit(CAN2, CAN_IT_EWG);
CAN_ClearITPendingBit(CAN2, CAN_IT_EPV);
CAN_ClearITPendingBit(CAN2, CAN_IT_BOF);
CAN_ClearITPendingBit(CAN2, CAN_IT_LEC);
}