CAN简介
CAN总线特征:
- 两根通信线(CAN_H、CAN_L),无需共地
- 差分信号,抗干扰
- 高速CAN:125k-1mbps,<40m
- 低速CAN:10k~125kbps, <1km
- 异步通信(无时钟线),通信速率由设备各自约定
- 半双工,可挂载多设备,多设备同时发送数据时通过仲裁判断先后顺序
- 11位/29位报文ID,用于区分消息功能,同时决定优先级
- 可配置1~8字节的有效载荷
- 可实现广播式和请求式两种传输方式
- 应答、CRC校验、位填充、位同步、错误处理等特性
主流通信协议
| 名称 | 引脚 | 双工 | 时钟 | 电平 | 设备 | 应用场景 |
|---|---|---|---|---|---|---|
| UART | TX、RX | 全双工 | 异步 | 单端 | 点对点 | 两个设备互相通信 |
| I2C | SCL、SDA | 半双工 | 同步 | 单端 | 多设备 | 一个主控外挂多个模块 |
| SPI | SCK、MOSI、MISO、SS | 全双工 | 同步 | 单端 | 多设备 | 一个主控外挂多个模块(高速) |
| CAN | CAN_H、CAN_L | 半双工 | 异步 | 差分 | 多设备 | 多个主控互相通信 |
CAN类似UART和IIC的结合
第一章
CAN硬件电路
主控会内置CAN控制器,借助CAN收发器挂载在CAN总线网络
高速CAN采用闭环网络,CAN的差分信号默认状态下(1,CANH=CANL),由电阻收紧,而电阻因为阻抗不大,因此电压跃变快,但是功耗高

低速CAN使用开环网络,两端加开路的电阻,降低反射

电平标准
差分信号,即电压差传输数据
高速CAN:
隐性电平是不碰两根线,电阻处为收紧状态(默认状态1,隐性)
显性电平是拉开两根线,电阻处为非收紧状态(显性可以控制总线,0强于1,所以能叫显性)
- 电压差为0V时表示逻辑1(隐性电平)
- 电压差为2V时表示逻辑0(显性电平)

CAN收发器-TJA1050(高速CAN)

CANH和CANL有电压差,RECEIVER输出1,下管导通,RXD为0(有电压差,逻辑0,显性)
CANH和CANL无电压差,RECEIVER输出0,上管导通,RXD为1(无电压差,逻辑1,隐性)

TXD为0时,2,3的场效应管导通,CANH和CANL有电压差(逻辑0,显性)
而TXD悬空时,电流源默认让TXD为1

CAN物理层特性

第二章
CAN总线帧格式
主要看数据帧
| 帧类型 | 用途 |
|---|---|
| 数据帧 | 发送设备主动发送数据(广播式) |
| 遥控帧 | 接收设备主动请求数据(请求式) |
| 错误帧 | 某个设备检测出错误时向其他设备通知错误 |
| 过载帧 | 接收设备通知其尚未做好接收准备 |
| 帧间隔 | 用于将数据帧及遥控帧与前面的帧分离开 |
数据帧
- SOF(Start of Frame):帧起始,表示后面一段波形为传输的数据位
- ID(Identify):标识符,区分功能,同时决定优先级
- RTR(Remote Transmission Request ):远程请求位,区分数据帧和遥控帧
- IDE(Identifier Extension):扩展标志位,区分标准格式和扩展格式
- SRR(Substitute Remote Request):替代RTR,协议升级时留下的无意义位
- r0/r1(Reserve):保留位,为后续协议升级留下空间
- DLC(Data Length Code):数据长度,指示数据段有几个字节
- Data:数据段的1~8个字节有效数据
- CRC(Cyclic Redundancy Check):循环冗余校验,校验数据是否正确
- ACK(Acknowledgement):应答位,判断数据有没有被接收方接收
- CRC/ACK界定符:为应答位前后发送方和接收方释放总线留下时间
- EOF(End of Frame ):帧结束,表示数据位已经传输完毕

