STM32F4-CAN

CAN简介 

CAN背景概括

        在当前的汽车产业中,出于对安全性、舒适性、方便性、低公害、低成本的要求,各种各样的电子控制系统被开发了出来。这些系统之间通信所用的数据类型及对可靠性的要求不尽相同,由多条总线构成的情况很多,线束的数量也随之增加。为适应“减少线束的数量”、“通过多个LAN,进行大量数据的高速通信”的需要。1986年德国电气商-博世公司开发出面向汽车的CAN通信协议。此后,CAN通过ISO11898及ISO11519进行了标准化,在欧洲已是汽车网络的标准协议。现在,CAN 的高性能和可靠性已被认同,并被广泛应用于工业自动化、船舶、医疗设备、工业设备等方面。

CAN协议的主要内容

CAN是 Controller Area Network 的缩写(简称为 CAN),是ISO 国际标准化的串行通信协议。

CAN通讯是异步,半双工通讯协议:没有时钟信号线来保持信号接、收同步。也无法同时发送与接收,在同一时刻,只能有一个节点发送数据,其余节点都只能接收数据。它有CAN_HIGH与CAN_LOW两条信号线组成。

节点:是由一个CAN控制器和一个CAN收发器组成(如下CAN总线结构图)

CAN 控制器根据两根线上的电位差来判断总线电平。

总线电平分为显性电平和隐性电平,二者必居其一。发送方通过使总线电平发生变化,将消息发送给接收方。

CAN 协议经过ISO标准化后有两个标准:ISO11898标准和 ISO11519标准。

  • ISO-11898:是针对通信速率为 125Kbps~1Mbps 的高速通信标准。属于闭环总线,传输速率可达1Mbps,总线长度 ≤ 40米。
  • ISO-11519:是针对通信速率为 125Kbps以下的低速通信标准。属于开环总线,传输速率为40kbps时,总线长度可达1000米。
ISO11898 和 11519-2 物理层的主要不同点

CAN总线结构图(高速/低速)

双绞线形式(抗干扰)

CAN总线信号

CAN总线上,信号表现为电压形式,通过CAN_H和CAN_L线上的电位差来表示CAN信号,分为显性电平和隐性电平两种类型。其中显性电平规定为逻辑 0 ,隐性电平则为逻辑 1 

如下图:当CAN_H和CAN_L的电压均为2.5v,两者电压差为0,就规定CAN信号为隐性电平;当CAN_H的电压为3.5v,CAN_L的电压为1.5v,两者电压差为2V,就规定CAN信号为显性电平。这里实际的规定是:电压差满足定义的一定范围,就可以认为是显性电平或者隐性电平,比如电压差在1.5-2.5v范围,都认为是显性电平。

实际的规定如下图:电压差满足定义的一定范围,就可以认为是显性电平或者隐性电平,比如电压差在1.5-2.5v范围,都认为是显性电平。

CAN信号传输

上述的电位差(差分电平)与逻辑电平由CAN收发器实现。

发送过程中:CAN控制器将CPU传来的信号转换为逻辑电平。CAN收发器接收逻辑电平之后,再将其转换为差分电平输出到CAN总线上。

接收过程中:CAN收发器将CAN_H和 CAN_L线上传来的差分电平转换为逻辑电平输出到CAN控制器,CAN控制器再把该逻辑电平转化为相应的信号发送到CPU上。

总的来说就是:发送方通过CAN收发器使总线电平发生变化,将其信息传递到CAN总线上。接收方通过监听总线电平,将总线上的消息读入自己的CAN收发器。

信号转换功能的实现:有的集成在单片机内部,有的外部挂载信号转换芯片。

开发板板载转换信号的芯片TJA1050如下:在收发器部分,逻辑信号和差分信号的转换。

CAN总线的2种架构如下两图:

闭环总线架构:起止端都有一个 120Ω的终端电阻,终端电阻的作用是匹配总线的特性阻抗,防止信号的反射和折射,确保信号稳定传输。没有终端电阻将导致信号反射,从而降低总线通信的质量和可靠性。电阻与CAN_H和CAN_L线之间连接,帮助形成差分信号,差分信号可以抵消共模噪声对总线的影响,提高总线抗噪声性能。

开环总线架构:在开环总线架构中,电阻的阻值为2.2KΩ,通过匹配特性阻抗,可以减少信号的反射和折射,防止信号干扰和失真,确保信号的传输质量。终端电阻起到抑制总线信号振荡和共振的作用。当信号在总线上传输时,会遇到来自总线长度、传输速率和电缆特性等因素引起的信号反射。终端电阻能有效地消除这些反射信号,防止信号叠加产生的振荡。终端电阻可以帮助降低外部噪声的干扰。电阻通过消耗部分噪声功率,减少噪声信号对总线上的CAN信号的影响。有助于提高总线的抗干扰能力。

