通信协议:CAN的位同步和帧格式解析(二)


上一篇文章已经简述了CAN总线的一些基本特性和数据的时序位的构成,接下来分析CAN总线的协议构成!


CAN的位同步 & 数据同步

(1)CAN 的位同步

在CAN中使用了 “位同步” 的方式来抵抗干扰、吸收误差,实现对总线电平信号的正常采样,确保通讯正常进行。同时,这个位同步也是用于调节通信过程中的采样点的。


(2)CAN 的数据同步

CAN的数据同步使用到SS段、PTS段、PBS1段、PBS2段,并且数据的同步分为硬同步、重新同步。

1)硬同步

CAN节点希望通过总线发送数据时,会发送一个由高变低的下降沿作为通讯的起始信号;而节点不发送数据时会时刻检测总线上的信号。

一个硬同步的过程如下图示例:

从上图中可以看到当总线上出现了帧起始信号时,某一个节点检测到总线的帧起始信号不在该节点内部时序的 SS 段范围,所以就可以判断它自己的内部时序与总线不同步,因而这种状态下的采样点采集得的数据是不正确的。所以节点以硬同步的方式调整,把自己的位时序中的 SS 段平移至总线出现下降沿的部分,获得同步,同步后采样点就可以采集得正确数据了


2)重新同步

硬同步是存在帧起始信号时才起作用,但是假如是一帧很长的数据,这一长串数据内不再出现帧起始信号,那么在节点信号与总线信号出现相位偏移时,用硬同步方式就行不通了。

所以就有了重新同步的方式,这种方式利用普通数据位的电平的高至低的跳变沿来同步同样都是在 SS 段中进行检测,从而实现同步的目的。

注意:同步的目的都是为了能在节点内的 SS 段把跳变沿包含起来。

重新同步可以细分为两种同步方式:相位超前重新同步和相位滞后重新同步。这两种方式以总线跳变沿与 SS 段的相对位置进行区分的。


3)相位超前重新同步

如下图所示:

上图中可以看到,节点的SS段相对于总线的边沿跳变往前了两个Tq的时间,即节点的时序比它检测的总线时序相对超前了2Tq。

解决这个问题可以在下一个位时序中的PBS1段增加2Tq的时间长度,使得节点与总线时序重新同步,如下图:


4)相位滞后重新同步

如下图所示:

上图中可以看到,节点的SS段相对于总线的边沿跳变延迟了两个Tq的时间,即节点的时序比它检测的总线时序相对落后了2Tq。

解决这个问题可以在下一个位时序中的PBS2段减少2Tq的时间长度,使得节点与总线时序重新同步,如下图:


CAN的帧种类和用途

CAN的帧种类有如下几种:

特别地,数据帧和遥控帧有标准格式和扩展格式两种格式。

标准格式 — 有 11 个位的标识符 ID

扩展格式 — 有 29 个位的 标识符 ID


CAN总线的数据帧

数据帧一般由 7 个段构成,即:

这几个段的作用如下:

1) 帧起始。表示数据帧开始的段。

2) 仲裁段。表示该帧优先级的段,即ID信息。

3) 控制段。表示数据的字节数及保留位的段。

4) 数据段。数据的内容,一帧可发送 0~8 个字节的数据。

5) CRC 段。检查帧的传输错误的段。

6) ACK 段。表示确认正常接收的段。

7) 帧结束。表示数据帧结束的段。


CAN的数据帧有标准格式和扩展格式两种,这两者不同的地方如下图如下:

数据帧的标准格式和扩展格式两者的不同之处主要在于仲裁段中,控制段中有细微的不同。

1)标准格式的ID是11位。

从ID28到ID18一次发送,禁止高7位都为隐形(禁止ID=1111111XXXX)。

2)扩展格式的ID有29个位。

基本ID从ID28到ID18,扩展ID由ID17到ID0表示。基本ID和标准格式的ID相同。

RTR位:帧选择位

0:数据帧 1:远程帧

IDE位:

0:标准标识符 1:扩展标识符

SRR位:

远程请求位,为隐形位,代替了标准帧中的RTR位。

r0、r1位:

保留位,发送时必须全部是显性电平,但是接收时可以是显性、隐形、任意组合的电平。


(1)起始帧

CAN的数据帧和远程帧开始发送时,是需要发送一个开始的标志的,称之为帧起始。它是一个显性位(逻辑0)。

一个CAN节点只有在总线处于空闲状态时才可以发送起始帧。


(2)仲裁段

起始帧发送完成之后,紧接着发送出的就是仲裁段的数据。

CAN2.0A的仲裁场一共有12位,如下图所示。

在这12位中,前11位表示的是11位标识符,第12位是远程发送请求RTR。在数据帧中RTR为显性,在远程帧中RTR为隐性。

如果相同标识符的数据帧与远程帧发生冲突,数据帧优先。

CAN2.0B的仲裁场一共有32位,它在CAN2.0A的基础上,将CAN ID扩展到了29位,并且向CAN2.0A兼容,如下图所示。

(3)控制段

仲裁之段后便是控制场。控制场的头两位为保留位(R1、R0),为隐性。

