一、用STM32F103做CAN的收发通信
CAN 是Controller Area Network 的缩写(以下称为CAN),该通信使用的是ISO11898标准,该标准的物理层特征如下图所示。
CAN协议是通过以下5种类型的帧进行的:
- 数据帧
- 摇控帧
- 错误帧
- 过载帧
- 帧间隔
另外,数据帧和遥控帧有标准格式和扩展格式两种格式。标准格式有11 个位的标识符(ID),扩展格式有29 个位的ID。
大部分系统使用的都是数据帧 ,我这里使用的也是数据帧。
数据帧一般由7个段构成,即:
(1) 帧起始。表示数据帧开始的段。
(2) 仲裁段。表示该帧优先级的段。
(3) 控制段。表示数据的字节数及保留位的段。
(4) 数据段。数据的内容,一帧可发送0~8个字节的数据。
(5) CRC段。检查帧的传输错误的段。
(6) ACK段。表示确认正常接收的段。
(7) 帧结束。表示数据帧结束的段。
明确了数据帧概念,还需要理解一下过滤器的作用。
STM32的标识符屏蔽滤波目的是减少了CPU处理CAN通信的开销。STM32的过滤器组最多有28个(互联型),但是STM32F103ZET6只有14个(增强型),每个滤波器组x由2个32为寄存器,CAN_FxR1和CAN_FxR2组成。
STM32每个过滤器组的位宽都可以独立配置,以满足应用程序的不同需求。根据位宽的不同,每个过滤器组可提供:
- 1个32位过滤器,包括:STDID[10:0]、EXTID[17:0]、IDE和RTR位
- 2个16位过滤器,包括:STDID[10:0]、IDE、RTR和EXTID[17:15]位
此外过滤器可配置为,屏蔽位模式和标识符列表模式。
在屏蔽位模式下,标识符寄存器和屏蔽寄存器一起,指定报文标识符的任何一位,应该按照“必须匹配”或“不用关心”处理。
而在标识符列表模式下,屏蔽寄存器也被当作标识符寄存器用。因此,不是采用一个标识符加一个屏蔽位的方式,而是使用2个标识符寄存器。接收报文标识符的每一位都必须跟过滤器标识符相同。相关文章: CAN总线详解。
一般也都是使用标识符列表模式,这里使用的也是标识符列表模式。滤波过程举例如下:
在程序中就是:
上述程序的设置的含义就是:只接收来自0x1314的数据,屏蔽其他ID的数据。
程序思路 这里准备做一个主机与从机的通信,主要用扩展标识符ExtId来区分,分配的标识符是:
主机:0x1314
从机:0x1311
主机负责接收所有从机的数据,不需要过滤,用扩展标识符ExtId来区分不同从机的数据;主机还可以向不同从机发送信息。而从机则只接收来自主机的数据,同样用扩展标识符ExtId来区分是否是发向自己的数据;同时,也能够向主机发送信息。
相关代码代码也是非常简单的,这里贴出了主机和从机的can.c和can.h两个文件。
从机相关代码can.c文件:
can.h文件
主机相关代码 这里主机代码大部分是和从机类似的,就只贴出不同的地方了。
can.c文件:
can.h文件:
开发板商城 天皓智联 CAN总线设备~~
二、CAN总线终端电阻为什么是120Ω?为什么是0.25W?
但是作为学渣的我,知道这个是在各种标准以及各种数据手册和应用笔记里面常用的电阻值,但是这两个终端电阻的具体作用是什么呢?之前就知道阻抗匹配,但是究竟匹配的是什么呢?
然后我就上知乎遨游了一下,半抄半写的总结了下面的这些知识点。知道终端电阻的作用,对于日常工作中波形不稳定等问题,也能更快的找到问题的原因。
终端电阻的作用
CAN总线终端电阻的作用有3个:
1、提高抗干扰能力,让高频低能量的信号迅速走掉
2、确保总线快速进入隐性状态,让寄生电容的能量更快走掉;
3、提高信号质量,放置在总线的两端,让反射能量降低。
1、提高抗干扰能力
CAN总线有“显性”和“隐性”两种状态,“显性”代表“0”,“隐性”代表“1”,由CAN收发器决定。下图是一个CAN收发器的典型内部结构图,CANH、CANL连接总线。
总线显性时,收发器内部Q1、Q2导通,CANH、CANL之间产生压差;隐性时,Q1、Q2截止,CANH、CANL处于无源状态,压差为0。
总线若无负载,隐性时差分电阻阻值很大,内部的MOS管属于高阻态,外部的干扰只需要极小的能量即可令总线进入显性(一般的收发器显性门限最小电压仅500mV)。这个时候如果有差模干扰过来,总线上就会有明显的波动,而这些波动没有地方能够吸收掉他们,就会在总线上创造一个显性位出来。所以为提升总线隐性时的抗干扰能力,可以增加一个差分负载电阻,且阻值尽可能小,以杜绝大部分噪声能量的影响。然而,为了避免需要过大的电流总线才能进入显性,阻值也不能过小。
2、确保快速进入隐性状态
在显性状态期间,总线的寄生电容会被充电,而在恢复到隐性状态时,这些电容需要放电。如果CANH、CANL之间没有放置任何阻性负载,电容只能通过收发器内部的差分电阻放电,这个阻抗是比较大的,按照RC滤波电路的特性,放电时间就会明显比较长。我们在收发器的CANH、CANL之间加入一个220PF的电容进行模拟试验,位速率为500kbit/s,波形如图,这个波形的下降沿就是比较长的状态。
为了让总线寄生电容快速放电,确保总线快速进入隐性状态,需要在CANH、CANL之间放置一个负载电阻。增加一个60Ω的电阻后,波形如图,从图中看出,显性恢复到隐性的时间缩减到128nS,与显性建立时间相当。
3、提高信号质量
信号在较高的转换速率情况下,信号边沿能量遇到阻抗不匹配时,会产生信号反射;传输线缆横截面的几何结构发生变化,线缆的特征阻抗会随之变化,也会造成反射。
能量发生反射时,导致反射的波形与原来的波形进行叠加,就会产生振铃。
在总线线缆的末端,阻抗急剧变化导致信号边沿能量反射,总线信号上会产生振铃,若振铃幅度过大,就会影响通信质量。在线缆末端增加一个与线缆特征阻抗一致的终端电阻,可以将这部分能量吸收,避免振铃的产生。
别人进行了一个模拟试验(图片都是我抄过来的),位速率为1Mbit/s,收发器CANH、CANL接一根10m左右的双绞线,收发器端接120Ω电阻保证隐性转换时间,末端不加负载。末端信号波形如图所示,信号上升沿出现了振铃。
若双绞线末端增加一个120Ω的电阻,末端信号波形明显改善,振铃消失。
一般在直线型拓扑中,线缆两端即是发送端,也是接收端,故线缆两端需各加一个终端电阻。
而在实际应用过程中,CAN总线一般都不是完美的总线式的设计,很多时候是总线型和星型的混合结构,这个时候一般都将CAN终端电阻布置在线束最远的两端,来尽量的模拟CAN总线的标准结构。
为什么选120Ω?
什么是阻抗?在电学中,常把对电路中电流所起的阻碍作用叫做阻抗。阻抗单位为欧姆,常用Z表示,是一个复数Z= R+i( ωL–1/(ωC))。具体说来阻抗可分为两个部分,电阻(实部)和电抗(虚部)。其中电抗又包括容抗和感抗,由电容引起的电流阻碍称为容抗,由电感引起的电流阻碍称为感抗。这里的阻抗是指Z的模。
任何一根线缆的特征阻抗都可以通过实验的方式得出。线缆的一端接方波发生器,另一端接一个可调电阻,并通过示波器观察电阻上的波形。调整电阻阻值的大小,直到电阻上的信号是一个良好的无振铃的方波: 阻抗匹配与信号完整性,此时的电阻值可以认为与线缆的特征阻抗一致。
采用两根汽车使用的典型线缆,将它们扭制成双绞线,就可根据上述方法得到特征阻抗大约为120Ω,这也是CAN标准推荐的终端电阻阻值,所以这个120Ω是测出来的,不是算出来的,都是根据实际的线束特性进行计算得到的。当然在ISO 11898-2这个标准里面也是有定义的。
为什么功率还要选0.25W?
这个就要结合一些故障状态也计算,汽车ECU的所有接口都需要考虑短路到电源和短路到地的情况,所以我们也需要考虑CAN总线的节点短路到电源的情况,根据标准需要考虑短路到18V的情况,假设CANH短路到18V,电流会通过终端电阻流到CANL上,而CANL内部由于限流的原因,最大注入电流为50mA(TJA1145的规格书上标注),这时候120Ω电阻的功率就是50mA*50mA*120Ω=0.3W。考虑到高温情况下的降额,终端电阻的功率就是0.5W。