标准格式
- 开始为空闲状态为隐性
- SOF为帧起始,表明开始一帧数据
- 起始帧后发送11位标识符报文,区分功能,同时决定优先级
- RTR为0:数据帧。为1:遥控帧
- IDE为0:标准格式。为1:扩展格式
- r0保留位,暂时无功能
- DLC为数据长度,0001发一个字节,1000发8字节
- Data根据DLC给几个字节能给范围0-64字节
- CRC为校验
- ACK应答位,发送方释放总线,如果接收方收到了,就抢占总线,发送方读取总线状态知道被接受
- CRC/ACK界定符是留出时间交出控制权
- EOF作为结束
遥控帧
适合使用频率低的数据
遥控帧无数据段,RTR为隐性电平1,其他部分与数据帧相同
如果有数据需要,首先接收方发出一个遥控帧,遥控帧包含报文ID,如果发送方有这个报文ID,就将数据发送出来,接收方可以及时获取数据
错误帧
总线所有设备监督总线数据,一旦发现错误,这些设备发出错误帧来破坏数据,同时终止当前的发送设备

过载帧
接收方收到大量数据无法处理,发送过载帧,延缓发送方的数据发送,以平衡总线负载,避免数据丢失
帧间隔
将数据帧和遥控帧与前面的帧分离开

位填充
规则:发送方每发送5个相同电平,自动追加相反电平的填充位,接收方检测到填充位,自动移除填充位。
即将发送: 100000110 10000011110 0111111111110 实际发送: 1000001110 1000001111100 011111011111010 实际接收: 1000001110 1000001111100 011111011111010 移除填充后: 100000110 10000011110 0111111111110
作用:
- 增加定时信息,有利于接收方同步,防止波形长时间无变化(防止连续很多相同电平,接收方可能数错)
- 将正常数据流与“错误帧”和“过载帧”区分(防止连续6个相同电平)
- 保持CAN发送数据的活跃状态,防止认为总线空闲(防止连续11个隐性电平1)
波形实例
标准数据帧
11位报文ID:0x555,
RTR = 0 数据帧,IDE = 0,标准格式
DLC = 0001(注意其中第一个1为位填充) = 1,一个字节数据
Data = 10101010 = 0xAA

扩展数据帧
扩展数据帧,报文ID为0x0789ABCD,数据长度1字节,数据内容为0x56

第三章
接收方数据采样
- CAN总线无时钟线,总线设备通过一个约定的波特率方式确定每个数据位的时长
- 发送方以约定的位时长每个固定时间输出一个数据位
- 接收方以约定的位时长每个固定时间采样总线电平,输入一个数据位
- 理想采样是数据位中心附近
会遇到的问题
- 接收方采样点没有对齐数据位中心附近
解决:第一个跳变沿对齐(硬同步)
- 接收方刚开始采样正确,但是时钟有误差,随着误差积累,采样点逐渐偏离
解决:采样点动态调节,弥补时钟误差(再同步)
位时序
因为要调节采样点,所以会对一个数据位时长进行细分
- 同步段(SS)
- 传播时间段(PTS)
- 相位缓冲段1(PBS1)
- 相位缓冲段2(PBS2)
每个段又由若干个最小时间单位(Tq)构成
SS = 1Tq、PTS = 18Tq、PBS1 = 18Tq、PBS2 = 2~8Tq

如果跳边沿在SS段,说明当前设备与波形达成同步,否则不同步,则需要调节时序使跳变沿正好在同步段

硬同步
使第一次采样对齐
每个设备有一个位时序计时周期,当某设备发送报文,其他设备接收到SOF下降沿,会将位时序计时周期拨到SS段,与发送方保持同步(实际就是让第一个边沿段调整为SS段,类似于时区,绝对时刻不一样,但都规定为北京时间)
而此时接受段直接确定数据位采样点(PBS1和PBS2段中间)
硬同步解决没有对齐数据位中心附近,只要时钟没误差,就不会有问题

再同步
解决时钟误差,若数据位边沿逐渐偏离SS段,此时接收方根据再同步补偿宽度值(sjw,是最大的补偿,如果误差1tq,sjw2,则补偿1tq;若误差3tq,则补偿2tq)加长PBS1段,或缩短PBS2段
再同步发生在,第一个下降沿之后每个数据位跳变边沿