后面是数据长度代码DLC(Data Length Code)。数据长度代码指示了数据场中有效的字节个数。DLC的长度为4位二进制数,虽然可以最大范围可以表示到0~15,但是由于CAN总线的数据域长度最大为8个字节,所以DLC的大小可以认为是最大为8。

控制场示意图如下:

详细示意图如下:

(4)数据段

控制场传输完成之后,紧接着传输的就是数据场了,数据场里面传输的就是我们想要传输的数据,长度为8个字节,如下图所示。

详细示意图如下:

(5)CRC段

CAN数据每次发送的时候,都会将CAN数据帧里面的有效数据进行CRC校验,并且将最终生成的CRC信息一起包含在数据帧中的CRC域内进行发送。

接收端接收到一帧CAN总线数据后,会将接收到的数据进行CRC计算,并且同发出端的CRC校验码进行比较,如果相同,则代表当前接收到的信息是正确的。

CRC段的示意如下:

CRC校验域的格式如下图所示。

在经典CAN中,使用15位CRC。在硬件可使用移位和异或运算完成CRC的计算。CAN总线中使用的几种CRC生成多项式公式如下图所示。

(6)应答段

CAN总线的应答场长度为2个位,包含应答间隙(ACK SLOT)和应答界定符(ACK DELIMITER)。

在应答场里,发送站发送两个“隐性”位。当接收器正确地接收到有效的报文,接收器就会在应答间隙(ACK SLOT)期间(发送ACK信号)向发送器发送一“显性”的位以示应答。

应答间隙:所有接收到匹配CRC序列(CRC SEQUENCE)的站会在应答间隙(ACK SLOT)期间用以“显性”的位写入发送器的“隐性”位来作出回答。

ACK界定符:ACK界定符是ACK场的第二个位,并且是一个必须为“隐性”的位。因此,应答间隙(ACK SLOT)被两个“隐性”的位所包围,也就是CRC界定符(CRC DELIMITER)和ACK界定符(ACK DELIMITER)。

CAN总线的应答场如下图所示:


(7)帧结束

应答段之后的7位数据是CAN总线的结束帧,是为7位连续的1(隐性电平),如下图所示。

CAN通信的数据段示例

下图可以看到一个CAN数据帧排列的所有数据域。下图展示了一个完整的数据段的通信过程,如下图:


STM32的CAN的配置示例

这里以STM32F407的CAN外设的配置为例。代码如下:

配置CAN1,并配置使用CAN1中断接收CAN消息:

 GPIO_InitTypeDef GPIO_InitStructure;
    CAN_InitTypeDef CAN_InitStructure;
    CAN_FilterInitTypeDef CAN_FilterInitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //使能PORTA时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); //使能CAN1时钟

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;   //复用功能
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;   //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //100MHz
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;   //上拉
    GPIO_Init(GPIOA, &GPIO_InitStructure);   //初始化PA11,PA12

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_CAN1); //GPIOA11复用为CAN1
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_CAN1); //GPIOA12复用为CAN1

    CAN_InitStructure.CAN_TTCM = DISABLE;  //非时间触发通信模式
    CAN_InitStructure.CAN_ABOM = DISABLE;  //软件自动离线管理
    CAN_InitStructure.CAN_AWUM = DISABLE;  //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)
    CAN_InitStructure.CAN_NART = ENABLE;   //启动禁止自动重传,即不自动重传
    CAN_InitStructure.CAN_RFLM = DISABLE;  //报文不锁定,新的覆盖旧的
    CAN_InitStructure.CAN_TXFP = DISABLE;  //优先级由报文标识符决定
    CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;   //模式设置
    CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;        //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1tq~CAN_SJW_4tq
    CAN_InitStructure.CAN_BS1 = CAN_BS1_7tq;        //Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq
    CAN_InitStructure.CAN_BS2 = CAN_BS2_6tq;        //Tbs2范围CAN_BS2_1tq ~CAN_BS2_8tq
    CAN_InitStructure.CAN_Prescaler = 6; //分频系数(Fp)为brp+1   波特率=Fpclk1/((BS1+1+BS2+1+1)*Prescaler),即42M/((6+7+1)*6)=500Kbps
    CAN_Init(CAN1, &CAN_InitStructure);   // 初始化CAN1

    CAN_FilterInitStructure.CAN_FilterNumber = 0; //过滤器0
    CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
    CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; //32位
    CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000; ////32位ID
    CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000; //32位MASK
    CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0; //过滤器0关联到FIFO0
    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; //激活过滤器0
    CAN_FilterInit(&CAN_FilterInitStructure); //滤波器初始化

    CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE); //FIFO0消息挂号中断允许.

    NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);


作者简介:

本人95后技术男,从事嵌入式软件开发,专注于技术成长和技术分享。目标是每天进一步一点点,通过技术改变自己的生活,创造自己的美好未来!如果你也对嵌入式感兴趣,欢迎关注我呀!


声明:

本文作者:嵌入式之入坑笔记

文章版权归作者所有,转载请注明出处!

展开阅读全文

页面更新:2024-04-20

标签:格式   标识符   显性   时序   个位   隐性   节点   总线   信号   通信协议   数据

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top