CAN 总线协议具有以下特点
  • 多主控制。 在总线空闲时,所有单元都可以发送消息(多主控制),而两个以上的单元同时开始发送消息时, 根据标识符(Identifier 以下称为 ID)决定优先级。 ID 并不是表示发送的目的地址,而是表示访问总线的消息的优先级,ID在数据帧的仲裁段。两个以上的单元同时开始发送消息时,对各消息ID段的每个位进行逐个仲裁比较。仲裁获胜(被判定为优先级高)的单元可继续发送消息,仲裁失利的单元则立刻停止发送转为进行接收工作。
  • 系统的柔软性。 与总线相连的单元没有类似于“地址”的信息。因此在总线上增加单元时,连接在总线上的其它单元的软硬件及应用层都不需要改变。
  • 通信速度较快,通信距离远。 最高 1Mbps(距离小于 40M),最远可达 10KM(速率低于 5Kbps)。
  • 远程数据请求。可通过发送“遥控帧” 请求其他单元发送数据。
  • 具有错误检测、错误通知和错误恢复功能。 所有单元都可以检测错误(错误检测功能);检测出错误的单元会立即同时通知其他所有单元(错误通知功能); 正在发送消息的单元一旦检测出错误,会强制结束当前的发送。强制结束发送的单元会不断反复地重新发送此消息直到成功发送为止(错误恢复功能)。
  • 故障封闭功能。 CAN 可以判断出错误的类型是总线上暂时的数据错误(如外部噪声等)还是持续的数据错误(如单元内部故障、驱动器故障、断线等)。因此,当总线上发生持续数据错误时,可将引起此故障的单元从总线上隔离出去。
  • 连接节点多。 CAN 总线是可同时连接多个单元的总线。可连接的单元总数理论上是没有限制的。但实际上可连接的单元数受总线上的时间延迟及电气负载的限制。降低通信速度,可连接的单元数增加;提高通信速度,则可连接的单元数减少。

正是因为 CAN 协议的这些特点,使得 CAN 特别适合工业过程监控设备的互连,因此,越来越受到工业界的重视,并已公认为最有前途的现场总线之一。现场总线是当今自动化领域技术发展的热点之一,被誉为自动化领域的计算机局域网。它的出现为分布式控制系统实现各节点之间实时时、可靠的数据通信提供了强有力的技术支持。

多主控制

CAN总线上的所有节点没有主从之分,总线空闲状态下,任意节点都可以向总线上发送信息。最先向总线发送信息的节点获得总线的发送权(如下图所示);多个节点同时向总线发送消息时,仲裁确定所发送消息的优先权高的那个节点获得总线的发送权。

线与机制

线与机制简单说就是位与计算,显性电平会覆盖隐性电平。总线上的电平有显性电平和隐性电平两种。总线上执行逻辑上的线“与”时,显性电平的逻辑值为“0”,隐性电平为“1”。“显性”具有“优先”的意味,“有0则0”,只要有一个单元输出显性电平,总线上即为显性电平。并且,“隐性”具有“包容”的意味,“全1才1”,只有所有的单元都输出隐性电平,总线上才为隐性电平。 (显性电平比隐性电平更强。)

总线仲裁机制,如下图:

假设:CAN总线上只有两个节点 A和B,它俩的ID用逻辑电平表示,我们规定:从SOF位开始,从左往右逐位比较,只要出现位不一样,比较就结束,显性电平者仲裁胜出,优先发送。

当节点A,B都发送请求时,开始逐位比较,直到它俩的ID7位,节点A为显性电平,节点B为隐性电平。根据线与机制,节点A胜出,优先发送。这就是一个大致的非破坏性仲裁过程。为了精准地实施仲裁过程,CAN协议帧结构有严谨的设计。协议帧相关内容记在了接下来后面的部分。

仲裁时从ID开始比较,如果ID相同,还可能会比较RTR和SRR等位。作为发送方的节点会去接收自己发送的内容进行检查,即:回读机制(节点在向总线上发送报文的过程中,同时也对总线上的二进制位进行“回读”,对比该节点发出的二进制位与总线上当前的二进制位是否一致,就可判断节点数据是否被正确接收)。如下图:节点B/单元1回读总线上的位与自己发送的位不同,知道自己仲裁失利,转向接收数据。

通信速度

根据整个网络的规模,可设定适合的通信速度。在同一网络中,所有单元必须设定成统一的通信速度。即使有一个单元的通信速度与其它的不一样,此单元也会输出错误信号,妨碍整个网络的通信。不同网络间则可以有不同的通信速度。(简单一句话理解:双方必须需要在同一频道交流,不然沟通就有障碍)

信息广播功能:

CAN协议支持信息广播,即一个CAN节点可以将消息发送给网络上的所有其他节点。这意味着一个节点发送的信息可以被所有其他节点接收,而不仅限于特定的目标节点。

CAN协议可以广播各种类型的数据,包括控制命令、传感器数据、状态更新等。这样各个节点能够实时共享数据,提高系统的协同性和效率。