波特率计算
波特率 = 1/一个数据位的时长 = 1/(Tss+Tpts+Tpbs1+Tpbs2)
SS = 1Tq,PTS = 3Tq,PBS1 = 3Tq,PBS2 = 3Tq,Tq = 0.5us
则波特率 = 1 / (0.5us + 1.5us + 1.5us + 1.5us) = 200kbps
第四章
多设备同时发送遇到的问题
CAN总线只有一差分信号线,同时只能有一个设备操作总线
若多设备同时又发送需求,该如何分配总线资源?
资源分配规则1-先占先得
- 若当前有设备操作总线发送数据帧/遥控帧,则其他设备不可发(可发错误帧/过载帧)
- 任何设备检测到11连续隐性电平,认为总线空闲,才能发送
- 若有设备有发送需求要等待总线空闲
而位填充的适用范围是从帧起始(SOF)到CRC序列结束,不包括CRC界定符、ACK域和EOF段
此时有ACK界定符一个隐性,EOF7个隐性,只需再等三个隐性即可继续发送。
但有可能不止一个信号在等待,多个设备同时到来(总线仲裁)
资源分配规则2-非破坏性仲裁
多设备发送需求同时到来,对仲裁段(ID+RTR)进行非破坏性仲裁,ID号小(优先级高)的取得控制权,ID号大(优先级低)仲裁失利,继续等待空闲
实现非破坏性仲裁两个需要的特性:
- 线与特性:0 & X & X = 0,1 & 1 & 1 = 1
- 回读机制:设备发出一个数据位后,读回总线电平状态,确认电平被发送。发送0读回0,发送1读回不一定是1
仲裁:发出数据1,读回(回读机制)数据0(被其他设备线与了)
非破坏性仲裁过程
数据位从前到后依次比较,出现差异且数据位为1的设备仲裁失利
单元1在仲裁段中某一个数据位发送1,回读出0,判断有其他设备在发生,但自己优先级低,放弃发送。但是总线电平依旧是单元2的,并没有被破坏

数据帧和遥控帧优先级
数据帧和遥控帧ID号一样时,数据帧的优先级高于遥控帧(RTR决断,因为RTR = 0 为数据帧)

标准格式和拓展格式的优先级
标准格式11位ID号和扩展格式29位ID号的高11位一样时,标准格式的优先级高于扩展格式(SRR必须始终为1,以保证此要求)

第五章
错误类型
位错误、填充错误、CRC错误、格式错误、应答错误

错误状态
- 主动错误状态参与通信并检测到错误时发送主动错误帧(6个0),可以破坏别的设备的数据
- 而频繁发送主动错误,说明这个设备不太可靠,就转到被动错误,收回他破坏其他设备通信的权利
- 若还是频繁被动错误,则进入总线关闭
- 如何判断:每个设备内部管理一个TEC和REC,根据TEC和REC确定自己状态(信誉分)

错误计数器
信誉分积分:

STM32 CAN外设
- STM32内置bxCAN支持CAN2.0A和2.0B,可自动发报文,程序只需处理报文数据
- 波特率最高1mbps
- 3个可配置优先级的发送邮箱
- 2个3级深度接收FIFO
- 时间触发通信、自动离线恢复、自动唤醒、禁止自动重传、接收FIFO溢出处理方式可配置、发送优先级可配置、双CAN模式
- STM32F103C8T6 CAN资源:CAN1
第一节
CAN网络拓扑

STM32F103C8T6 CAN引脚默认复用

重定义

CAN收发器电路
注意TX,RX接法与串口区分


第二节
CAN框图

对于STM32F103C8T6,没有CAN2,只有CAN1。
通过读写以下寄存器对CAN电路进行配置:

3个主发送邮箱,每个可以存入一个CAN报文,若想发送一个报文,可以将报文放入空置邮箱,在设置寄存器请求发送

接收部分包括过滤器和2个FIFO,过滤器设置过滤规则,告诉硬件想要的ID的报文,如果硬件收到相应ID的报文,将报文放入FIFO;如果都没用,就抛弃,减轻软件负担。
FIFO:先入先出,类似于队列,等待CPU读取

CAN基本结构

发送过程
选择空置邮箱-写入报文-配置寄存器请求发送
RQCP:请求完成
TXOK:发送成功
TME = 1:发送邮箱空

