CAN协议
CAN简介 CAN 是 Controller Area Network 的缩写(以下称为 CAN),是 ISO国际标准化的,为适应“减少线束的数量”、“通过多个 LAN,进行大量数据的高速通信”的需要的串行通信协议。 CAN 控制器根据两根线上的电位差来判断总线电平。总线电平分为显性电平和隐性电平,二者必居其一。发送方通过使总线电平发生变化,将消息发送给接收方。
CAN连接图
CAN 协议具有以下特点。
(1) 多主控制 在总线空闲时,所有的单元都可开始发送消息(多主控制)。最先访问总线的单元可获得发送权(CSMA/CA方式*1)。多个单元同时开始发送时,发送高优先级 ID 消息的单元可获得发送权。 (2) 消息的发送 在 CAN协议中,所有的消息都以固定的格式发送。总线空闲时,所有与总线相连的单元都可以开始发送新消息。两个以上的单元同时开始发送消息时,根据标识符(Identifier以下称为 ID)决定优先级。ID 并不是表示发送的目的地址,而是表示访问总线的消息的优先级。两个以上的单元同时开始发送消息时,对各消息 ID的每个位进行逐个仲裁比较。仲裁获胜(被判定为优先级最高)的单元可继续发送消息,仲裁失利的单元则立刻停止发送而进行接收工作。 (3)系统的柔软性 与总线相连的单元没有类似于“地址”的信息。因此在总线上增加单元时,连接在总线上的其它单元的软硬件及应用层都不需要改变。 (4)通信速度 根据整个网络的规模,可设定适合的通信速度。在同一网络中,所有单元必须设定成统一的通信速度。即使有一个单元的通信速度与其它的不一样,此单元也会输出错误信号,妨碍整个网络的通信。不同网络间则可以有不同的通信速度。 (5) 远程数据请求 可通过发送“遥控帧” 请求其他单元发送数据。 (6) 错误检测功能·错误通知功能·错误恢复功能 所有的单元都可以检测错误(错误检测功能),检测出错误的单元会立即同时通知其他所有单元(错误通知功能)。 正在发送消息的单元一旦检测出错误,会强制结束当前的发送。强制结束发送的单元会不断反复地重新发送 此消息直到成功发送为止(错误恢复功能)。 (7) 故障封闭 CAN 可以判断出错误的类型是总线上暂时的数据错误(如外部噪声等)还是持续的数据错误(如单元内部故障、驱动器故障、断线等)。由此功能,当总线上发生持续数据错误时,可将引起此故障的单元从总线上隔离出去。 (8) 连接 CAN 总线是可同时连接多个单元的总线。可连接的单元总数理论上是没有限制的。但实际上可连接的单元数受总线上的时间延迟及电气负载的限制。降低通信速度,可连接的单元数增加;提高通信速度,则可连接 的单元数减少
错误状态的种类 单元始终处于 3 种状态之一。 (1) 主动错误状态 主动错误状态是可以正常参加总线通信的状态。 处于主动错误状态的单元检测出错误时,输出主动错误标志。 (2) 被动错误状态 被动错误状态是易引起错误的状态。 处于被动错误状态的单元虽能参加总线通信,但为不妨碍其它单元通信,接收时不能积极地发送错误通知。 处于被动错误状态的单元即使检测出错误,而其它处于主动错误状态的单元如果没发现错误,整个总线也被认为是没有错误的。处于被动错误状态的单元检测出错误时,输出被动错误标志。 另外,处于被动错误状态的单元在发送结束后不能马上再次开始发送。在开始下次发送前,在间隔帧期间内必须插入“延迟传送”(8 个位的隐性位)。 (3) 总线关闭态 总线关闭态是不能参加总线上通信的状态,信息的接收和发送均被禁止。 这些状态依靠发送错误计数和接收错误计数来管理,根据计数值决定进入何种状态。错误状态和计数值的关系如下 关系简图如下 错误计数值 发送错误计数值和接收错误计数值根据一定的条件发生变化(错误计数值的变动条件如下图所示)。一次数据的接收和发送可能同时满足多个条件,错误计数器在错误标志的第一个位出现的时间点上开始计数。
错误计数值的变动条件
ISO 标准化的 CAN 协议
CAN 协议经 ISO 标准化后有 ISO11898 标准和 ISO11519-2 标准两种。ISO11898 和 ISO11519-2标准对于数据链路层的定义相同,但物理层不同。 (1) 关于 ISO11898 ISO11898 是通信速度为 125kbps-1Mbps的 CAN 高速通信标准。 目前,ISO11898 追加新规约后,成为 ISO11898-1 新标准。 (2) 关于 ISO11519 ISO11519 是通信速度为 125kbps 以下的 CAN 低速通信标准。 ISO11519-2 是 ISO11519-1追加新规约后的版本。 下图 表示 CAN 协议和 ISO11898 及 ISO11519-2 标准的范围。 物理层的不同点 如上图所示,ISO11898 和 ISO11519-2 在 CAN 协议中物理层的标准有所不同。CAN 协议的物理层如下图 所示,定义了三个子层,ISO11898 和 ISO11519-2 在物理层中的 PMA 层和 MDI 层有所不同。 *1 PLS: Physical Signaling Sublayer (物理信号子层) *2 PMA: Physical Medium Attachment (物理介质连接) *3 MDI: Medium Dependent Interface (介质相关接口)
总线拓扑 CAN 收发器根据两根总线(CAN_High 和 CAN_Low)的电位差来判断总线电平。总线电平分为显性电平和隐性电平两种,总线必须处于两种电平之一。总线上执行逻辑上的线“与”时,显性电平为“0”,隐性电平为“1”。 帧的种类 通信是通过以下 5 种类型的帧进行的:数据帧、遥控帧、错误帧、过载帧、帧间隔。 另外,数据帧和遥控帧有标准格式和扩展格式两种格式。标准格式有 11 个位的标识符(Identifier: 以下称 ID),扩展格式有 29 个位的 ID。
帧的种类及其构成示意图 数据帧 (1) 帧起始 表示数据帧开始的段。 (2) 仲裁段 表示该帧优先级的段。 (3) 控制段 表示数据的字节数及保留位的段。 (4) 数据段 数据的内容,可发送 0~8 个字节的数据。从最高位(MSB)开始输出。 (5) CRC 段 检查帧的传输错误的段。由 15 个位的 CRC 顺序*1 和 1 个位的 CRC 界定符(用于分隔的位)构成。 CRC 顺序是根据多项式生成的 CRC 值,CRC 的计算范围包括帧起始、仲裁段、控制段、数据段。接收方以同样的算法计算 CRC 值并进行比较,不一致时会通报错误 (6) ACK 段 表示确认正常接收的段。 (7) 帧结束 表示数据帧结束的段,用来确认是否正常接收。 遥控帧 接收单元向发送单元请求发送数据所用的帧。遥控帧由 6 个段组成。遥控帧没有数据帧的数据段。 (1) 帧起始(SOF):表示帧开始的段。 (2) 仲裁段:表示该帧优先级的段。可请求具有相同 ID 的数据帧。 (3) 控制段:表示数据的字节数及保留位的段。 (4) CRC 段:检查帧的传输错误的段。 (5) ACK 段:表示确认正常接收的段。 (6) 帧结束:表示遥控帧结束的段。 数据帧和遥控帧的不同 遥控帧的 RTR 位为隐性位,没有数据段。 没有数据段的数据帧和遥控帧可通过 RTR 位区别开来。 遥控帧没有数据段,数据长度码该如何表示? 遥控帧的数据长度码以所请求数据帧的数据长度码表示。 没有数据段的数据帧有何用途? 例如,可用于各单元的定期连接确认/应答、或仲裁段本身带有实质性信息的情况下。 帧间隔 帧间隔是用于分隔数据帧和遥控帧的帧。数据帧和遥控帧可通过插入帧间隔将本帧与前面的任何帧(数据帧、遥控帧、错误帧、过载帧)分开。过载帧和错误帧前不能插入帧间隔。 (1) 间隔 3 个位的隐性位。 (2) 总线空闲 隐性电平,无长度限制(0 亦可)。 本状态下,可视为总线空闲,要发送的单元可开始访问总线。 (3) 延迟传送(发送暂时停止) 8 个位的隐性位。 只在处于被动错误状态的单元刚发送一个消息后的帧间隔中包含的段。 过载帧 过载帧是用于接收单元通知其尚未完成接收准备的帧。过载帧由过载标志和过载界定符构成。 (1) 过载标志 6 个位的显性位。 过载标志的构成与主动错误标志的构成相同。 (2) 过载界定符 8 个位的隐性位。 过载界定符的构成与错误界定符的构成相同。 错误帧 用于在接收和发送消息时检测出错误通知错误的帧。错误帧由错误标志和错误界定符构成。 错误帧的构成如图 25 所示。 (1) 错误标志 错误标志包括主动错误标志和被动错误标志两种。 主动错误标志:6 个位的显性位。 被动错误标志:6 个位的隐性位。 (2) 错误界定符 错误界定符由 8 个位的隐性位构成。
位填充 位填充是为防止突发错误而设定的功能。当同样的电平持续 5 位时则添加一个位的反型数据。 (1) 发送单元的工作 在发送数据帧和遥控帧时,SOF~CRC 段间的数据,相同电平如果持续 5 位,在下一个位(第 6 个位)则要插入 1 位与前 5 位反型的电平。 (2) 接收单元的工作 在接收数据帧和遥控帧时,SOF~CRC 段间的数据,相同电平如果持续 5 位,需要删除下一个位(第 6 个位)再接收。如果这个第 6 个位的电平与前 5 位相同,将被视为错误并发送错误帧。 CAN的硬件连接(以A、B两个F407为例) (1)(A)CANL接(B)CANL,(A)CANH接(A)CANH; (2)PA11引脚接CAN_RX,PA12接CAN_TX。 CAN的控制器 STM32自带CAN的外设bxCAN,特点如下 1.支持CAN协议的2.0A和2.0B主动模式。 2.波特率最高达1Mbps 3.支持时间触发通讯 4.具有三个发送邮箱 5.具有三级深度的两个接收FIFO 6.可变的筛选器组(也称过滤器组,最多28个) 控制器模式: 工作模式(以下为CAN_MCR寄存器的位) 1.初始化模式(INRQ=1,SLEEP=O) 2.正常模式(INRQ=0, SLEEP=0) 3.睡眠模式(SLEEP=1) 测试模式(以下为CAN_BTR寄存器的位) 1静默模式(LBKM=0,SILM=1) 2.环回模式(LBKM-1,SILM=O) 3.环回静默模式(LBKM=1,SILM=1) 标志符筛选器 CAN的标识符不表示目的地址而是表示发送优先级。接收节点根据标识符的值,来决定是否接收对应消息。 STM32 CAN控制器,提供了28个可配置的筛选器组(F1仅互联型才有28个,其他的只有14个),可降低CPU处理CAN通信的开销。 STM32 CAN控制器每个筛选器组由2个32位寄存器组成(CAN_ FxR1和CAN_FxR2, X=0~27)。根据位宽不同,每个筛选器组可提供: (1)1个32位筛选器,包括:STDID[10:0]、EXTID[17:0]、IDE和RTR位 (2)2个16位筛选器,包括:STDID[10:0]、IDE、RTR和EXTID[17:15]位筛选器可配置为:屏蔽位模式(只比较指定的位)和标识符列表(全部比较)模式。在屏蔽位模式下,标识符寄存器和屏蔽寄存器一起,指定报文标识符的任何一位,应该按照“必须匹配”或“不用关心”处理。而在标识符列表模式下,屏蔽寄存器也被当作标识符寄存器用。因此,不是采用一个标识符加一个屏蔽位的方式,而是使用2个标识符寄存器。接收报文标识符的每一位都必须跟筛选器标识符相同。
为了过滤出一组标识符,应该设置筛选器组工作在屏蔽位模式。 为了过滤出一个标识符,应该设置过滤器组工作在标识符列表模式。 应用程序不用的筛选器组,应该保持在禁用状态(通过CAN_ FA1R设置)。 筛选器组中的每个筛选器,都被编号为(即:筛选器编号)从0开始,到某个最大数值一取决于筛选器组的模式和位宽的设置。 (标识符掩码的比较)通过CAN FFA1R的设置,可以将筛选器组关联到FIFO0/FIFO1例:设置筛选器组0工作在:1个32位筛选器-标识符屏蔽模式,然后设置CAN_F0R1 =0xFFFF0000,CAN_ F0R2=0xFF00FF00。其中存放到CAN_F0R1的值就是期望收到的ID,即(STID+EXTID+IDE+RTR)最好是:0xFFFF0000.而0xFF00FF00就是设置我们需要必须关心的ID,表示收到的映像,其位[31:24]和位[15:8]这16个位的必须和CAN_F0R1中对应的位~模一样,而另外的16个位则不关心,可以一样,也可以不一样,都认为是正确的ID,即收到的映像必须是0xFFxx00xx,才算是正确的(x表示不关心)。 CAN发送流程 程序选择1个空置的邮箱(TME=1)→设置标识符(ID)数据长度和发送数据->设置CAN_TIxR的 TXRQ位为1,请求发送→邮箱挂号(等待成为最高优先级)→预定发送(等待总线空闲)→发送→邮箱空置。 CAN接收流程 CAN接收流程为: FIFO空→收到有效报文→挂号_1(存FIFO的一个邮箱,这个由硬件控制,我们不需要理会)→收到有效报文→挂号_2→收到有效报文→挂号_3→收到有效报文→溢出。 CAN收到的有效报文,存储在3级邮箱深度的FIFO中。 FIFO接收到的报文数,我们可以通过查询CAN_RFXR的FMP寄存器来得到,只要FMP不为0,我们就可以从FIFO读出收到的报文。 报文FIFO具有锁定功能(由CAN_ MCR,CAN_RFLM位控制),锁定后,新数据将丢弃,不锁定则新数据代替老数据。 CAN位时序寄存器CAN_BTR (1)位31SILM:静默模式(调试)(Silent mode (debug)) 0:正常工作 1:静默模式 (2)位30:LBKM:环回模式(调试)(Loop back mode (debug)) 0:禁止环回模式 1:使能环回模式 (3)位29:26保留,必须保持复位Y: (4)位25:24SJW[1:0]:再同步跳转宽度(Resynchronization jump width) 这些位定义CAN硬件在执行再同步时最多可以将位加长或缩短的时间片数目。 t(RJW )= t(CAN) × (SJW[1:0]+ 1) (5)位23保留,必须保持复位值。 (6)位22:20 TS2[2:0]:时间段2 (Time segment 2) 这些位定义时间段2中的时间片数目。 t(BS2) = t(CAN)× (TS2[2:0]+1) (7)位19:16 TS1[3:0]:时间段1 (Time segment 1) 这些位定义时间段1中的时间片数目。 t(BS1) = t(CAN)× (TS1[3:0]+1) (8)位15:10保留,必须保持复位值。 (9)位9:0 BRP[9:0]:波特率预分频器(Baud rate prescaler) 这些位定义一个时间片的长度。 t(q)=(BRP[9:0]+1) x t(PCLK)
CAN_RF0R用于FIFO0控制,CAN_RF1R用汉语FIFO1控制。
CAN_RF0R 位 31:6 保留,必须保持复位值。 位 5 RFOM0:释放 FIFO 0 输出邮箱 (Release FIFO 0 output mailbox) 由软件置 1,用于释放 FIFO 的输出邮箱。FIFO 中至少有一条消息挂起时,才能释放输出邮 箱。FIFO 为空时,将此位置 1 没有任何作用。如果 FIFO 中至少有两条消息挂起,软件必须 释放输出邮箱,才能访问下一条消息。 输出邮箱释放后,此位由硬件清零。 位 4 FOVR0:FIFO 0 上溢 (FIFO 0 overrun) FIFO 填满时,如果接收到新消息并且通过筛选器,此位将由硬件置 1。 此位由软件清零。 位 3 FULL0:FIFO 0 满(FIFO 0 full) FIFO 中存储三条消息后,由硬件置 1。 此位由软件清零。 位 2 保留,必须保持复位值。 位 1:0 FMP0[1:0]:FIFO 0 消息挂起 (FIFO 0 message pending) 这些位用于指示接收 FIFO 中挂起的消息数。 硬件每向 FIFO 存储一条新消息,FMP 即会增加。软件每次通过将 RFOM0 位置 1 来释放输 出邮箱,FMP 即会减小。 CAN_RF1R 位 31:6 保留,必须保持复位值。 位 5 RFOM1:释放 FIFO 1 输出邮箱 (Release FIFO 1 output mailbox) 由软件置 1,用于释放 FIFO 的输出邮箱。FIFO 中至少有一条消息挂起时,才能释放输出邮箱。FIFO 为空时,将此位置 1 没有任何作用。如果 FIFO 中至少有两条消息挂起,软件必须释放输出邮箱,才能访问下一条消息。 输出邮箱释放后,此位由硬件清零。 位 4 FOVR1:FIFO 1 上溢 (FIFO 1 overrun) FIFO 填满时,如果接收到新消息并且通过筛选器,此位将由硬件置 1。 此位由软件清零。 位 3 FULL1:FIFO 1 满 (FIFO 1 full) FIFO 中存储三条消息后,由硬件置 1。 此位由软件清零。 位 2 保留,必须保持复位值。 位 1:0 FMP1[1:0]:FIFO 1 消息挂起 (FIFO 1 message pending) 这些位用于指示接收 FIFO1 中挂起的消息数。 硬件每向 FIFO1 存储一条新消息,FMP1 即会增加。软件每次通过将 RFOM1 位置 1 来释放 输出邮箱,FMP 即会减小。
每个筛选器组的CAN FiRx都由2个32位寄存器构成,即:CAN_FiR1和CAN_FiR2。根据过滤器位宽和模式的不同设置,这两个寄存器的功能也不尽相同。
初始化流程 1.配置相关引脚的复用功能,使能CAN时钟。 要用CAN,先要使能CAN的时钟. CAN的时钟通过APB1ENR的第25位来设置。其次要设置CAN的相关引脚为复用输出,这里我们需要设置PA11为上拉输入(CAN_RX引脚) PA12为复用输出(CAN_TX引脚),并使能PA口的时钟 2.设置CAN工作模式及波特率等。 通过先设置CAN_ MCR寄存器的INRQ位,让CAN进入初始化模式,然后设置CAN_MCR的其他相关控制位。再通过CAN_BTR设置波特率和工作模式(正常模式/环回模式)等信息。最后设置INRQ为0,退出初始化模式。 3.设置滤波器。 使用筛选器组0,并工作在32位标识符屏蔽位模式下先设置CAN_FMR的FINIT位,进入初始化模式。然后设置筛选器组0的工作模式以及标识符ID和屏蔽位。最后激活筛选器,并退出初始化模式。
|