CAN协议还支持多播功能。多播是指一个节点可以将消息发送给网络上的一组特定节点,而不是所有节点。这允许节点只将信息发送给与其相关的节点,减少网络通信负载。

CAN网络上的节点可以独立地决定是否接收发送给它们的消息。这种独立性使节点能够自主地选择接收和处理感兴趣的消息,而忽略不关心的消息。

举例:总线上挂载了四个节点:A,B,C,D。当节点A发送一条信息,节点B,C,D都能收到的。B,C,D最终是否会接收这个节点A发送的信息,与他们设置相关。比如可以设置只有节点B设置接收,则C,D节点将会丢弃该条信息,这个过程与报文过滤相关。

CAN协议-报文(数据帧结构)

CAN 通信是通过以下 5 种类型的帧进行的:

数据帧和遥控帧有标准格式和扩展格式两种格式。标准格式有 11 个位的标识符(ID),扩展格式有 29 个位的 ID。最常用,最复杂的是数据帧。

数据帧

数据帧一般由 7 个段构成,即:
(1) 帧起始。表示数据帧开始的段。
(2) 仲裁段。表示该帧优先级的段。(也就是ID部分)
(3) 控制段。表示数据的字节数及保留位的段。
(4) 数据段。数据的内容,一帧可发送 0~8 个字节的数据。
(5) CRC 段。检查帧的传输错误的段。(校验)
(6) ACK 段。表示确认正常接收的段。
(7) 帧结束。表示数据帧结束的段。

数据帧的构成

注:D-显性电平,逻辑0,压差1.5-2V;R-隐性电平,逻辑1,压差0。

帧起始:标准格式帧和扩展格式帧都是由 1 个位的显性电平表示帧起始,告诉一声数据来了。
仲裁段:表示数据优先级的段,标准帧和扩展帧格式在本段如下区别:(图中标注)

控制段:控制段,由 6 个位构成,DLC四个位表示数据段的字节数。标准帧和扩展帧的控制段稍有不同。

数据段:该段可包含 0~8 个字节的数据。从最高位(MSB)开始输出。

CRC 段:该段用于检查帧传输错误。由15个位的CRC顺序和1个位的CRC界定符(用于分隔的位)组成,标准帧和扩展帧在这个段的格式也是相同的。

此段 CRC 的值计算范围包括: 帧起始、仲裁段、控制段、数据段。接收方以同样的算法计算 CRC 值并进行比较校验,不一致时会通报错误。

ACK 段:此段用来确认是否正常接收。由 ACK 槽(ACK Slot)和 ACK 界定符 2 个位组成。标准帧和扩展帧在这个段的格式也是相同的。

发送单元的 ACK段:发送 2 个位的隐性位。

接收到正确消息的单元在 ACK 槽发送显性位,通知发送单元正常接收结束,这个过程叫发送 ACK/返回 ACK。在ACK界定符发送隐性位。

发送 ACK 的是在既不处于总线关闭态也不处于休眠态的所有接收单元中,接收到正常消息的单元(接收单元发送ACK,发送单元不发送 ACK)。

正确消息是指不含填充错误、格式错误、 CRC 错误的消息。

帧结束:这个段也比较简单,标准帧和扩展帧在这个段格式一样, 由 7 个位的隐性位组成。

遥控帧

遥控帧的构成及标准/扩展格式区别(除没有0~64个Data位以外,其余与数据帧格式都相同。)

数据帧和遥控帧的不同遥控帧的 RTR 位为隐性位,没有数据段。没有数据段的数据帧和遥控帧可通过 RTR 位区别开来。
遥控帧没有数据段,遥控帧的数据长度码以所请求数据帧的数据长度码表示。
没有数据段的数据帧:可用于各单元的定期连接确认/应答、或仲裁段本身带有实质性信息的情况下。

错误帧

用于在接收和发送消息时检测出错误,通知错误的帧。错误帧由错误标志和错误界定符构成。

什么情况发送错误帧:按照CAN协议的规定

  • 位错误、填充错误、格式错误、ACK错误。在错误产生的那位的下一位开始发送错误帧。
  • CRC错误。紧随ACK界定符后的位发送错误帧。

错误标志包括主动错误标志( 6 个位的显性位。)和被动错误标志(6 个位的隐性位。)两种。

主动错误标志:处于主动错误状态的单元检测出错误时输出的错误标志。
被动错误标志:处于被动错误状态的单元检测出错误时输出的错误标志。

错误界定符由 8 个位的隐性位构成。

位填充:位填充是为防止突发错误而设定的功能当同样的电平持续 5 位时,则添加一个位的反型数据。

在发送数据帧和遥控帧时,SOF ~ CRC段间的数据,相同电平如果持续 5 位,则在下一个位(第 6 个位)要插入 1 位与前 5 位反型的电平。

在接收数据帧和遥控帧时,SOF ~ CRC段间的数据,相同电平如果持续 5 位,则需要删除下一个位(第 6 个位)再接收。如果这个第 6 个位的电平与前 5 位相同,将被视为错误并发送错误帧。

