前言
最近在学习稚辉君的机械臂代码,用到了CAN通讯协议,其实这个之前我是有所了解过的,可恨的是之前学习习惯不好,并没有养成记笔记的习惯,导致现在都忘光了QAQ
趁此机会好好巩固一下CAN通讯,学习资源来自
GitHub - peng-zhihui/Dummy-Robot: 我的超迷你机械臂机器人项目。
正点原子
SN65HVD23x 3.3V CAN 总线收发器 datasheet (Rev. O) (ti.com)
基本介绍
CAN总线基于差分信号驱动,只需要两根信号线即可完成通讯(CAN_H&CAN_L)
当高速CAN的两根信号电势差为2V左右时(CAN_H = 3.5 & CAN_L = 1.5)代表显性电平,逻辑为0
电势差为0V左右时(CAN_H = CAN_L = 2.5V)代表隐性电平,逻辑为1
在总线上显性电平具有很大的优先权,只要总线上有一个设备是显性电平,那么整根总线即为显性电平
相比较下隐性电平就比较‘弱势’,只有总线上所有设备均输出隐性电平时总线才会显示隐性
硬件原理
拿C8T6举例,我们可以看到MCU中的控制器是CAN_TX&CAN_RX,和前面介绍到的CAN_H&CAN_L不一样
这个时候就需要介绍一下CAN转换芯片了
稚辉君开源的电机驱动板中使用的是TI家的一款CAN芯片
在左上方串联了一个120Ω的电阻,他的作用是用于做阻抗匹配,以减少回波反射,简单来说就是优化信号,这个了解即可,并不是重点
我们要关注的是SN65HVD232DR这块芯片
基本工作流程就是单片机的控制信号通过CAN芯片处理输出CAN_H&CAN_L两个信号再输出给CAN外设驱动即可
CAN协议层
帧数据
CAN大致的帧数据种类有五种
简单来说
数据帧就是携带数据信息的帧
遥控帧就是请求发送数据的帧
错误帧就是提示出现错误的帧
过载帧就是提示没准备好的帧
间隔帧就是将帧与帧分隔的帧
其实了解了最主要的数据帧,其他帧也可以比较容易的掌握
一个标准的数据帧包含了以上几个段,最小单位是位
SOF为帧的起始,是一个显性信号
仲裁段又称ID,每个设备享有一个独立的ID,根据比较ID来决定设备的优先级
RTR代表了远程发送请求位,之前提到遥控帧就是请求发送数据,那么不难理解,当RTR位为1时代表该帧为遥控帧,为0时代表该帧为数据帧,遥控帧和数据帧的最大区别就在于遥控帧没有数据段
IDE代表扩展标识符位,用于控制这个帧是标准帧还是扩展帧
简单来说扩展帧就是对仲裁段中ID位数的补偿,若11位ID不够的情况下可以通过扩展转换成29位的ID
DLC段影响的就是定义数据的长度,直接控制的后面的数据段长度(0-8Byte)
CRC段就是用于校验,之前学习EEPROM的时候有提到,当时的外设就带有校验功能,通过一个多项式数学计算得出一个数值,将其与存储区的数值比较,若一致才代表数据无误,这里是一样的原理
ACK就相当于I2C的应答位,DEL是界定符,分隔用
最后的EOF段由7个隐性信号组成,结束段
位时序
在CAN通讯中,为了实现电平的正确采样,必须要严格把控位于位之间的时序同步,这个时候设计人员将一个位的数据分为四段:同步段SS | 传播时间段PTS | 相位缓冲段1PBS1 | 相位缓冲段2PBS2
具体作用如下
若时序上出现了延时,设备就会移动SS段使时序同步
且这里的每一段均由多个位时序组成,这个位时序可以理解为最小的工作周期Tq,Tq还可以用于计算传输的波特率
一个位就由上面的几个时间段组成,其中采样点在PBS1和PBS2之间,这两者的Tq值可以根据实际环境调整实现同步
仲裁机制
最后就是关于仲裁机制,其实就是总线根据ID的第一位开始仲裁,最先出现隐性电平的外设失去对总线的占用权