发送流程:
- 默认TME=1处于空置状态时,TXRQ(请求发送控制位)=1(产生发送请求)
- 进入挂号状态TME=0,排队等到该邮箱为最高优先级发送报文
- 进入预定状态,若优先级被比下去,则退回挂号状态
- 处于预定的报文,探测到CAN总线=IDLE空闲,管理员将报文发送到CAN总线
- 发送成功回到空置状态,发送失败时若启用NART=0(禁止自动重发)回到空置,若禁止,NART=1则回到预定等待发送(比如总线仲裁失败)
接收过程
接收到一个报文→匹配过滤器后进入FIFO 0或FIFO 1→CPU读取
FMP:报文数目
FOVR:FIFO溢出

- 接收到一个报文时,FMP=1,FOVR=0,依次接收后FMP递增
- 有效报文存满FULL置1,在收到有效报文进入溢出FOVR=1
- 若读取一个报文,RFOM=1,释放一次邮箱
注意:溢出状态释放一次是挂号2
发送和接收配置位
- NART:NART=1关闭自动重传,CAN报文只发送一次,不管发送结果如何;置0,自动重传,直到发送成功
- TXFP:TXFP=1,优先级按发送请求的顺序;置0,优先级按报文ID,标志符小的先发送(标志符相等,邮箱号小的先发送)
- RFLM:置1,接收FIFO锁定,FIFO溢出,新报文丢弃;置0,FOFO溢出后最后收到报文被覆盖
标识符过滤器
x可以表示0-13,每个过滤器都有一套电路
每个过滤器由2个32位寄存器组成,R1[31:0] R2[31:0]
位宽设置,FSCx=0,16位,FSCx=1,32位
- 若只有标准ID,则16位足矣,若有标准,有拓展需要用到32位
- 16位的话两个32位寄存器能写4个ID号,32位写两个
模式设置,
FBMx=0,屏蔽模式
允许一类,使用了类似掩码功能,屏蔽的是不需要的ID号的位,如只需要用前三位,可以ID段前三位写001xxxxxxxx,屏蔽写11100000000,过滤ID前三位为001
FBMx=1,列表模式(允许个别)
关联到队列,FFAx=0,关联FIFO0,否则关联FIFO1
激活FACTx:FACTx=0,禁用,否则启用

列表模式
想要的ID号写入R1或R2寄存器中
位宽32位
- STID高11位为标准ID
- 前29位是拓展ID
- 过滤拓展ID,IDE=1,过滤标准ID,IDE=0
- RTR=1,过滤遥控帧,RTR=0,过滤数据帧
位宽16位
- 只使用标准ID,4个16位
屏蔽模式
- ID号过多时使用
- 采用位与屏蔽,类似掩码功能
- ID段有效位写实际,对应屏蔽位写1
过滤器配置示例

第三节
测试模式
- 静默模式:用于分析CAN总线的活动,不会对总线造成影响
- 环回模式:用于自测试,同时发送的报文可以在CAN_TX引脚上检测到
- 环回静默模式:用于热自测试,自测的同时不会影响CAN总线

工作模式
- 初始化模式:用于配置CAN时禁止收发
- 正常模式
- 睡眠模式:低功耗,CAN外设时钟停止,可以软件唤醒或硬件自动唤醒
- AWUM:置1,自动唤醒,一旦检测到CAN总线活动,硬件就自动清零SLEEP,唤醒CAN外设;置0,手动唤醒,软件清零SLEEP,唤醒CAN外设

位时间特性
STM32中,PDS和PBS1合在一起
- SS = 1Tq
BS1 = 1
16Tq BS2 = 18Tq - SJW=1~4Tq

波特率=APB1时钟频率/分频系数/1位Tq数
=36Mhz/(BRP[9:0]+1)/(1+(TS1[3:0]+1)+(TS2[2:0]+1))
中断
CAN外设占用4个专用中断向量
发送中断:发送邮箱空时产生
FIFO 0中断:收到一个报文/FIFO 0满/FIFO 0溢出时产生
FIFO 1中断:收到一个报文/FIFO 1满/FIFO 1溢出时产生
状态改变错误中断:出错/唤醒/进入睡眠时产生
中断发生条件:
