CAN通信协议
一、应用范围:
广泛应用于汽车电子行业,其优点在于传输距离远,抗电磁干扰能力强,有错误检测,错误通知以及自动重传等功能。
物理层: 串行异步通信,半双工。CAN通信节点由CAN控制器和CAN收发器组成,只有两根信号线,CAN_H和CAN_L,用于产生差分信号来表示显性电平和隐性电平。
显性电平:记产生差分信号的两根线的电压差为显性电平时,为逻辑0
隐性电平:记产生差分信号的两根线的电压差为隐性电平时,为逻辑1,
这里的逻辑0或1则是我们在通信时所说的高低电平,也就是我们传输的数据。由于各节点共用一条总线,对于同一时刻的发送的两个电平,假如一个显性电平一个隐性电平,因为显性电平为逻辑0,由于线与的缘故总线总是处于显性电平的状态,这就是显性电平的由来。同理,参考下iic协议,对于各个节点都有自己的ID地址,通信时主机先选择从机的ID地址然后再进行数据通信,CAN通信过程中的ID则是包含在报文中的,对于同一时刻发送的报文通过比较报文的ID来进行优先级的仲裁,那么怎么进行仲裁呢,答案是根据ID中谁先出现显性电平为止,即谁先把总线拉低。
协议层: 波特率与位同步:波特率自然不用多说,对于异步通信是必须设置的。位同步则是CAN协议的特点之一,CAN使用“位同步”的方式来抗干扰、吸收误差,实现对总线电平信号进行正确的采样,确保通讯正常。对于位同步时序需要了解的内容有,CAN通信中将一个位的传输时间进行了进一步的划分,主要包括四个部分:SS段、PTS段、PBS1段、PBS2段,分解后最小的时间单位是Tq,而一个完整的位由8~25个Tq 组成。这四个段各表示什么呢,SS段称为同步段,是一个位最开始的部分,当检测到总线上信号的跳变沿处于该段,则可表示节点与总线的时序是同步的。PTS段译为传播时间段,这个时间段是用于补偿网络的物理延时时间。PBS1段和PBS2段,译为相位缓冲段,主要用来补偿边沿阶段的误差。怎么补偿这里举个例子,对于SS段之前说过是用来检测总线上的信号跳变是否处于该段,若不处于该段则不同步,那么不同步怎么办呢,就通过PBS1或者PBS2段来进行补偿了,PBS1和PBS2段的区别就是一个可以增加时间,一个可以减少时间。若SS段滞后了 2个Tq, 那么就通过PBS2段来减少2个tq使得下次的数据获得同步。这种方式也叫作重新同步。一般CAN内部的寄存器会通过设置SJW的值来控制PBS1或者PBS2段增加或减少的最大Tq值。在约定好一个Tq的时间长度以及一个位需要多少个Tq后则可以确定总线的波特率了,然后再根据外设时钟来设置预分频系数。
报文结构及种类:起初对CAN通信的报文感到十分复杂,不明其原理,为什么要这样设计。看到火哥书里的一段话后恍然大悟:
在SPI 通讯中,片选、时钟信号、数据输入及数据输出这4 个信号都有单独的信号线,I2C 协议包含有时钟信号及数据信号2 条信号线,异步串口包含接收与发送2 条信号线,这些协议包含的信号都比CAN协议要丰富 ,它们能轻易进行数据同步或区分数据传输方向。而CAN 使用的是两条差分信号线,只能表达一个信号,简洁的物理层决定了CAN必然要配上一套更复杂的协议,如何用一个信号通道实现同样、甚至更强大的功能呢? CAN协议给出的解决方案是对数据、操作命令(如读/写)以及同步信号进行打包,打包后的这些内容称为报文。确实,你虽然有两根线,但是只能发出一个信号,你怎么用这一个信号来表示你什么时候开始发数据,发送的是什么类型的数据,是数据啊还是命令啊还是报错啊。你发的数据是多长,你数据内容是什么,数据发的内容出没出现错误,数据什么时候发完了。这都是需要考虑的事情。
我们一个一个解决,从数据帧来解读报文的格式。目前学到的协议来看,不论是uart还是iic他们总线的空闲状态总是处于高电平,CAN通信也是如此,那么起始信号也就很好想了,即一个显性电平来吧总线拉低,表示开始发送数据,起始信号后紧跟着的是仲裁段,它的作用是什么呢,想象一下如果有两个节点同时发送数据,谁的数据优先级更高,这就需要进行仲裁了,仲裁后的优先级较高的节点数据可以发出,较低的节点则进入接收状态。仲裁的原理刚刚介绍过,是利用线与的特性,谁先出现显性电平把总线拉低谁的优先级就更高。一般用来仲裁的ID有两种格式,一个为标准格式ID,共11位,一种为扩展格式ID,共29位。而ID只是仲裁段的一部分,仲裁段还包括什么呢,想一想就知道了,既然分标准格式和扩展格式,那么就需要一个来表示是标准格式还是扩展格式的位称他为IDE位,此外还有RTR位,是用来区分这段报文是什么类型的,是数据帧啊还是遥控帧(请求发送数据的帧)。另外的SRR位只存在于扩展格式里,是用于代替标准格式中的RTR位。紧接着仲裁段的就是控制段了,最主要的位是DLC,用来表示这段报文里实际上要发送数据的长度,另外还有两个位r0,r1预留扩展的。紧接着控制段的是数据段用来存放数据,然后是CRC校验码,ACK段类似于IIC,再就是帧结束信号了,用7个隐性电平来表示发送结束。
对CAN通信的协议层和物理层有了了解之后,再就是硬件相关的一些东西了。以stm32f4系列的bxCAN为例:具有三个发送邮箱,两个三级深度的接收FIFO,还具有滤波器来筛选接收的报文ID,可配置自动重发等。STM32的有两组CAN控制器,其中CAN1是主设备,bxCAN的存储访问控制器”是由CAN1 控制的,CAN2无法直接访问存储区域,所以使用CAN2的时候必须使能CAN1外设的时钟。对于具体的功能在实际应用过程中只需要大致了解下即可。对于bxCAN主要有四种工作模式,分别为:正常模式,回环模式,静默模式,静默回环模式。四种工作模式的区分看图即可分辨。下面对CAN的HAL库做下简单介绍:
HAL库提供的接口函数有
HAL_CAN_Init()用来初始化CAN的参数,
HAL_CAN_Start()开启CAN
HAL_CAN_ActivateNotification()用于CAN的FIFO消息挂起中断允许
HAL_CAN_ConfigFilter(): CAN滤波功能的相关配置
HAL_CAN_AddTxMessage(): 发消息 相当于原来的HAL_CAN_Transmit
HAL_CAN_GetRxMessage(): 收消息 相当于原来的HAL_CAN_Receive