错误类型

注:位错误

  • 位错误由向总线上输出数据帧、遥控帧、错误帧、过载帧的单元和输出 ACK 的单元、输出错误的单元来检测。
  • 在仲裁段输出隐性电平,但检测出显性电平时,将被视为仲裁失利,而不是位错误。
  • 在仲裁段作为填充位输出隐性电平时,但检测出显性电平时,将不视为位错误,而是填充错误。
  • 发送单元在 ACK 段输出隐性电平,但检测到显性电平时,将被判断为其它单元的 ACK 应答,而非位错误。
  • 输出被动错误标志( 6 个位隐性位)但检测出显性电平时,将遵从错误标志的结束条件,等待检测出连续相同 6 个位的值(显性或隐性),并不视为位错误。

格式错误

  • 即使接收单元检测出 EOF( 7 个位的隐性位)的最后一位(第 8 个位)为显性电平,也不视为格式错误。
  • 即使接收单元检测出数据长度码( DLC)中 9∼15 的值时,也不视为格式错误。
错误状态的种类

单元始终处于 3 种状态之一:主动错误状态,被动错误状态,总线关闭态。
主动错误状态:是可以正常参加总线通信的状态。处于主动错误状态的单元检测出错误时,输出主动错误标志。
被动错误状态:是易引起错误的状态。处于被动错误状态的单元虽能参加总线通信,但为不妨碍其它单元通信,接收时不能积极地发送错误通知。处于被动错误状态的单元即使检测出错误,而其它处于主动错误状态的单元如果没发现错误,整个总线也被认为是没有错误的。处于被动错误状态的单元检测出错误时,输出被动错误标志。另外,处于被动错误状态的单元在发送结束后不能马上再次开始发送。在开始下次发送前,在间隔帧期间内必须插入“延迟传送”(8 个位的隐性位)。
总线关闭态:是不能参加总线上通信的状态。信息的接收和发送均被禁止。这些状态依靠发送错误计数和接收错误计数来管理,根据计数值决定进入何种状态。

以上这些状态依靠发送错误计数和接收错误计数来管理,根据计数值决定进入何种状态。错误状态和计数值的关系如下表以及图:

错误计数值
发送错误计数值和接收错误计数值根据一定的条件发生变化。错误计数值的变动条件如右表所示。
一次数据的接收和发送可能同时满足多个条件。错误计数器在错误标志的第一个位出现的时间点上开始计数。

错误帧发送的例子:

  1. 发送节点Node_A发送一个显性位,但是却从总线上听到一个隐形位,于是Node_A节点就会检测到一个位错误;
  2. Node_A检测到位错误之后,立即在下一位开始发送主动错误帧:6个连续显性位的主动错误标志+8个连续隐性位的错误界定符;
  3. 对应Node_A发出的主动错误标志,总线上电平为6个连续显性位;
  4. 接收节点Node_B和Node_C从总线上听到连续6个显性位,那么就会检测到一个填充错误,于是这两个节点都会发送主动错误帧;
  5. 对应Node_B和Node_C发出的主动错误标志,总线电平又有6个连续显性电平,对应Node_B和Node_C发出的错误界定符,总线电平有8个连续的隐性电平。
  6. 在间歇场之后,Node_A节点重新发送刚刚出错的报文。
过载帧

过载帧是用于接收单元通知其尚未完成接收准备的帧。过载帧由过载标志和过载界定符构成。过载帧的构成如下图:

过载标志:6 个位的显性位。过载标志的构成与主动错误标志的构成相同。
过载界定符:8 个位的隐性位。过载界定符的构成与错误界定符的构成相同。

 

过载帧的帧原理:接收节点达到接收极限时,就会发出过载帧到总线上。过载标志的6个连续显性位会屏蔽掉总线上其它节点的发送,接收节点通过发送过载帧的方式来破坏其它节点的发送,这样在接收节点发送过载帧期间,其它节点就不能成功发送报文,就相当于把其它节点的发送推迟了,也就是说接收节点在其发送过载帧的这段时间得以“休息”(我收满了,我不收了)。

有3种情况会引起过载帧:

  • 接收节点自身原因。接收节点由于某种原因需要延迟接收下一个数据帧或者遥控帧。
  • 在帧间隔的间歇段的第一位和第二位检测到一个显性位(正常的间歇段都是隐性位)。帧间隔的间隔段本应是三个连续的隐性位,如果接收节点在间隔段检测到显性位,那么就意味着此时有报文发向接收节点,但这个时候是不应该有报文发来的,于是接收节点发送过载帧。
  • CAN节点在错误界定符或过载界定符的第八位(最后一位)听到一个显性位0,节点会发送一个过载帧,且错误计数器不会增加。接收节点在错误界定符和过载界定符的最后一位听到显性位,也意味着有报文发向接收节点,但这个时候是不应该有报文发来的,于是接收节点发送过载帧。
帧间隔(间隔帧)

