CAN通信的用户层设计

关注+星标公众,及时获取更多技术分享~ 

 作者 | 冰茶奥利奥

微信公众号 | 嵌入式电子创客街 


在汽车电子和工业领域里,经常会使用CAN总线方式来进行通信,CAN总线速率高,采用差分通信方式,因此抗干扰性强,常规走线可达十米以上。那么我们需要在实际使用中需要注意哪些问题呢?

CAN协议底层有阻塞和唤醒模式,且有冗余校验和错误帧识别,因此可靠性极高。不同于modbus总线使用485作为通信方式,CAN总线没有主从机之分,总线上的设备均可不定时广播消息,主控制器只需根据帧ID接受相应的有用帧而舍弃其他帧。

现在越来越多的主控制芯片都会集成1到2个CAN控制器,PLC厂商也会提供CAN拓展模块以支持CAN通信(此处不得不吐槽PLC厂商的捆绑销售)。本文将以stm32系列主控芯片为例,重点讲解程序中的要点。

发送部分

大多数芯片的CAN控制器会提供2个以上发送邮箱。所谓发送邮箱,理解为邮差更为合适。当需要向总线发送数据时,要先检查当前是否有空闲邮差,如果能找到空闲邮差则直接发送之,邮差会把你的数据送到总线上。因为发送数据需要时间,所以邮差也有空闲和忙碌一说。当你有多个信息需要发送,则会同时需要多个邮差。

如果邮差都出去送信了,那么此时发送数据一定会是失败的。因此在程序里需要加判断,如果返回值为no_mail,则需要等待。

    /*发送数据,获取邮箱号*/
    mbox = CAN_Transmit(CANx, &TxMessage);
    //若获取邮箱失败,说明发送正忙,需等待重发
    while(CAN_TxStatus_NoMailBox == mbox)
    {
        mbox = CAN_Transmit(CANx, &TxMessage);
        __NOP();
    }

一般芯片的CAN控制器配置有一个选项,叫做自动重传。如果用户使能这个自动重传的功能,当向总线发送数据出错时,软件会一直阻塞在发送函数处,直到数据重传完成。那么我们就可能会想到一种隐患,如果总线脱落,那么设备会由于数据无法发送出去而导致程序阻塞,对工业设备和汽车电子来说这绝对是致命的隐患。

/**
 *MCR-NART  禁止报文自动重传      DISABLE-自动重传    ENABLE-禁止自动重传
 *DISABLE:按照CAN标准,CAN硬件在发送报文失败时会一直 自动重传直到发送成功; 
 *ENABLE: CAN报文只被发送1次,不管发送的结果如何(成功、出错或仲裁丢失)。
 */
CAN_InitStructure.CAN_NART = ENABLE; 

因此我们常规的操作是禁用自动重传,通过软件检测CAN数据发送状态,如果发送失败,则尝试自动重传N次,如果N次均失败,则不会继续传输,而是执行主程序。这样的话,即便CAN设备掉线,也不会影响设备的其他功能的运转。

    /*在设定的时间内等待发送结束,时间到了未发送完亦退出,发送失败,防止假死*/
    while((CAN_TransmitStatus(CANx, mbox) == CAN_TxStatus_Failed) && (Timeout < 0XFFFF))
    {
        Timeout++;    /*等待发送结束*/
    }
    if(Timeout >= 0XFFFF)
    {
        CAN_Transmit(CANx, &TxMessage);
        return 1;     /*发送失败*/  
    }

但是使用软件检测CAN发送状态并不是万能的,这次我就遇到了一个麻烦,由于总线上挂载的一个设备,可能是阻抗匹配的不太好,导致CAN总线通信质量受影响。以下是用示波器截取到的部分质量不太好的数据。黄色线为CAN_H,蓝色线为CAN_L,正常情况下两者形成差分为显性,两者相等为隐形。但是看到最后的7个帧结束位显性电平不干净,疑似是信号反射引起的阻抗不匹配。

 这种情况下,使用寄存器提供的状态检查不能够检查出帧错误了,而是回报的成功状态,因此驱动层软件会误认为发送成功而直接结束。但是反应到总线上,这一帧的数据,一定是被抛弃了,不能被正确接收到。

可疑的是,stm32的CAN控制器确能够检测到这种发送失败,因为当我们使能自动重传后,总线上不再出现丢帧情况,说明stm32对这帧数据进行了重传。

因此,存在一种传输失败的情况,通过读取芯片的寄存器无法得知失败,但芯片的CAN控制器却能够得知失败并进行重传操作。


如果您觉得这篇文章帮到了你,请点赞或者留下您的评论,您的鼓励是我前进的动力~

关注博主公众号 “嵌入式电子创客街” 获取更多及时技术分享~

  关注+星标公众,及时获取更多技术分享~ 

 

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值