CAN物理特性与链接
CAN总线采用差分信号
高速CAN规定:
电压差为0V时表示逻辑1(隐性电平) 电压差为2V时表示逻辑0(显性电平)低速CAN规定:
电压差为-1.5V时表示逻辑1(隐性电平) 电压差为3V时表示逻辑0(显性电平)


- 每个设备通过CAN收发器挂载在CAN总线网络上
- CAN控制器引出的TX和RX与CAN收发器相连,CAN收发器引出的CAN_H和CAN_L分别与总线的CAN_H和CAN_L相连
[!TIP]
高速CAN使用闭环网络,CAN_H和CAN_L两端添加120Ω的终端电阻
低速CAN使用开环网络,CAN_H和CAN_L其中一端添加2.2kΩ的终端电阻


CAN总线帧格式

数据帧
- CAN 1.2时期,仅存在标准格式,IDE位当时仍为保留位r1
- CAN 2.0时期,ID不够用,出现了扩展格式,增加了ID的位数,为了区分标准格式与扩展格式,协议将标准格式中的r1设为IDE

帧起始:
- SOF(Start of Frame):1位,帧起始,表示后面一段波形为传输的数据位
仲裁段:相同ID数据帧或遥控帧,数据帧优先级高。
- ID(Identify):标准11位,扩展29位,标识符,区分功能,同时决定优先级,ID小的报文优先级高。
- RTR(Remote Transmission Request ):1位远程请求位,区分数据帧和遥控帧。显性0为数据帧,隐性1为遥控帧。
- SRR(Substitute Remote Request):1位,在拓展协议里替代RTR,必须给隐性1,协议升级时留下的无意义位
- 标准仲裁段:11位ID+RTR
- 扩展仲裁段:11位ID+SRR+IDE+18位ID+RTR
数据段:
- IDE(Identifier Extension):1位,扩展标志位,标准协议为里r1,用来区分标准格式和扩展格式,显性0为标准帧,隐性1为扩展帧。
- r0/r1(Reserve):1位,保留位,为后续协议升级留下空间,标准协议里r1为IDE,拓展协议回归r1无意义。
- DLC(Data Length Code):4位,数据长度,指示数据段有几个字节,一个字节0001
- Data:数据段的1~8个字节有效数据,0-64位。
CRC段:校验
- CRC(Cyclic Redundancy Check):15位,循环冗余校验,校验 SOF到Data数据是否正确,否则出现错误,将输出错误帧。
- CRC界定符:1位,为应答位前后发送方和接收方释放总线留下时间,必须为隐性1
ACK段:应答(体现一帧数据是发送与接收共同完成的)
- ACK(Acknowledgement):1位,应答位,判断数据有没有被接收方接收。
发送方在此释放总线,总线回归隐性1,接收方此时要把总线拉至显性0,发送方读取到显性0为成功接收,否则出现错误,将输出错误帧。- ACK界定符:1位,为应答位前后发送方和接收方释放总线留下时间
- EOF(End of Frame ):7位,帧结束,发送连续7个隐性1表示数据位已经传输完毕
遥控帧:接收设备用来主动请求数据。
- 某些设备使用频率太低,让其不要定时发送,而是被外部请求时发送,类似于从机。
- 遥控帧无数据段,RTR为隐性电平1,其他部分与数据帧相同

错误帧:错误处理。
- 总线上所有设备都会监督总线的数据,一旦发现“位错误”或“填充错误”或“CRC错误”或“格式错误”或“应答错误” ,这些设备便会发出错误帧来破坏数据,同时终止当前的发送设备

- 上图0-6是多个设备同时检测到错误发送错误帧的缓冲,因其可能会多个设备不同时间发送叠加超过6个。
[!NOTE]
主动错误状态(默认):总线上的设备检测总线出错会发送6个显性0
被动错误状态:总线上的设备检测总线出错会发送6个隐性1主动错误状态的设备正常参与通信并在检测到错误时发出主动错误帧
被动错误状态的设备正常参与通信但检测到错误时只能发出被动错误帧
总线关闭状态的设备不能参与通信
每个设备内部管理一个TEC和REC,根据TEC和REC的值确定自己的状态
- 主动被动切换原因:根本目的是为了避免有些设备坏了或者故障导致总线无法通信,设备内部有发送/接收错误计数器,当发送/接收错误时计数+1,正常发送接收时计数-1,当发送错误计数大于127进入被动错误状态,转为发送隐性1
- 之前发送显性0,如果设备坏了或故障会一直为显性0影响总线通信,当错误计数大于127切换被动模式,发送隐性1,根据线与特性不会影响总线其他设备正常通信,当发送错误计数大于255,切换总线关闭态,视为损坏该设备关停不在影响总线,除非总线空闲时出现128次连续11个隐性1,该设备尝试重启上线。通过此循环保证设备损坏不影响其他设备通信。


