STM32笔记(CAN通信协议详解)

目录

CAN协议简介

CAN物理层

[闭环总线网络( ISO11898 标准: 高速 CAN)](#闭环总线网络( ISO11898 标准: 高速 CAN))

[开环总线网络(低速CAN:125Kbps 以下)](#开环总线网络(低速CAN:125Kbps 以下))

通讯节点

差分信号

CAN协议层

CAN的报文种类及结构

报文的种类

数据帧的结构

帧开始(SOF段)

仲裁段

控制段

数据段

CRC段

ACK段

帧结束

其它报文的结构

CAN的波特率及位同步

位时序分解

SS段 (SYNC SEG)

PTS段 (PROP SEG)

PBS1段 (PHASE SEG1)

PBS2段 (PHASE SEG2)

通讯的波特率

同步过程分析

硬同步

重新同步

STM32的CAN外设简介

STM32的CAN架构剖析

主控制寄存器CAN_MCR

位时序寄存器(CAN_BTR)及波特率

STM32中CAN的位时序

STM32中CAN的波特率

CAN发送邮箱

CAN接收FIFO

验收筛选器

CAN通讯实验

代码源码自取

[注意:没有使用中断的接收FIFO是FIFO0, 使用中断接收FIFO是FIFO1。](#注意:没有使用中断的接收FIFO是FIFO0, 使用中断接收FIFO是FIFO1。)

主要代码解析

代码运行演示

连接好设备:

回环模式:

正常模式:


CAN协议简介

CAN 是控制器局域网络(Controller Area Network) 的简称,它是由研发和生产汽车电子产品著称的 德国BOSCH 公司开发的,并最终成为国际标准(ISO11519), 是国际上应用最广泛的现场总线之一。CAN 的高性能和可靠性已被认同,并被广泛地应用于工业自动化、船舶、医疗设备、工业设备等方面。

CAN 协议具有一下特点:

  • 多主控制: 总线空闲时,所有单元都可以发送消息(多主控制),而两个以上的单元

    同时开始发送消息时,根据标识符(Identifier以下称为ID)决定优先级。ID并不是表示发

    送的目的地址,而是表示访问总线的消息的优先级。

  • **通信速度较快,通信距离远:**最高1Mbps(距离小于40M),最远可达10KM(速率低于5Kbps)。

  • **具有错误检测、错误通知和错误恢复功能:**单元都可以检测错误(错误检测功能),检测出错误的单元会立即同时通知其他所有单元(错误通知功能),正在发送消息的单元一旦检测出错误,会强制结束当前的发送。

  • 连接节点多: CAN总线是可同时连接多个单元的总线。连接的单元总数理论上是没有限制的。实际上可连接的单元数受总线上的时间延迟及电气负载的限制。降低通信速度,可连接的单元数增加;提高通信速度,则可连接的单元数减少。

结合以上特点,所以CAN 特别适合工业过程监控设备的互连。

CAN 协议经过 ISO 标准化后有两个标准: ISO11898 标准(高速 CAN:125Kbps~1Mbps)ISO11519-2 标准(低速CAN:125Kbps 以下

CAN物理层

CAN通讯并不是以时钟信号来进行同步的, 它是一种异步通讯,只具有CAN_High 和CAN_Low 两条信号线,共同构成一组差分信号线,以差分信号的形式进行通讯。

闭环总线网络( ISO11898 标准: 高速 CAN)

总线两端各串联了 120Ω的电阻(用于阻抗匹配,减少回波反射),同时总线上可以挂载多个节点。

开环总线网络(低速CAN:125Kbps 以下)

通讯节点

CAN通讯节点由一个CAN控制器CAN收发器 组成,控制器与收发器之间通过CAN_Tx及CAN_Rx信号线相连, 收发器与CAN总线之间使用CAN_High及CAN_Low信号线相连。

差分信号

差分信号又称差模信号,与传统使用单根信号线电压表示逻辑的方式有区别,使用差分信号传输时,需要两根信号线, 这两个信号线的振幅相等,相位相反,通过两根信号线的电压差值来表示逻辑0 和逻辑1。

CAN协议中对它使用的CAN_High及CAN_Low表示的差分信号做了规定,显性电平对应逻辑 0, CAN_H 和 CAN_L 之差为 2 V 左右。而隐性电平对应逻辑 1, CAN_H 和 CAN_L 之差为 0V。

若同时一个输出隐性电平,另一个输出显性电平,类似I2C总线的"线与"特性将使它处于显性电平状态0。

CAN总线协议的物理层只有1对差分线,在一个时刻只能表示一个信号,所以对通讯节点来说,CAN通讯是半双工的,收发数据需要分时进行。

在CAN的通讯网络中,因为共用总线,在整个网络中同一时刻只能有一个通讯节点发送信号,其余的节点在该时刻都只能接收。

CAN协议层

CAN协议层则规定了通讯逻辑。

CAN的报文种类及结构

报文的种类

CAN一共规定了5种类型的帧。

帧的种类及其用途

|-----|---------------------------|
| 帧 | 帧用途 |
| 数据帧 | 用于节点向外传送数据 |
| 遥控帧 | 用于向远端节点请求数据 |
| 错误帧 | 用于向远端节点通知校验错误,请求重新发送上一个数据 |
| 过载帧 | 用于通知远端节点:本节点尚未做好接收准备 |
| 帧间隔 | 用于将数据帧及遥控帧与前面的帧分离开来 |

数据帧的结构

数据帧是在CAN通讯中最主要、最复杂的报文。

以下是对数据帧的详细解析:

数据帧具有标准格式和扩展格式 两种,区别就在于ID信息的长度, 标准格式的ID为11位,扩展格式的ID为29位,它在标准ID的基础上多出18位。

数据帧以一个显性位(逻辑0)开始(开始帧),以7个连续的隐性位(逻辑1)结束(结束帧),在它们之间,分别有仲裁段、控制段、数据段、CRC段和ACK段 。

注:D 表示显性电平, R 表示隐形电平

帧开始(SOF段)

SOF段(Start OfFrame),译为帧起始,帧起始信号只有一个数据位,是一个显性电平,它用于通知各个节点将有数据传输, 其它节点通过帧起始信号的电平跳变沿来进行硬同步。

仲裁段

仲裁段,报文的优先级,是通过对ID的仲裁来确定的。若两个节点同时竞争CAN总线的占有权,当它们发送报文时,若首先出现隐性电平,则会失去对总线的占有权,进入接收状态 。

示例如下图:

仲裁段ID的优先级也影响着接收设备对报文的反应。因为在CAN总线上数据是以广播的形式发送的,所有连接在CAN总线的节点都会收到所有其它节点发出的有效数据,因而我们的CAN控制器大多具有根据ID过滤报文的功能,它可以控制自己只接收某些ID的报文。

仲裁段除了报文ID外,还有RTR、IDE和SRR位:

  • RTR位 (Remote Transmission Request Bit),译作远程传输请求位,它是用于区分数据帧和遥控帧的, 当它为显性电平时表示数据帧,隐性电平时表示遥控帧。

  • IDE位 (Identifier ExtensionBit),译作标识符扩展位,它是用于区分标准格式与扩展格式, 当它为显性电平时表示标准格式,隐性电平时表示扩展格式。

  • SRR位 (Substitute Remote Request Bit),只存在于扩展格式,它用于替代标准格式中的RTR位。 由于扩展帧中的SRR位为隐性位,RTR在数据帧为显性位,所以在两个ID相同的标准格式报文与扩展格式报文中,标准格式的优先级较高。

控制段

控制段中的r1和r0为保留位,默认设置为显性位。它最主要的是DLC段(Data Length Code),译为数据长度码, 它由4个数据位组成,用于表示本报文中的数据段含有多少个字节,DLC段表示的数字为0~8。

数据段

数据段为数据帧的核心内容,它是节点要发送的原始信息,由0~8个字节组成,MSB先行

CRC段

CAN的报文包含了一段15位的CRC校验码,一旦接收节点算出的CRC码 跟接收到的CRC码不同, 则它会向发送节点反馈出错信息,利用错误帧请求它重新发送。CRC部分的计算一般由CAN控制器硬件完成,出错时的处理则由软件控制最大重发数。

CRC 的值计算范围包括:帧起始、仲裁段、控制段、数据段。

CRC校验码之后,有一个CRC界定符 ,它为隐性位,主要作用是把CRC校验码与后面的ACK段间隔起来。

ACK段

ACK段包括一个ACK槽位 ,和ACK界定符位 。类似I2C总线,在ACK槽位中,发送节点发送的是隐性位, 而接收节点则在这一位中发送显性位以示应答。在ACK槽和帧结束之间由ACK界定符间隔开。

帧结束

EOF段(End Of Frame),译为帧结束,帧结束段由发送节点发送的7个隐性位 表示结束。

其它报文的结构

CAN的波特率及位同步

CAN属于异步通讯,没有时钟信号线,连接在同一个总线网络中的各个节点会像串口异步通讯那样, 节点间使用约定好的波特率进行通讯,特别地,CAN还会使用"位同步" 的方式来抗干扰、吸收误差, 实现对总线电平信号进行正确的采样,确保通讯正常。

位时序分解

为了实现位同步,CAN协议把每一个数据位的时序分解成SS段、PTS段、PBS1段、PBS2段这四段 。

分解后最小的时间单位是Tq,而一个完整的位由8~25个Tq组成。

该图中表示的CAN通讯信号每一个数据位的长度为19Tq,其中SS段占1Tq,PTS段占6Tq,PBS1段占5Tq,PBS2段占7Tq。信号的采样点位于PBS1段与PBS2段之间,通过控制各段的长度,可以对采样点的位置进行偏移,以便准确地采样。

SS段 (SYNC SEG)

SS 译为同步段,多个连接在总线上的单元通过此段实现时序调整,同步进行接收和发送的工作。由隐性电平到显性电平的边沿或由显性电平到隐性电平边沿最好出现在此段中。SS段的大小固定为1Tq。

PTS段 (PROP SEG)

PTS 译为传播时间段,这个时间段是用于补偿网络的物理延时时间。是总线上输入比较器延时和输出驱动器延时总和的两倍。PTS段的大小可以为1~8Tq。

PBS1段 (PHASE SEG1)

PBS1 译为相位缓冲段,主要用来补偿边沿阶段的误差,它的时间长度在重新同步 的时候可以加长 。PBS1段的初始大小可以为1~8Tq。

PBS2段 (PHASE SEG2)

PBS2 这是另一个相位缓冲段,也是用来补偿边沿阶段误差的,它的时间长度在重新同步时可以缩短 。PBS2段的初始大小可以为2~8Tq。

通讯的波特率

总线上的各个通讯节点只要约定好1个Tq的时间长度以及每一个数据位占据多少个Tq,就可以确定CAN通讯的波特率。

如上图中的1Tq=1us,而每个数据位由19个Tq组成,则传输一位数据需要时间T1bit =19us,从而每秒可以传输的数据位个数为:

1x106­/19 = 52631.6 (bps)

每秒可传输的数据位的个数即为通讯中的波特率。

同步过程分析

波特率只是约定了每个数据位的长度,数据同步还涉及到相位的细节,这个时候就需要用到数据位内的SS、PTS、PBS1及PBS2段了。

CAN的数据同步分为硬同步和重新同步。硬同步只是当存在"帧起始信号"时起作用,无法确保后续一连串的位时序都是同步的,而重新同步方式可解决该问题。

硬同步

某个CAN节点通过总线发送数据时,它会发送一个表示通讯起始的信号(高跳变到低的下降沿 )。挂载到CAN总线上的通讯节点在不发送数据时,会时刻检测总线上的信号。

当总线出现帧起始信号时,某节点检测到总线的帧起始信号不在节点内部时序的SS段范围, 所以判断它自己的内部时序与总线不同步,因而这个状态的采样点采集得的数据是不正确的。 所以节点以硬同步的方式调整,把自己的位时序中的SS段平移至总线出现下降沿的部分,获得同步,同步后采样点就可以采集得正确数据了。

重新同步

利用普通数据位的高至低电平的跳变 沿来同步(帧起始信号是特殊的跳变沿)。重新同步与硬同步方式相似的地方是它们都使用SS段来进行检测,同步的目的都是使节点内的SS段把跳变沿包含起来 。重新同步的方式分为超前滞后两种情况,以总线跳变沿与SS段的相对位置进行区分。

相位超前的情况:

节点从总线的边沿跳变中, 检测到它内部的时序比总线的时序相对超前 2Tq,这时控制器在下一个位时序中的PBS1段增加 2Tq的时间长度,使得节点与总线时序重新同步。

相位滞后的情况:

节点从总线的边沿跳变中,检测到它的时序比总线的时序相对 滞后2Tq, 这时控制器在前一个位时序中的PBS2段减少 2Tq的时间长度,获得同步。

在重新同步的时候,PBS1和PBS2中增加或减少的这段时间长度被定义为"重新同步补偿宽度SJW* (reSynchronization Jump Width)"。

CAN控制器会限定SJW的最大值,如限定了最大SJW=3Tq时,单次同步调整的时候不能增加或减少超过3Tq的时间长度,若有需要,控制器会通过多次小幅度调整来实现同步。

当控制器设置的SJW极限值较大时,可以吸收的误差加大,但通讯的速度会下降。

STM32的CAN外设简介

STM32的芯片中具有bxCAN控制器 (Basic Extended CAN), 支持CAN协议2.0A和2.0B标准。

CAN控制器支持最高的通讯速率为1Mb/s;可以自动地接收和发送CAN报文,支持使用标准ID和扩展ID的报文;

STM32的CAN架构剖析

外设中具有3个发送邮箱,发送报文的优先级可以使用软件控制,还可以记录发送的时间;具有2个3级深度的接收FIFO,可使用过滤功能只接收或不接收某些ID号的报文;可配置成自动重发;不支持使用DMA进行数据收发。

CAN控制内核包含了各种控制寄存器及状态寄存器, 介绍需要用到的一些比较重要的寄存器。

主控制寄存器CAN_MCR

**DBF:**调试冻结,使用它可设置CAN处于工作状态或禁止收发的状态,禁止收发时仍可访问接收FIFO中的数据。这两种状态是当STM32芯片处于程序调试模式时才使用的,平时使用并不影响。

**TTCM:**时间触发模式,它用于配置CAN的时间触发通信模式 ,在此模式下,CAN使用它内部定时器产生时间戳, 并把它保存在CAN_RDTxR、CAN_TDTxR寄存器中。内部定时器在每个CAN位时间累加,在接收和发送的帧起始位被采样, 并生成时间戳。利用它可以实现ISO 11898-4 CAN标准的分时同步通信功能。

**ABOM:**自动离线管理,它用于设置是否使用自动离线管理功能。 当节点检测到它发送错误 或接收错误 超过一定值时,会自动进入离线状态 ,在离线状态中, CAN不能接收或发送报文。处于离线状态的时候,可以软件控制恢复或者直接使用这个自动离线管理功能,它会在适当的时候自动恢复。

**AWUM:**自动唤醒功能,CAN外设可以使用软件进入低功耗的睡眠模式,如果使能了这个自动唤醒功能,当CAN检测到总线活动的时候,会自动唤醒。

**NART:**报文自动重传功能,设置这个功能后, 当报文发送失败时会自动重传至成功为止。若不使用这个功能,无论发送结果如何,消息只发送一次。

**RFLM:**FIFO锁定模式,该功能用于锁定接收FIFO 。 锁定后,当接收FIFO溢出时,会丢弃下一个接收的报文。若不锁定,则下一个接收到的报文会覆盖原报文。

**TXFP:**报文发送优先级的判定方法,当CAN外设的发送邮箱中有多个待发送报文时, 本功能可以控制它是根据报文的ID优先级还是报文存进邮箱的顺序来发送。

**INRQ:**控制初始化请求。在 CAN 初始化的时候,先要设置该位为 1,然后进行初始化(尤其是 CAN_BTR 的设置,该寄存器必须在 CAN 正常工作之前设置),之后再设置该位为 0,让 CAN 进入正常工作模式。

位时序寄存器(CAN_BTR)及波特率

CAN 位时序寄存器用于设置分频、 Tbs1、 Tbs2 以及 Tsjw 等非常重要的参数,直接决定了CAN 的波特率。

该寄存器还可以设置 CAN 的测试模式, STM32 提供了三种测试模式:回环模式、静默模式和回环静默模式。

**正常模式:**正常模式下就是一个正常的CAN节点,可以向总线发送数据和接收数据。

**静默模式:**不能向总线发送显性位(逻辑0),只能发送隐性位(逻辑1)。由于它只可发送的隐性位不会强制影响总线的状态,所以把它称为静默模式。输入端可以从总线接收内容。该模式用于分析总线上的流量监控,但又不会因为发送显性位而影响总线

**回环模式:**输出端的所有内容都直接传输到自己的输入端,输出端的内容同时也会被传输到总线上,即也可使用总线监测它的发送内容。输入端只接收自己发送端的内容,不接收来自总线上的内容。使用回环模式可以进行自检。

**回环静默模式:**以上两种模式的结合,自己的输出端的所有内容都直接传输到自己的输入端,并且不会向总线发送显性位影响总线,不能通过总线监测它的发送内容。输入端只接收自己发送端的内容,不接收来自总线上的内容。这种方式可以在"热自检"时使用,即自我检查的时候,不会干扰总线。

STM32中CAN的位时序

STM32的CAN外设位时序中只包含3段,分别是同步段SYNC_SEG、位段BS1及位段BS2,采样点位于BS1及BS2段的交界处。SYNC_SEG段固定长度为1Tq,而BS1及BS2段可以在位时序寄存器CAN_BTR设置它们的时间长度,可以在重新同步期间增长或缩短,该长度SJW也可在位时序寄存器中配置。

BS1段理解为是由前面介绍的CAN标准协议中PTS段与PBS1段合在一起的,而BS2段就相当于PBS2段。

STM32中 CAN的波特率

通过配置位时序寄存器CAN_BTR的TS1[3:0]及TS2[2:0]寄存器位设定BS1及BS2段的长度后,我们就可以确定每个CAN数据位的时间(配置波特率):

BS1段时间:TS1=Tq x (TS1[3:0] + 1)

BS2段时间:TS2= Tq x (TS2[2:0] + 1)

一个数据位的时间:T1bit =1Tq+TS1+TS2 =1+ (TS1[3:0] + 1)+ (TS2[2:0] + 1)= N Tq

单个时间片的长度Tq与CAN外设的所挂载的时钟总线及分频器配置有关,CAN1和CAN2外设都是挂载在APB1总线上的,而位时序寄存器CAN_BTR中的BRP[9:0]寄存器位可以设置CAN外设时钟的分频值 ,所以:Tq = (BRP[9:0]+1) x TPCLK,PCLK指APB1时钟,默认值为42MHz。

最终可以计算出CAN通讯的波特率:BaudRate = 1/N Tq

波特率配置为1Mbps示例:

|-----------|----------------------------------------------|
| 参数 | 说明 |
| SYNC_SE段 | 固定为1Tq |
| BS1段 | 设置为4Tq (实际写入TS1[3:0]的值为3) |
| BS2段 | 设置为2Tq (实际写入TS2[2:0]的值为1) |
| TPCLK | APB1按默认配置为F=42MHz,TPCLK=1/42M |
| CAN外设时钟分频 | 设置为6分频(实际写入BRP[9:0]的值为4) |
| 1Tq时间长度 | Tq = (BRP[9:0]+1) x TPCLK = 6 x 1/42M=1/7M |
| 1位的时间长度 | T1bit =1Tq+TS1+TS2 = 1+4+2 = 7Tq |
| 波特率 | BaudRate = 1/N Tq = 1/(1/7M x 7)=1Mbps |

CAN发送邮箱

上面框图中一共有3个发送邮箱,即最多可以缓存3个待发送的报文。

发送邮箱的寄存器:

|--------------------|--------------------------------|
| 寄存器名 | 功能 |
| 标识符寄存器CAN_TIxR | 存储待发送报文的ID、扩展ID、IDE位及RTR位 |
| 数据长度控制寄存器CAN_TDTxR | 存储待发送报文的DLC段 |
| 低位数据寄存器CAN_TDLxR | 存储待发送报文数据段的Data0-Data3这四个字节的内容 |
| 高位数据寄存器CAN_TDHxR | 存储待发送报文数据段的Data4-Data7这四个字节的内容 |

标识符寄存器CAN_TIxR:

数据长度控制寄存器CAN_TDTxR:

低位数据寄存器CAN_TDLxR:

高位数据寄存器CAN_TDHxR和低位结构一样。

CAN接收FIFO

上面框图中一共有2个接收FIFO,每个FIFO中有3个邮箱, 即最多可以缓存6个接收到的报文。

接收到报文时,FIFO的报文计数器会自增,而STM32内部读取FIFO数据之后,报文计数器会自减, 我们通过状态寄存器可获知报文计数器的值。

每个接收FIFO中包含有标识符寄存器CAN_RIxR、数据长度控制寄存器CAN_RDTxR及2个数据寄存器CAN_RDLxR、CAN_RDHxR。

|--------------------|-------------------------------|
| 寄存器名 | 功能 |
| 标识符寄存器CAN_RIxR | 存储收到报文的ID、扩展ID、IDE位及RTR位 |
| 数据长度控制寄存器CAN_RDTxR | 存储收到报文的DLC段 |
| 低位数据寄存器CAN_RDLxR | 存储收到报文数据段的Data0-Data3这四个字节的内容 |
| 高位数据寄存器CAN_RDHxR | 存储收到报文数据段的Data4-Data7这四个字节的内容 |

验收筛选器

上面框图中一共有28个筛选器组,每个筛选器组有2个寄存器, CAN1和CAN2共用的筛选器的。

CAN 协议中,消息的标识符与节点地址无关,但与消息内容有关。发送节点将报文广播给所有接收器时,接收节点会根据报文标识符的值来确定软件是否需要该消息。为了简化软件的工作,STM32的CAN外设接收报文前会先使用验收筛选器检查,只接收需要的报文到FIFO中。

筛选器工作的时候,可以调整筛选ID的长度过滤模式

根据筛选ID长度来分类有有以下两种:

  1. 检查 STDID[10:0]、 EXTID[17:0]、 IDE 和 RTR 位,一共31位。

  2. 检查STDID[10:0]、 RTR、 IDE 和 EXTID[17:15],一共16位。

通过配置筛选尺度寄存器CAN_FS1R的FSCx位可以设置筛选器工作在哪个尺度。

CAN 过滤器位宽寄存器(CAN_FS1R):

根据过滤的方法分为以下两种模式:

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

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

通过配置筛选模式寄存器CAN_FM1R的FBMx位可以设置筛选器工作在哪个模式。

CAN 过滤器模式寄存器(CAN_FM1R):

不同的尺度和不同的过滤方法可使筛选器工作:

|----------|-----------------------------------------------------------------------------------------------|
| 模式 | 说明 |
| 32位掩码模式 | CAN_FxR1存储ID,CAN_FxR2存储哪个位必须要与CAN_FxR1中的ID一致,2个寄存器表示1组掩码。 |
| 32位标识符模式 | CAN_FxR1和CAN_FxR2各存储1个ID,2个寄存器表示2个筛选的ID |
| 16位掩码模式 | CAN_FxR1高16位存储ID,低16位存储哪个位必须要与高16位的ID一致; CAN_FxR2高16位存储ID,低16位存储哪个位必须要与高16位的ID一致 2个寄存器表示2组掩码。 |
| 16位标识符模式 | CAN_FxR1和CAN_FxR2各存储2个ID,2个寄存器表示4个筛选的ID |

每组筛选器包含2个32位的寄存器,分别为CAN_FxR1和CAN_FxR2,它们用来存储要筛选的ID或掩码。

CAN 的过滤器组 i 的寄存器 x(CAN_FiRx):

例如下面的表格所示,在掩码模式时,第一个寄存器存储要筛选的ID,第二个寄存器存储掩码,掩码为1的部分表示该位必须与ID中的内容一致,筛选的结果为表中第三行的ID值,它是一组包含多个的ID值,其中x表示该位可以为1可以为0。

|-------|---|---|---|---|---|---|---|-----|
| ID | 1 | 0 | 1 | 1 | 1 | 0 | 1 | ... |
| 掩码 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | ... |
| 筛选的ID | 1 | 0 | 1 | x | x | 0 | x | ... |

工作在标识符模式时,2个寄存器存储的都是要筛选的ID,它只包含2个要筛选的ID值(32位模式时)。

如果使能了筛选器,且报文的ID与所有筛选器的配置都不匹配,CAN外设会丢弃该报文,不存入接收FIFO。

CAN2外设的结构,它与CAN1外设是一样的,他们共用筛选器且由于存储访问控制器由CAN1控制,所以要使用CAN2的时候必须要使能CAN1的时钟。

CAN通讯实验

整体框图:

硬件接口(本次实验使用野火指南者开发板/CAN收发器使用JTA1050):

代码源码自取

STM32F103_Project: stm32f103 相关的项目或者示例

注意:没有使用中断的接收FIFO是FIFO0, 使用中断接收FIFO是FIFO1。

主要代码解析

配置波特率为125k:

配置筛选器:

配置发送报文函数:

报文接收:

1.非中断接收:

2.中断接收:

代码运行演示

连接好设备:

该实验使用PCAN结合PCANVIEW上位机与STM32F103VET6进行实验,也可以将PCAN换成单片机(双击通讯实验)。

按下KEY按照指定ID发送一次报文,中断接收,主循环打印出来(非中断实验示例现象一致)。

复制代码
#include "stm32f10x.h"
#include "bsp_led.h"
#include "bsp_key.h"
#include "bsp_usart.h"
#include "bsp_can.h"

uint32_t TxID = 0x1314;
uint8_t TxLength = 8;
uint8_t TxData[8] = {0, 1, 2, 3, 4, 5, 6, 7};

CanRxMsg RxMessage;
__IO uint8_t ReceiveFlag = 0;

int main(void)
{	
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  LED_GPIO_Config();	
  Key_GPIO_Config();
  USART_Config();
  CAN_Config();

	printf("This is CAN Loop Experiment!\r\n");
  
  while(1)
	{	
    if (Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_PIN) == KEY_ON  )
		{
      LED_BLUE;
      for (uint8_t i = 0; i < TxLength; i++)
      {
        TxData[i] ++;
      }
      CAN_Transmit_Config(TxID, TxLength, TxData);
    }
    
     if (ReceiveFlag)
     {
        ReceiveFlag = 0;
        
        printf("\r\n < -- RxID: 0x%x \t RxLength: %d -- >\r\n", RxMessage.ExtId, RxMessage.DLC);
        for (uint8_t i = 0; i < RxMessage.DLC; i ++)
        {
          printf("RxData[%d]: %d\t", i, RxMessage.Data[i]);
        }
        printf("\r\n");
     }
	}	
}
/*********************************************END OF FILE**********************/
回环模式:

实验现象:

注:如果将TxID改成不是0x1314的ID且配置筛选器只能接收0x1314的报文,则不会打印。需要设置为别的ID,可以将筛选器配置为0x0000,或者筛选你设定的ID。

正常模式:

双机通讯实验即将程序烧入到两个开发板,结果和回环测试一样。

相关推荐
玻璃瓶和纸飞机1 小时前
Java常用类库大全(学习笔记)持续更新中
java·笔记·学习
菜一头包1 小时前
QT5中的QGraphics图形视图框架学习笔记(Item、Scene和View)
笔记·qt·学习
rufeike6 小时前
Redis学习笔记
redis·笔记·学习
晨曦backend10 小时前
Vim 替换命令完整学习笔记
笔记·学习·vim
蒙奇D索大11 小时前
【11408学习记录】[特殊字符] 速解命题核心!考研数学线性代数:4类行列式满分技巧(含秒杀公式)
笔记·学习·线性代数·考研·改行学it
江池俊12 小时前
通过Docker和内网穿透技术在Linux上搭建远程Logseq笔记系统
linux·笔记·docker
moxiaoran575312 小时前
uni-app学习笔记三十六--分段式选项卡组件的使用
笔记·学习·uni-app
笑鸿的学习笔记12 小时前
Windows笔记之Win11让非焦点窗口程序也能获得流畅性能的方法
windows·笔记
moxiaoran575314 小时前
uni-app项目实战笔记1--创建项目和实现首页轮播图功能
笔记·uni-app
fictionist15 小时前
动态 Web 开发技术入门篇
java·服务器·开发语言·笔记·学习·mysql·spring