帧间隔是用于数据帧,遥控帧与前面帧分隔开的帧。数据帧和遥控帧可通过插入帧间隔将本帧与前面的任何帧(数据帧、遥控帧、错误帧、过载帧)分开。过载帧和错误帧前不能插入帧间隔。帧间隔的构成如下图:

间隔:3 个位的隐性位。
总线空闲:隐性电平,无长度限制(0 亦可)。本状态下,可视为总线空闲,要发送的单元可开始访问总线。
延迟传送(发送暂时停止):8 个位的隐性位。只在处于被动错误状态的单元刚发送一个消息后的帧间隔中包含的段。

为什么需要延迟传送段呢?

考虑主动错误状态的节点A,发送主动错误标志之后就要重新发送刚刚发送失败的报文,但是为了间隔开与前面刚刚发送的错误帧,总线在错误帧之后就会插入3个隐形位的帧间隔,在这3个隐形位期间,其它的节点不能判定总线空闲(需要连续11个隐性位才能判定),所以节点A仍然占据着总线的控制权,于是在帧间隔之后,节点A能够接着发送报文。现在节点A转入到被动错误状态了,说明它已经不是很可靠了,这个时候如果没有延迟传送段,在节点A发出被动错误标志之后,它仍然能够在3位的帧间隔之后立即重新发送报文,这是不符合我们对被动错误状态的处理要求的也不符合CAN协议,于是对于发送出被动错误标志的节点,总线在帧间隔中加入了8个连续隐性位的延迟传送段,这样的3+8=11个连续隐性位就能让节点A在这个帧间隔期间失去对总线的控制权,从而优先保证其它正常(处于主动错误状态)节点能够使用总线,而不必等着一个已经不可靠的节点A占据总线。

CAN通讯速率(位速率)

发送单元在非同步的情况下每秒钟发送的位数称为位速率。单位时间内总线上传输的信息量,即:每秒能够传输的二进制位的数量,单位:bit per second,简称:bps。比如:位速率为125kbps,意思为一秒传输125000 bit,包含了125000 个二进制事件的信息量。位速率与波特率可不是同一概念。位时间=1/ 波特率,知道位时间,我们就可以知道波特率。

接收方接收报文数据采用逐位逐位地接收方式。具体来说,将一个位分为4段:

  • 同步段(SS)
  • 传播时间段(PTS)
  • 相位缓冲段 1(PBS1)
  • 相位缓冲段 2(PBS2)

这些段又由可称为Time Quantum(以下称为Tq)的最小时间单位构成。1 位分为 4 个段,每个段又由若干个 Tq 构成,这称为位时序。1位由多少个 Tq 构成、每个段又由多少个 Tq 构成等,可以任意设定位时序。通过设定位时序,多个单元可同时采样,也可任意设定采样点。

下图为1个位的构成(假定1bit=10Tq):采样点是读取总线电平,并将读到的电平作为位值的点,位置在PBS1结束处。图中采样时间加大或减小(也就是采样点提前或者延后)量的最大值就是SJW。

 

CAN 协议的通信方法为 NRZ(Non-Return to Zero)方式。各个位的开头或者结尾都没有附加同步信号。发送单元以与位时序同步的方式开始发送数据。另外,接收单元根据总线上电平的变化进行同步并进行接收工作。
但是,发送单元和接收单元存在的时钟频率误差及传输路径上的(电缆、驱动器等)相位延迟会引起同步偏差。因此接收单元通过硬件同步或者再同步的方法调整时序进行接收。

硬同步:就是接收节点直接与发送节点同步。

如下图:发送节点A在发送SOF位时,SOF位的下降沿在SS段;这个时候接收节点B发现自己当前位的SS段和发送节点SOF位的SS段不同步。也就是说当A产生SOF位SS段时,B的当前位的SS段已经在5个Tq之前产生了;于是接收节点B强行将自己当前位的SS段拉到与发送节点A的SOF位的SS段同步。

再同步(重同步):接收节点检测出除SOF位以外的其他位时,进行的同步调整。再同步会通过加长PSB1段或缩短PBS2段来调整同步,以保证采样点的准确。每当检测出边沿时,根据 SJW 值通过加长 PBS1 段,或缩短 PBS2 段,以调整同步。但如果发生了超出 SJW值的误差时,最大调整量不能超过 SJW 值。

PSB1段加长的情况(发的晚,收的早这种情况的同步方式):

发送节点A比接收节点B的时间慢了,也就是说节点A当前位的SS段产生的时候,节点B当前位的SS段已经在2个Tq之前产生了;所以这个时候接收节点B就将PBS1延长2个Tq的时间。这样,保证节点A和B的采样点位置同步了。

PSB2段缩短的情况(发的早,收的晚这种情况的同步方式):

发送节点A当前位的SS段诞生2Tq时长之后,接收节点B的当前位才产生SS段;于是,接收节点B当前位的PBS2段缩短,这样就会导致接收节点B的下一位能够提前2个Tq,从而B的下一位采样点和A下一位的采样点能够同步。

