CAN控制器局域网学习笔记
CAN控制器局域网(Controller Area NetWork),是由德国Bosch公司制定,是工业以及汽车领域广泛使用的总线之一。当前许多嵌入式MCU的外设基本都具备有CAN外设。
一般在设计中如果需要用到CAN,并不是MCU具备CAN外设即可,还需要配备CAN收发芯片。因为MCU的TX/RX输出的CAN信号是TTL电平信号,要发送到总线上的话,需要将其转化为差分信号,所以外接的收发芯片的作用则是TTL信号和差分信号的相互转换。
【资料图】
下图是遵循ISO11898标准的高速/短距离的“闭环总线网络”。首位两端各有一个120欧姆的匹配电阻(120欧姆的匹配电阻只是一个经典值,并非固定),总线阻抗测量应为60欧姆,该总线也是工业场景中常用的总线结构。
下图为遵循ISO11519-2标准的低速,远距离“开环网络”。
总线上的匹配电阻的作用,主要有两个:一.提高抗干扰能力,确保信号快速进入隐形状态,更快地执行放电动作 二.提高信号质量,吸收信号传输到总线两端后的反射波。
如下图所示,能明显看到匹配电阻对信号的质量的实际改善。
上述,CAN有两个不同的通讯标准,不同的测试标准对于实际差分信号和逻辑电平的要求是不同的,如下图所示,因为CANH/CANL输出的是差分信号,当差分信号的电压差小于下表中的标准值,则认为是隐形电平,代表逻辑电平为1;同理,差分信号压差的电压差大于下表中标准值,则认为是显性电平,代表逻辑电平为0;
所以在实际使用过程中,可通过实际测量MCU出的TX/RX(逻辑电平)和收发芯片出的CAN H/CANL(差分信号),来简易地判断板级CAN电路是否工作正常。
CAN的帧类型有数据帧/遥控帧/错误帧/过载帧四种主要帧类型,其中应用最广泛和最复杂的就是数据帧,其中大家比较熟悉的就是数据帧里的标准帧和拓展帧(帧构成区别如下图所示),对于开发者来说,标准帧和拓展帧最直观的区别就是标准帧的帧ID范围:0~0x7ff,拓展帧的帧ID范围:0~0x1fffffff,数据域的使用是一致的。
标准帧
拓展帧
接下来介绍的也是CAN的配置中最重要的一个内容,就是波特率的配置。CAN的波特率也就是CAN报文的传输数量,单位是bps(Bits Per Second)每秒能传输的bit数目,目前常见的CAN 2.0理论最大支持到1M bps。接下来基于ST库函数代码,来查看CAN的波特率配置过程有哪些变量是需要关注的,且它们的含义是什么。
如上述所言,CAN的波特率即是每秒可传输的bit个数,那么可知
BaudRate= 1/BitTime
因此如下图所示,当分别配置CAN的波特率为125kbps、250kbps以及1Mbps时,可测得单个bit位的传输时长分别是8us、4us以及1us,因此这也是可用用作测试波特率是否配置正确的一种方法
如下所示,在实际开发过程中,以ST为例CAN的配置结构体如下所示,其中与波特率相关的变量为CAN_Prescaler/CAN_BS1/CAN_BS2,配置好这几个数值则可以完成目标波特率的配置。
那上述的这些变量具体可见下图,每个CAN报文的bit都可以拆成如下段,CAN报文也是通过如下段来决定如何对齐CAN时序、如何实现该bit位电平的采样。
如图所示一个bit位进一步拆分成SS段、PTS段、PBS1段(CAN_BS1)、PBS2段(CAN_BS2),每个段的单位为1Tq
Tq = CAN_Prescaler/CAN所在总线频率 = CAN_Prescaler/Fclk。
综上可计算公式:
BitTime = (1+BS1+BS2)*Tq = (CAN_Prescaler)(1+BS1+BS2)/Fclk
BaudRate = 1/BitTime = Fclk/ (CAN_Prescaler)(1+BS1+BS2)
举个例子,若当前CAN所在总线的频率为45Mhz(即Fclk = 45M),此时若想要配置得到1Mbps的波特率,那么就需要凑出(CAN_Prescaler)(1+BS1+BS2) = 45,如下可知通过选取BS1 = 5、BS2 = 3、CAN_Prescaler = 5的形式来得到5*(1+5+3) = 45,来求的波特率是1Mbps。
由此可知计算波特率的数值取值不是固定的,因为BS1= 6,BS2 = 2也是可得到同样的波特率,但是这个时候需要引入一个采样点的概念,即CAN的处理电路什么时候开始判断当前这个CAN bit是属于高电平还是低电平,这边不做更多延伸,采样点的计算公式如下
Sample = (1+BS1)/(1+BS1 + BS2),所以例子中的采样率为(1+5)/(1+5+3) = 0.67,则采样率为67%,一般情况下采样率最好是配置在75%~85%之间。
不同的芯片厂商的库函数其含义有些许不同,有的厂商是需要寄存器需要配置的TSEG1、TSEG2,其实就是BS1和BS2,但是例如如果你要配置BS1 = 5,实际赋值需要为TSEG1 = 4。区别就在于需要做加一或者减一的区别,下图即是公式,由于自己没有深究过这一块的区别,有研究的朋友欢迎评论交流。