STM32学习笔记(四)--CAN通信



  • CAN协议学习笔记

    最近在调试CAN协议,CAN协议比我之前学过的协议都要复杂,形式也比较独特,在将近一周的时间里,从初步了解CAN协议,在物理层面上去理解CAN通信方式,到最终写出CAN通信代码,我遇到了很多困难,在这里,写一篇笔记来记录我之前的工作。

    首先,了解一下CAN协议的物理架构。
    CAN的主要部分是CAN总线,总线分为两种连接方式,第一种为闭环总线网络,一种为开环总线网络,见下图(图片来源https://www.cnblogs.com/firege)

    闭环总线网络
    0_1601517393239_8d342a55-bf59-4e2e-b6ca-53a70ec02a75-image.png

    开环总线网络
    0_1601517408305_338bfeb9-a96d-458a-9a6a-d837763f26f4-image.png

    CAN总线上可以接入很多设备,其中,每一组接入总线的CAN控制器与收发器,都被称为通讯结点,CAN通讯的通信方式则利用了两条线(CAN_High,CAN_Low)上的差分电压,当CAN_High上的电压高于CAN_Low的电压时,逻辑电平为0,为显性电平,若CAN_High的电压不高于CAN_Low的电压,逻辑电平则为1,为隐性电平,具体的电平关系如下表所示:
    0_1601517482837_ea578953-97a4-4416-8717-ecf73b4c7a0d-image.png
    0_1601517505507_eb32b2ed-46de-433d-aa57-7074587922a8-image.png

    当显性电平0遇到隐性电平1时,表现为显性电平(这一点在后面的仲裁段会得以体现)

    接下来,是CAN通信的协议层。
    由于CAN通信不像IIC协议之类拥有时钟线,因此,如何实现通讯的同步就成为了一个很关键的问题。
    想要达到步调一致的目的,首先,要统一好通信的频率。
    因此,第一步应当设置好波特率,调试C610时,CAN总线的频率为1KHz
    另外,CAN协议为了保证通讯过程中不会出现偏差,特地设置了位时序,一个总线上的数据位可以分解成多个Tq,其中,Tq是CAN协议中一种时间的计量单位。
    在一个数据位的位时序中,可以分解为四段,分别为SS段,PTS段,PBS1段,PBS2段,如下图所示
    0_1601517533447_424856b1-ef91-4ca8-bc4e-95f28a3a823d-image.png
    SS段称为同步段,时间长度固定为1Tq,SS段的作用是,CAN协议可以控制上升沿落在SS段以内,如果上升沿落在了SS段外,CAN协议可以自动调整时间,使时间重新匹配,后续说明调整时间的方法
    PTS段称为传播时间段,由于物理线路传播信息需要一定时间,PTS段则是要补偿这段时间,PTS段的时间可以自行设置,一般为1~8Tq。
    PBS1和PBS2都是用来使时间同步的,电平采样点也设置在二者中间,其中,PBS1用来加长以满足同步,PBS2用来缩短以满足同步,之所以这样设置,是有原因的。

    下面,解释CAN协议如何同步时间

    上升沿超前的情况:
    当上一个总线电平位还处在PBS2阶段时,下一个电平位的上升沿已经来了,这时候,当总线检测到上升沿时,会中断掉PBS2,直接发起下一个电平的SS段来和总线电平匹配,因此,可以发现上升沿之前的PBS2段被缩短了。

    上升沿滞后的情况
    当上一个总线电平的PBS2已经结束,下一个电平的SS段已经发起时,SS段结束了也没有接收到上升沿,上升沿落到了后面的PTS段或PBS1段(采样点之前,否则会导致发送的报文出错)(事实上,CAN协议会设置允许的最大偏差,超过这一长度的偏差会被认为是错误,通常,这一偏差设置为3Tq,偏差太小,容错率低,偏差太大,会拖慢通讯速度),这时,CAN协议会记录偏差的长度,并在PBS1段加上同样长度的延时,这一举措事实上保证了采样点在每一个电平位上的相对位置基本是稳定的,保证了CAN协议通信的稳定性。

    接着是CAN协议的报文结构。
    CAN协议的报文分为五种格式,分别为数据帧,遥控帧,错误帧,过载帧,帧间隔。这五种帧的用途见下表:
    0_1601517555662_04f854b5-3e26-4dd4-b48d-0c0a0a953ba2-image.png

    各种帧的发送格式如下:
    0_1601517575573_0fe5de03-00c0-4cf2-8d91-8dfd194a095d-image.png

    重点来描述一下数据帧
    0_1601517620401_cd4f43c6-5896-404d-bf5c-76507e019461-image.png

    图中标注的数字表示这一段有多少个总线电平,而每一个总线电平,又由前面所说的SS段,PTS段,PBS1,PBS2四段组成。
    CAN协议的独特之处,不仅在于他采用了差分电平,还在于独特的仲裁方式。
    数据帧当中,有一段叫做仲裁段,仲裁段的作用在于,判断发送数据的从机的优先级,CAN通信会先传递优先级高的数据。

    仲裁原理如下图
    0_1601517646701_784f1a80-7c29-4cf7-8d4f-3f67c146e321-image.png

    之前描述过,当显性电平0遇到隐性电平1时,总线上会表现为显性电平0,正是利用这一点,当一个从机发送0,而另一个从机发送1时,总线电平会表现为0,这个时候,总线电平就和第二个从机所发送的电平不同,第二个从机在这次仲裁中失败了,失去了继续发送数据的权力,转而接收数据。

    CAN协议的好处是,仲裁段本身位于数据帧内,仲裁结果出来之后,不需要获胜的从机重新发送数据,而是继续发送这一数据帧即可,而且仲裁段本身就是从机的地址(标准格式下),这一定程度上节约了时间。

    了解完CAN协议的基本模式之后,CAN协议有四种测试方式
    分别为正常模式,静默模式,回环模式,回环静默模式。
    所谓静默,就是不改变总线的电平,自己将数据交给自身的接收端,回环则是CAN总线上只有一个设备,自发自收。

    STM32规定的位时序与前面所讲的略有不同,STM32将PTS和PBS1合为一段,叫做PBS1段。段长度可设置

    STM32CAN收发数据需要通过Tx邮箱和Rx的FIFO接收邮箱,一个FIFO有三个邮箱,可以缓存三个报文,可以采用接收中断的方式来读取数据。

    在编写程序时,就要先进行CAN协议的初始化(端口初始化:一些端口作为CAN的Tx和Rx端口的时候,需要重映射;时钟,中断配置;总线电平三段时间的设置;还要设置CAN过滤器)。发送数据则需要配置Tx邮箱,然后通过调用库函数来将邮箱中的数据以CAN协议的格式发送出去。接收数据则利用中断读取,中断服务函数中,只需要调用函数读取FIFO邮箱中的信息即可。



  • 更正一处错误,CAN协议通信比特率为1Mbps,笔误写成了1k


 

Copyright © 2018 bbs.dian.org.cn All rights reserved.

与 Dian 的连接断开,我们正在尝试重连,请耐心等待