硬件同步和再同步遵从如下规则。
(1) 1 个位中只进行一次同步调整。
(2) 只有当上次采样点的总线值和边沿后的总线值不同时,该边沿才能用于调整同步。
(3) 在总线空闲且存在隐性电平到显性电平的边沿时,则一定要进行硬件同步。
(4) 在总线非空闲时检测到的隐性电平到显性电平的边沿如果满足条件( 1)和( 2),将进行再同步。但还要满足下面条件。
(5) 发送单元观测到自身输出的显性电平有延迟时不进行再同步。
(6) 发送单元在帧起始到仲裁段有多个单元同时发送的情况下,对延迟边沿不进行再同步。

STM32F4的CAN控制器-bxCAN

bxCAN简介

基本扩展CAN外设又称 bxCAN,可与 CAN 网络进行交互。该外设支持 2.0A 和 B 版本的CAN协议,旨在以最少的 CPU 负载高效管理大量的传入消息,并可按需要的优先级实现消息发送。

bxCAN主要特性

支持 2.0 A 及 2.0 B Active 版本 CAN 协议;比特率高达 1 Mb/s;支持时间触发通信方案。

  • 发送

三个发送邮箱;可配置的发送优先级;SOF发送时间戳。

  • 接收

具有2个三级深度的接收 FIFO;可调整的筛选器组(也叫过滤器组):CAN1 和 CAN2 之间共享 28 个筛选器组;标识符列表功能;可配置的 FIFO 上溢;SOF 接收时间戳。

  • 时间触发通信方案:

禁止自动重发送模式;16 位自由运行定时器;在最后两个数据字节发送时间戳。

  • 管理

可屏蔽中断;在唯一地址空间通过软件实现高效的邮箱映射。

  • 双 CAN:

CAN1:主 bxCAN,用于管理 bxCAN 与 512 字节 SRAM 存储器之间的通信。
CAN2:从 bxCAN,无法直接访问 SRAM 存储器。
两个 bxCAN 单元共享 512 字节 SRAM 存储器。

STM32的CAN控制器的模式

  • 工作模式(通过CAN_MCR 寄存器控制 INRQ 或SLEEP 位控制)

初始化模式 (INRQ=1,SLEEP=O)

正常模式 (INRQ=0,SLEEP=O)

睡眠模式(SLEEP=1)

  • 测试模式(通过CAN_BTR寄存器控制LBKM 或SILM位控制)

静默模式 (LBKM=0,SILM=1)

环回模式( LBKM=1,SILM=0 )

环回静默模式 (LBKM=1,SILM=1)

  • 调试模式(用的很少)

当微控制器进入调试模式时( Cortex™-M4F 内核停止), bxCAN 可以继续正常工作,也可
以停止工作,具体取决于如下条件:

DBG 模块中用于CAN1的DBG_CAN1_STOP位或者用于CAN2的DBG_CAN2_STOP位。

CAN_MCR 中的 DBF 位。

工作模式

初始化模式:当硬件处于初始化模式时,可以进行软件初始化。在初始化模式下,所有从 CAN 总线传入和传出的消息都将停止,并且 CAN 总线输出 CANTX的状态为隐性(高)。

正常模式:一旦初始化完成,软件必须向硬件请求进入正常模式,这样才能在 CAN 总线上进行同步,并开始接收和发送。bxCAN 进入正常模式,并与 CAN 总线上的数据传输实现同步后,即可参与总线活动。执行这一步时,需要等待出现一个由 11 个连续隐性位(总线空闲状态)组成的序列。
睡眠模式(低功耗模式):为降低能耗功耗, bxCAN 具有低功耗模式,称为睡眠模式。该模式下, bxCAN 时钟停止,但软件仍可访问 bxCAN 邮箱。在 bxCAN 处于睡眠模式时,如果软件通过将 INRQ 位置 1 来请求进入初始化模式,同时必须将 SLEEP 位清零。软件将 SLEEP 位清零或是检测到 CAN 总线活动时, bxCAN 即被唤醒(退出睡眠模式)。
注:如果使能唤醒中断(CAN_IER 寄存器的 WKUIE 位置 1),即使 bxCAN 自动执行唤醒序列,
一旦检测到 CAN 总线活动,也会发生唤醒中断。

bxCAN工作模式图

测试模式

静默模式:在静默模式下, bxCAN 可以接收有效数据帧和有效遥控帧,但仅在 CAN 总线上发送隐性位,并且无法启动发送。如果 bxCAN 必须发送一个显性位( ACK 位、溢出标志、活动错误标志),该位将在内部被改道发送,以便 CAN 内核可以监视该显性位,但 CAN 总线可以保持
隐性状态。静默模式可用于分析 CAN 总线上的流量,同时又不会因发送显性位(确认位、错误帧)对其造成影响。