过载帧:
- 当接收方收到大量数据而无法处理时,其可以发出过载帧6个显性0,8个隐性1,延缓发送方的数据发送,以平衡总线负载,避免数据丢失。

- 将数据帧和遥控帧与前面的帧分离开

位填充:协议的补丁
规则:发送方每发送5个相同电平后,自动追加一个相反电平的填充位,接收方检测到填充位时,会自动移除填充位,恢复原始数据
[!note]
例如:
即将发送: 1000001 10 实际发送: 1000001110 实际接收: 1000001110 移除填充后: 1000001 10 100000 1 111 0
100000 1 1111 0 0
100000 1 1111 0 0
100000 1 111 0 011111 11111 10
011111011111010
011111011111010
011111 11111 10
位填充作用:
- 1增加波形的定时信息,防止波形长时间无变化,导致接收方不能精确掌握数据采样时机
- 2用以区分错误帧过载帧(6个相同的电平触发,所以要5个相同位填充一次)
- 3防止设备认为总线空闲(11个隐性电平1是空闲状态)
波特率与时序采样同步(解决没有时钟线带来的异步问题)
- CAN总线没有时钟线,总线上的所有设备通过约定波特率的方式确定每一个数据位的时长
- 波特率 = 1 / 一个数据位的时长 = 1 / (TSS + TPTS + TPBS1 + TPBS2)
[!NOTE]
例如:
SS = 1Tq,PTS = 3Tq,PBS1 = 3Tq,PBS2 = 3Tq Tq = 0.5us 波特率 = 1 / (0.5us + 1.5us + 1.5us + 1.5us) = 200kbps
- 发送方以约定的位时长每隔固定时间输出一个数据位
- 接收方以约定的位时长每隔固定时间采样总线的电平,输入一个数据位
- 理想状态下,接收方能依次采样到发送方发出的每个数据位,且采样点位于数据位中心附近
- CAN总线对每一个数据位的时长进行了更细的划分,分为同步段(SS)、传播时间段(PTS)、相位缓冲段1(PBS1)和相位缓冲段2(PBS2),每个段又由若干个最小时间单位(Tq:time quantum)构成。
1接收方以约定的位时长进行采样,但是采样点没有对齐数据位中心附近
- 每个设备都有一个位时序计时周期,当某个设备(发送方)率先发送报文,其他所有设备(接收方)收到SOF的下降沿时,接收方会将自己的位时序计时周期拨到SS段的位置,与发送方的位时序计时周期保持同步
- 硬同步只在帧的第一个下降沿(SOF下降沿)有效
- 经过硬同步后,若发送方和接收方的时钟没有误差,则后续所有数据位的采样点必然都会对齐数据位中心附近
简而言之:在发送起始位的下降沿时,发送端和接收端,都将时序校准到SS段,理解为时钟同步校准,校准后数据位采样点才会准确。

2接收方刚开始采样正确,但是时钟有误差,随着误差积累,采样点逐渐偏离
- 若发送方或接收方的时钟有误差,随着误差积累,数据位边沿逐渐偏离SS段,则此时接收方根据再同步补偿宽度值(SJW)通过加长PBS1段,或缩短PBS2段,以调整同步
- 再同步可以发生在第一个下降沿之后的每个数据位跳变边沿
- 简而言之:晶振时钟不准(温漂之类),导致后面的接收数据位采样点偏移,必须要再次同步,可以通过增加PBS1段,或缩短PBS2段完成。范围正负1-4Tq
仲裁(线与特性的完美利用)
1、正常交替发送情况
- 若当前已经有设备正在操作总线发送数据,则其他任何设备不能再同时发送数据(可以发送错误帧/过载帧破坏当前数据)总线连续11个隐性电平才是总线空闲,只有在总线空闲时,设备才能发送数据帧/遥控帧。
- 一旦有设备正在发送数据帧/遥控帧,总线就会变为活跃状态,必然不会出现连续11个隐性电平,其他设备自然也不会破坏当前发送。若总线活跃状态其他设备有发送需求,则需要等待总线变为空闲,才能执行发送需求
2、多个设备同时发送
- 若多个设备的发送需求同时到来或因等待而同时到来,则CAN总线协议会根据ID号(仲裁段)进行非破坏性仲裁,ID号小的(优先级高)取到总线控制权,ID号大的(优先级低)仲裁失利后将转入接收状态,等待下一次总线空闲时再尝试发送
实现非破坏性仲裁需要两个要求:
- 线与特性:总线上任何一个设备发送显性电平0时,总线就会呈现显性电平0状态,只有当所有设备都发送隐性电平1时,总线才呈现隐性电平1状态,即:0 & X & X = 0,1 & 1 & 1 = 1
- 回读机制:每个设备发出一个数据位后,都会读回总线当前的电平状态,以确认自己发出的电平是否被真实地发送出去了,根据线与特性,发出0读回必然是0,发出1读回不一定是1
仲裁原理:数据位从前到后依次比较,出现差异且数据位为1的设备仲裁失利,如下图,单元1与单元2起始位,前几位ID都一致此时他们都在发送,当时序在单元1的红色处,单元1是隐性电平1,单元2是显性电平0,此时总线线与电平为显性电平0,单元1回读电平发现不一致即退出通信置为接收状态。