环回模式:在环回模式下,bxCAN 将其自身发送的消息作为接收的消息来处理并存储(如果这些消息通过了验收筛选)在接收邮箱中。该模式为自检功能提供。为了不受外部事件的影响, CAN 内核在环回模式下将忽略确认错误(在数据/远程帧的确认时隙不对显性位采样)。在此模式下, bxCAN 将执行从发送输出到接收输入的内部反馈。 bxCAN 将忽略 CANRX 输入引脚的实际值。从 CANTX 引脚可以监视发送的消息。

环回静默模式(用的较少):该模式下,bxCAN 可以像在环回模式下一样进行检测,同时又不会影响与 CANTX 和 CANRX 引脚相连接的运行中的 CAN 系统。在此模式下,CANRX 引脚与 bxCAN 断开连接, CANTX 引脚则保持隐性。

CAN控制器bxCAN框图

标识符筛选器

通过CAN_FM1R和CAN_FS1R可配置筛选器的位宽和模式。设置好筛选器之后,就可以自动判断数据是不是你想要的,不用CPU干预。CAN通讯不会对地址进行筛选,而是会在数据存放在FIFO前进行筛选,这个标识符筛选器就起到了筛选数据的作用。

根据长度分:

STM32CAN控制器每个筛选器组由2个32位寄存器组成 (CAN_FxR1和CAN_FxR2,x=0~27)。根据位宽不同,每个筛选器组可提供:

  • 1个32位筛选器,包括:STDID[10:0]、EXTID[17:0]、IDE和RTR位。
  • 2个16位筛选器,包括:STDID[10:0]、IDE、RTR和EXTID[17:15]位。
根据过滤方法分:

筛选器可配置为:标识符屏蔽位模式和标识符列表模式。在屏蔽位模式下,标识符寄存器和屏蔽寄存器一起,指定报文标识符的任何一位,应该按照“必须匹配”或“不用关心”处理。在标识符列表模式下,屏蔽寄存器也被当作标识符寄存器用。因此,不是采用一个标识符加一个屏蔽位的方式,而是使用2个标识符寄存器。接收报文标识符的每一位都必须跟筛选器标识符相同。

标识符列表模式:它把要接收报文的 ID 列成一个表,要求发来的报文的ID与列表中的某一个标识符完全相同才可以接收。

标识符屏蔽位模式(掩码模式):它把可接收报文 ID 的某几位作为列表,这几位被称为掩码,类似关键字,只要掩码(关键字)相同,就符合接收要求,报文就会被保存到接收 FIFO。

标识符筛选器,可配置成如下四种工作状态:
  • 1个32位筛选器-标识符掩码;
  • 2个32位筛选器-标识符列表;
  • 2个16位筛选器-标识符掩码;
  • 4个16位筛选器-标识符列表。

  • 为了过滤出一个标识符(ID),应该设置过滤器组工作在标识符列表模式。
  • 为了过滤出一组标识符(可能有多个ID),应该设置筛选器组工作在屏蔽位模式。
  • 应用程序不用的筛选器组,应该保持在禁用状态(通过CAN FA1R设置)。
  • 筛选器组中的每个筛选器,都被编号(即:筛选器编号)从0开始,到某个最大数值一取决于筛选器组的模式和位宽的设置。
  • 通过CAN_FFA1R的设置,可以将筛选器组关联到FIFO0/FIFO1。(筛选器组是可以关联到不同FIFO上面的)

举例:设置筛选器组0工作在1个32位筛选器-标识符屏蔽位模式,然后设置CAN_F0R1=0xFFFF0000,(掩码寄存器)CAN_F0R2=0XFF00FF00。其中存放到CAN_F0R1的值就是期望收到的ID,即 (STID+EXTID+IDE+RTR) 。最好是:0XFFFF000。而OXFF00FF00就是设置我们需要必须关心的ID,表示收到的映像,其位[31:24]和位[15:8]这16个位的必须和CAN_F0R1中对应的位一模一样,而另外的16个位则不关心,可以一样,也可以不一样,都认为是正确的ID,即收到的映像必须是0XFFxx00xx,才算是正确的(x表示不关心)。

标识符列表模式就把掩码寄存器CAN_F0R2改成与CAN_F0R1相同的ID值,只有与两个列表完全相同的ID才能通过筛选。

CAN控制器bxCAN的发送

CAN发送邮箱:数据帧里面包含很多段数据,这些数据就先存放在CAN的发送邮箱里。

FIFO:是一个先进先出的数据缓存器,我们也可以理解为一个寄存器,CAN发送邮箱中的数据经过筛选器会转到这里。

CAN控制器bxCAN的发送流程

程序选择1个空置的邮箱(TME=1)-->设置标识符(ID),数据长度,要发送的数据-->设置CAN_TIxR的TXRQ位为1,请求发送-->邮箱挂号(等待成为最高优先级)-->预定发送(等待总线空闲)-->发送-->邮箱空置。

CAN控制器bxCAN的接收流程

FIFO空-->收到有效报文-->挂号_1(存入FIFO的一个邮箱这个由硬件控制,我们不需要理会)-->收到有效报文-->挂号_2>收到有效报文-->挂号_3>收到有效报文-->溢出。

CAN收到的有效报文,存储在3级邮箱深度的FIFO中。FIFO接收到的报文数,我们可以通过查询CAN_RFxR的FMP寄存器来得到,只要FMP不为0,我们就可以从FIFO读出收到的报文。(三级邮箱满了若还没读走数据来释放邮箱,当再发来一个数据,就会发生溢出。报文FIFO具有锁定功能(由CAN_MCR,RFLM位控制),当发生溢出,锁定后,新数据丢弃;不锁定,则新数据代替老数据。)

STM32F4的CAN控制器bxCAN的位时序

STM32的bxCAN将传播时间段(PTS)和相位缓冲段 1(PBS1)合并成时间段1。

STM32F407,设TS1=6,TS2=5,BRP=5,波特率=42000/[(7+6+1)*6]=500Kbps。

STM32F4的CAN控制器bxCAN常用的寄存器

CAN主控制寄存器(CAN_MCR)

该寄存器的INRQ位,用来控制初始化请求

设置INRQ=0,可使CAN从初始化模式进入正常工作模式。

设置INRQ=1,可使CAN从正常工作模式进入初始化模式。

CAN初始化时,先设置INRQ=1 ,进入初始化模式,进行初始化 (尤其是CAN_BTR的设置,该寄存器,必须在CAN正常工作之前设置),之后再设置INRQ=0,进入正常工作模式。

CAN 位时序寄存器 (CAN_BTR)
CAN 接收 FIFO 0/1 寄存器 (CAN_RF0R/CAN_RF1R)
CAN 发送邮箱标识符寄存器 (CAN_TIxR) (x=0..2)

 CAN 邮箱数据长度控制和时间戳寄存器 (CAN_TDTxR) (x=0..2)
CAN 发送邮箱数据寄存器(CAN_TDLxR/CAN_TDHxR) (x=0..2)

上图为CAN_TDLXR寄存器,用于存储低4个字节的数据。CAN_TDHXR寄存器与之类似,用于存储高4个字节的数据。要发送的数据就是存储在这两个寄存器。

CAN 接收 FIFO 邮箱标识符寄存器 (CAN_RIxR) (x=0..1)
 CAN 接收 FIFO 邮箱数据长度控制和时间戳寄存器 (CAN_RDTxR) (x=0..1)
CAN 接收 FIFO 邮箱数据低位寄存器 (CAN_RDLxR/CAN_RDHxR) (x=0..1)

上图为CAN_RDLxR寄存器的描述,用于存储低4个字节的数据。CAN_RDHXR寄存器与之类似,用于存储高4个字节的数据。接收到的数据就存储在这两个寄存器。

CAN 筛选器模式寄存器 (CAN_FM1R)

该寄存器设置筛选器的工作模式,必须在CAN_FMR寄存器FINIT=1时配置。

CAN 筛选器尺度寄存器 (CAN_FS1R)

该寄存器用于设置筛选器的位宽,必须在CAN_FMR寄存器FINIT=1时配置。

CAN 筛选器 FIFO 分配寄存器 (CAN_FFA1R)

该寄存器设置报文通过筛选器组之后,被存入的FIFO,如果对应位为0,则存放到FIFO0,如果为1,则存放到FIFO1。该寄存器也只能在过滤器处于初始化模式(CAN_FMR寄存器的FINIT=1下配置。

CAN 筛选器激活寄存器 (CAN_FA1R)

该寄存器用于设置筛选器组的开启和关闭。对对应位置1,即开启对应的筛选器组,置0则关闭该筛选器组。

 筛选器组 i 寄存器 x (CAN_FiRx)( i=0..27, x=1, 2)

每个筛选器组的CAN_FiRx都由2个32位寄存器构成,即:CAN_FiR1和CAN_FiR2。根据过滤器位宽和模式的不同设置,这两个寄存器的功能也不尽相同。

CAN控制器初始化流程

配置相关引脚的复用功能,使能CAN时钟。
要用CAN,先要使能CAN的时钟,CAN的时钟通过APB1ENR的第25位来设置。其次要设置CAN的相关引脚为复用输出,这里我们需要设置PA11为上拉输入(CAN_RX引脚) PA12为复用输出 (CAN_TX引脚),并使能PA口的时钟。

设置CAN工作模式及波特率等
通过先设置CAN_MCR寄存器的INRQ位,让CAN进入初始化模式,然后设置CAN_MCR的其他相关控制位。再通过CAN_BTR设置波特率和工作模式(正常模式/环回模式)等信息。最后设置INRQ为0,退出初始化模式。

设置滤波器
本例程,我们将使用筛选器组0,并工作在32位标识符屏蔽位模式下。先设置CAN_FMR的FINIT位,进入初始化模式,然后设置筛选器组0的工作模式以及标识符ID和屏蔽位。最后激活筛选器,并退出初始化模式。

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值