数据帧和遥控帧ID号一样时,遥控帧RTR为隐性电平1,数据帧RTR为显性电平0,线与后回读遥控帧退出置为接收态,所以数据帧的优先级高于遥控帧

标准格式11位ID号和扩展格式29位ID号的高11位一样时,协议规定SRR必须始终为1,而标准格式RTR为显性电平0,线与后回读扩展格式退出置为接收态,所以标准格式的优先级高于扩展格式

位填充是否会影响仲裁?
不会,因为如果位填充会改变设备1、设备2的优先级,那么前面设备1和设备2的5位数据一定是一致的,位填充肯定会同时发生,因为如果不一致,就会被提前仲裁出去。
如 010000000 -> 0100000100
010000000 -> 0100000100
CAN外设代码分析
MCU外设使用一般过程:
1、先看想要的外设对应引脚


2、先看该型号芯片的整体框图,知道MCU外设的时钟挂在哪里,比如下图,CAN挂在APB1,GPIOA挂在APB2上,CPU通过APB总线来控制外设,那么操作时首先要将对应总线上的外设时钟开启。

3、IO配置与外设配置,配置CAN_TX为发送,CAN_RX为接收,配置CAN的各功能配置位


4、通过外设进行数据接收或发送

- 通过以上步骤即可完成外设的使用,现在的Cortex-M核心的MCU基本都是相同的用法。
[!NOTE]
STM32内置bxCAN外设(CAN控制器),支持CAN2.0A和2.0B,可以自动发送CAN报文和按照过滤器自动接收指定CAN报文,程序只需处理报文数据而无需关注总线的电平细节波特率最高可达1兆位/秒
- 3个可配置优先级的发送邮箱
- 2个3级深度的接收FIFO
- 14个过滤器组(互联型28个)
时间触发通信、自动离线恢复、
- 自动唤醒、禁止自动重传、
- 接收FIFO溢出处理方式可配置、
- 发送优先级可配置、双CAN模式
- 如图所示,STM32的CAN发送邮箱有三个,接收滤波器一共13个,接收FIFO有两个,每两个FIFO各有三个接收邮箱

发送与接收
- 当发送报文时,将想要发送的报文各个参数写入到邮箱中,然后给出请求发送的命令,发送和接收控制器就会等待总线空闲后把这个报文广播到总线上,设计三个邮箱的原因是防止总线繁忙时数据丢失用来暂存的队列。

RQCP(Request completed)请求完成,=X表示任意值
TXOK(Transmission OK)发送成功,=X表示任意值
TME(Tranmsit mailbox empty)发送邮箱空,=1表示邮箱空置状态
TXRQ(Tranmsit mailbox request)发送请求控制位,=1表示产生发送请求
NART(No automatic retransmission)禁止自动重传,=0表示使用,=1表示禁止,CAN硬件在发送报文失败时会一直自动重传直到发送成功
- 对于数据的接收,当CAN总线出现任何一个报文时,控制器就会将报文收下,但是总线上的报文不一定就是自己需要的,需要通过接收过滤器进行筛选,接收过滤器可以根据ID号对报文进行过滤,如果ID不是我们想要的,就不会通过过滤器,数据就不会进行后续的传递,默认条件下不去配置过滤器,过滤器处于失能的状态,无法使用,想要什么ID就可以对过滤器进行配置。
- 过滤器过滤完的数据,会存储在FIFO中,在STM32总共配置了两个FIFO,每个FIFO配备3个邮箱,过滤器过滤完的数据可以指定进入那个FIFO
- 比如遥控帧和数据帧各走一个FIFO,比如优先级高的ID走FIFO0,不重要的走FIFO1
此外,配置了FIFO锁定,在FIFO满了以后,新的报文就会丢弃,不配置锁定会覆盖最后一个邮箱的数据。


过滤器
- 每个过滤器的核心由两个32位寄存器组成:R1[31:0]和R2[31:0]
FSCx:位宽设置,置0,16位;置1,32位
FBMx:模式设置,置0,屏蔽模式;置1,列表模式
FFAx:关联设置,置0,FIFO 0;置1,FIFO 1
FACTx:激活设置,置0,禁用;置1,启用
过滤器可以设置为多种多种格式。
- 比如可以设置直接收指定ID,屏蔽指定ID,可选16位或者32位ID,也可以设置为只接收遥控帧,只接受拓展格式等。
- 实际上相当于外置了一个硬件协议解析,可以帮助加快协议分析和数据交换。

本文参考江科大stm32教程学习整理
评论