学习CAN通信协议(下)--实例讲解

谈思实验室 2023-10-15 18:48

点击上方蓝字谈思实验室

获取更多汽车网络安全资讯


二. STM32 CAN 控制器介绍

STM32 的芯片中具有 bxCAN 控制器 (Basic Extended CAN),它支持 CAN 协议 2.0A 和 2.0B 标准。
该 CAN 控制器支持最高的通讯速率为 1Mb/s;可以自动地接收和发送 CAN 报文,支持使用标准ID 和扩展 ID 的报文;外设中具有 3 个发送邮箱,发送报文的优先级可以使用软件控制,还可以记录发送的时间;具有 2 个 3 级深度的接收 FIFO,可使用过滤功能只接收或不接收某些 ID 号的报文;可配置成自动重发;不支持使用 DMA 进行数据收发。框架示意图如下:
STM32 的有两组 CAN 控制器,其中 CAN1 是主设备,框图中的“存储访问控制器”是由 CAN1控制的,CAN2 无法直接访问存储区域,所以使用 CAN2 的时候必须使能 CAN1 外设的时钟。框图中主要包含 CAN 控制内核、发送邮箱、接收 FIFO 以及验收筛选器,下面对框图中的各个部分进行介绍。

2.1 CAN 控制内核

框图中标号处的 CAN 控制内核包含了各种控制寄存器及状态寄存器,我们主要讲解其中的主控制寄存器 CAN_MCR 及位时序寄存器 CAN_BTR。

2.1.1 主控制寄存器 CAN_MCR

主控制寄存器 CAN_MCR 负责管理 CAN 的工作模式,它使用以下寄存器位实现控制。
(1) DBF 调试冻结功能

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

(2) TTCM 时间触发模式

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

(3) ABOM 自动离线管理

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

(4) AWUM 自动唤醒

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

(5) NART 自动重传

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

(6) RFLM 锁定模式

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

(7) TXFP 报文发送优先级的判定方法

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

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

CAN 外设中的位时序寄存器 CAN_BTR 用于配置测试模式、波特率以及各种位内的段参数。
2.1.2.1 模式

位31 SILM:静默模式(调试)(Silent mode (debug))

0:正常工作

1:静默模式

位30 LBKM:环回模式(调试)(Loop back mode (debug))

0:禁止环回模式
1:使能环回模式
为方便调试,STM32 的 CAN 提供了测试模式,配置位时序寄存器 CAN_BTR 的 SILM 及 LBKM寄存器位可以控制使用正常模式、静默模式、回环模式及静默回环模式,见图。

各个工作模式介绍如下:

• 正常模式

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

• 静默模式

静默模式下,它自己的输出端的逻辑 0 数据会直接传输到它自己的输入端,逻辑 1 可以被发送到总线,所以它不能向总线发送显性位 (逻辑 0),只能发送隐性位 (逻辑 1)。输入端可以从总线接收内容。由于它只可发送的隐性位不会强制影响总线的状态,所以把它称为静默模式。这种模式一般用于监测,它可以用于分析总线上的流量,但又不会因为发送显性位而影响总线。

• 回环模式

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

• 回环静默模式

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

以上说的各个模式,是不需要修改硬件接线的,例如,当输出直接连输入时,它是在 STM32 芯片内部连接的,传输路径不经过 STM32 的 CAN_Tx/Rx 引脚,更不经过外部连接的 CAN 收发器,只有输出数据到总线或从总线接收的情况下才会经过 CAN_Tx/Rx 引脚和收发器

2.1.2.2 位时序及波特率
STM32 外设定义的位时序与我们前面解释的 CAN 标准时序有一点区别,见图
STM32 的 CAN 外设位时序中只包含 3 段,分别是同步段 SYNC_SEG、位段 BS1 及位段 BS2,采样点位于 BS1 及 BS2 段的交界处。其中 SYNC_SEG 段固定长度为 1Tq,而 BS1 及 BS2 段可以

在位时序寄存器 CAN_BTR 设置它们的时间长度,它们可以在重新同步期间增长或缩短,该长度SJW 也可在位时序寄存器中配置。

理解 STM32 的 CAN 外设的位时序时,可以把它的 BS1 段理解为是由前面介绍的 CAN 标准协议中 PTS 段与 PBS1 段合在一起的,而 BS2 段就相当于 PBS2 段。

了解位时序后,我们就可以配置波特率了。通过配置位时序寄存器 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波特率=Fpclk1/((CAN_BS1+CAN_BS2+1)*CAN_Prescaler)

其中clk为42M!

推荐一个CAN波特率计算器

2.2 CAN 发送邮箱

回到图 中的 CAN 外设框图,在标号处的是 CAN 外设的发送邮箱,它一共有 3 个发送邮箱,即最多可以缓存 3 个待发送的报文。
每个发送邮箱中包含有标识符寄存器 CAN_TIxR、数据长度控制寄存器 CAN_TDTxR 及 2 个数据寄存器 CAN_TDLxR、CAN_TDHxR,它们的功能见表
当我们要使用 CAN 外设发送报文时,把报文的各个段分解,按位置写入到这些寄存器中,并对标识符寄存器 CAN_TIxR 中的发送请求寄存器位 TMIDxR_TXRQ 置 1,即可把数据发送出去。
其中标识符寄存器 CAN_TIxR 中的 STDID 寄存器位比较特别。我们知道 CAN 的标准标识符的总位数为 11 位,而扩展标识符的总位数为 29 位的。当报文使用扩展标识符的时候,标识符寄存器 CAN_TIxR 中的 STDID[10:0] 等效于 EXTID[18:28] 位,它与 EXTID[17:0] 共同组成完整的 29位扩展标识符。

2.3 CAN 接收 FIFO

图 中的 CAN 外设框图,在标号处的是 CAN 外设的接收 FIFO,它一共有 2 个接收 FIFO,每个 FIFO 中有 3 个邮箱,即最多可以缓存 6 个接收到的报文。
当接收到报文时,FIFO 的报文计数器会自增,而 STM32 内部读取 FIFO 数据之后,报文计数器会自减,我们通过状态寄存器可获知报文计数器的值,而通过前面主控制寄存器的 RFLM 位,可设置锁定模式,锁定模式下 FIFO溢出时会丢弃新报文,非锁定模式下 FIFO 溢出时新报文会覆盖旧报文。

跟发送邮箱类似,每个接收 FIFO 中包含有标识符寄存器 CAN_RIxR、数据长度控制寄存器CAN_RDTxR 及 2 个数据寄存器 CAN_RDLxR、CAN_RDHxR,它们的功能见表。

通过中断或状态寄存器知道接收 FIFO 有数据后,我们再读取这些寄存器的值即可把接收到的报文加载到 STM32 的内存中

2.4 验收筛选器

图 中的 CAN 外设框图,在标号处的是 CAN 外设的验收筛选器,一共有 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 位可以设置筛选器工作在哪个尺度。而根据过滤的方法分为以下两种模式:

(1) 标识符列表模式,它把要接收报文的 ID 列成一个表,要求报文 ID 与列表中的某一个标识符完全相同才可以接收,可以理解为白名单管理。

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

通过配置筛选模式寄存器 CAN_FM1R 的 FBMx 位可以设置筛选器工作在哪个模式。不同的尺度和不同的过滤方法可使筛选器工作在图 的 4 种状态。

每组筛选器包含 2 个 32 位的寄存器,分别为 CAN_FxR1 和 CAN_FxR2,它们用来存储要筛选的ID 或掩码,各个寄存器位代表的意义与图中两个寄存器下面“映射”的一栏一致,各个模式的说明见表。

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

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

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

2.5 整体控制逻辑

回到图 结构框图,图中的标号处表示的是 CAN2 外设的结构,它与 CAN1 外设是一样的,他们共用筛选器且由于存储访问控制器由 CAN1 控制,所以要使用 CAN2 的时候必须要使能CAN1 的时钟。其中 STM32F103 系列芯片不具有 CAN2 控制器。

2.6 STM32 HAL库代码逻辑

2.6.1 初始化

注意:网络上基本上用的很久的HAL库,我们采用很新的1.25.2,最新的库还是差异挺大的!

从 STM32 的 CAN 外设我们了解到它的功能非常多,控制涉及的寄存器也非常丰富,而使用STM32 HAL 库提供的各种结构体及库函数可以简化这些控制过程。跟其它外设一样,STM32

HAL 库提供了 CAN 初始化结构体及初始化函数来控制 CAN 的工作方式,提供了收发报文使用的结构体及收发函数,还有配置控制筛选器模式及 ID 的结构体。这些内容都定义在库文件“STM32F4xx_hal_can.h”及“STM32F4xx_hal_can.c”中,编程时我们可以结合这两个文件内的注释使用或参考库帮助文档。首先我们来学习初始化结构体的内容,见代码清单 1。代码清单 CAN 初始化结构

typedef struct
{

  uint32_t Prescaler;  /* 配置 CAN 外设的时钟分频,可设置为 1-1024*/
  uint32_t Mode;       /* 配置 CAN 的工作模式,回环或正常模式 */
  uint32_t SyncJumpWidth;  /* 配置 SJW 极限值 */
  uint32_t TimeSeg1;   /* 配置 BS1 段长度 */
  uint32_t TimeSeg2;   /* 配置 BS2 段长度 */
  FunctionalState TimeTriggeredMode;   /* 是否使能 TTCM 时间触发功能 */
  FunctionalState AutoBusOff;     /* 是否使能 ABOM 自动离线管理功能 */
  FunctionalState AutoWakeUp;   /* 是否使能 AWUM 自动唤醒功能 */
  FunctionalState AutoRetransmission;  /* 是否使能 NART 自动重传功能 */
  FunctionalState ReceiveFifoLocked;   /* 是否使能 RFLM 锁定 FIFO 功能 */
  FunctionalState TransmitFifoPriority;/* 配置 TXFP 报文优先级的判定方法 */
} CAN_InitTypeDef;

体这些结构体成员说明如下,其中括号内的文字是对应参数在 STM32 HAL 库中定义的宏

(1) Prescaler

本成员设置 CAN 外设的时钟分频,它可控制时间片 Tq 的时间长度,这里设置的值最终会减 1 后再写入 BRP 寄存器位,即前面介绍的 Tq 计算公式:

Tq = (BRP[9:0]+1) x TPCLK

等效于:Tq = CAN_Prescaler x TPCLK

(2) Mode

本成员设置 CAN 的工作模式,可设置为正常模式 (CAN_MODE_NORMAL)、回环模式 (CAN_MODE_LOOPBACK)、静默模式 (CAN_MODE_SILENT) 以及回环静默模式(CAN_MODE_SILENT_LOOPBACK)。

(3) SyncJumpWidth

本成员可以配置 SJW 的极限长度,即 CAN 重新同步时单次可增加或缩短的最大长度,它可以被配置为 1-4Tq(CAN_SJW_1/2/3/4tq)。

(4) TimeSeg1

本成员用于设置 CAN 位时序中的 BS1 段的长度,它可以被配置为 1-16 个 Tq 长度(CAN_BS1_1/2/3…16tq)。

(5) TimeSeg2

本成员用于设置 CAN 位时序中的 BS2 段的长度,它可以被配置为 1-8 个 Tq 长度(CAN_BS2_1/2/3…8tq)。SYNC_SEG、 BS1 段及 BS2 段的长度加起来即一个数据位的长度,即前面介绍的原来

计算公式:T1bit =1Tq+TS1+TS2=1+ (TS1[3:0] + 1)+ (TS2[2:0] + 1)

等效于:T1bit= 1Tq+CAN_BS1+CAN_BS2

(6) TimeTriggeredMode

本成员用于设置是否使用时间触发功能 (ENABLE/DISABLE),时间触发功能在某些CAN 标准中会使用到。

(7) AutoBusOff

本成员用于设置是否使用自动离线管理 (ENABLE/DISABLE),使用自动离线管理可以在节点出错离线后适时自动恢复,不需要软件干预。

(8) AutoWakeUp

本成员用于设置是否使用自动唤醒功能 (ENABLE/DISABLE),使能自动唤醒功能后它会在监测到总线活动后自动唤醒。

(9) 此处与AutoBusOff重复(笔误)

本成员用于设置是否使用自动离线管理功能 (ENABLE/DISABLE),使用自动离线管理可以在出错时离线后适时自动恢复,不需要软件干预。

(10) AutoRetransmission

本成员用于设置是否使用自动重传功能 (ENABLE/DISABLE),使用自动重传功能时,会一直发送报文直到成功为止。

(11) ReceiveFifoLocked

本成员用于设置是否使用锁定接收 FIFO(ENABLE/DISABLE),锁定接收 FIFO 后,若FIFO 溢出时会丢弃新数据,否则在 FIFO 溢出时以新数据覆盖旧数据。

(12) TransmitFifoPriority

本成员用于设置发送报文的优先级判定方法 (ENABLE/DISABLE),使能时,以报文存入发送邮箱的先后顺序来发送,否则按照报文 ID 的优先级来发送。配置完这些结构体成员后,我们调用库函数 HAL_CAN_Init 即可把这些参数写入到 CAN 控制寄存器中,实现 CAN 的初始化

2.6.2 CAN 发送及接收结构体

在发送或接收报文时,需要往发送邮箱中写入报文信息或从接收 FIFO 中读取报文信息,利用STM32HAL 库的发送及接收结构体可以方便地完成这样的工作,它们的定义见代码清单 。代码清单 39‑2 CAN 发送及接收结构体

typedef struct
{

  uint32_t StdId;    /* 存储报文的标准标识符 11 位,0-0x7FF. */
  uint32_t ExtId;    /* 存储报文的扩展标识符 29 位,0-0x1FFFFFFF. */
  uint32_t IDE;     /* 存储 IDE 扩展标志 */
  uint32_t RTR;    /* 存储 RTR 远程帧标志 */
  uint32_t DLC;     /* 存储报文数据段的长度,0-8 */
  FunctionalState TransmitGlobalTime; 
} CAN_TxHeaderTypeDef;

typedef struct
{

  uint32_t StdId;    /* 存储报文的标准标识符 11 位,0-0x7FF. */
  uint32_t ExtId;    /* 存储报文的扩展标识符 29 位,0-0x1FFFFFFF. */
  uint32_t IDE;     /* 存储 IDE 扩展标志 */
  uint32_t RTR;      /* 存储 RTR 远程帧标志 */
  uint32_t DLC;     /* 存储报文数据段的长度,0-8 */
  uint32_t Timestamp; 
  uint32_t FilterMatchIndex; 
} CAN_RxHeaderTypeDef;

这些结构体成员, 说明如下:

(1) StdId

本成员存储的是报文的 11 位标准标识符,范围是 0-0x7FF。

(2) ExtId

本成员存储的是报文的 29 位扩展标识符,范围是 0-0x1FFFFFFF。ExtId 与 StdId 这两个成员根据下面的 IDE 位配置,只有一个是有效的。

(3) IDE

本成员存储的是扩展标志 IDE 位,当它的值为宏 CAN_ID_STD 时表示本报文是标准帧,使用 StdId 成员存储报文 ID;当它的值为宏 CAN_ID_EXT 时表示本报文是扩展帧,使用 ExtId 成员存储报文 ID。

(4) RTR

本成员存储的是报文类型标志 RTR 位,当它的值为宏 CAN_RTR_Data 时表示本报文是数据帧;当它的值为宏 CAN_RTR_Remote 时表示本报文是遥控帧,由于遥控帧没有数据段,所以当报文是遥控帧时,数据是无效的

(5) DLC

本成员存储的是数据帧数据段的长度,它的值的范围是 0-8,当报文是遥控帧时 DLC值为 0。

2.6.3 CAN 筛选器结构体

CAN 的筛选器有多种工作模式,利用筛选器结构体可方便配置,它的定义见代码清单 。代码清单CAN 筛选器结构体

typedef struct
{

  uint32_t FilterIdHigh;         /*CAN_FxR1 寄存器的高 16 位 */
  uint32_t FilterIdLow;         /*CAN_FxR1 寄存器的低 16 位 */
  uint32_t FilterMaskIdHigh;   /*CAN_FxR2 寄存器的高 16 位 */
  uint32_t FilterMaskIdLow;    /*CAN_FxR2 寄存器的低 16 位 */
  uint32_t FilterFIFOAssignment;  /* 设置经过筛选后数据存储到哪个接收 FIFO */
  uint32_t FilterBank;            /* 筛选器编号,范围 0-27,数据手册上说0-27是CAN1/CAN2共享,但是实测发现并不是这样,CAN1是0-13,CAN2是14-27 */
  uint32_t FilterMode;            /* 筛选器模式 */
  uint32_t FilterScale;           /* 设置筛选器的尺度 */
  uint32_t FilterActivation;      /* 是否使能本筛选器 */
  uint32_t SlaveStartFilterBank;  
} CAN_FilterTypeDef;

这些结构体成员都是“41.2.14 验收筛选器”小节介绍的内容,可对比阅读,各个结构体成员的介绍如下:

(1) FilterIdHigh

FilterIdHigh 成员用于存储要筛选的 ID,若筛选器工作在 32 位模式,它存储的是所筛选 ID 的高 16 位;若筛选器工作在 16 位模式,它存储的就是一个完整的要筛选的 ID。

(2) FilterIdLow

类似地,FilterIdLow 成员也是用于存储要筛选的 ID,若筛选器工作在 32 位模式,它存储的是所筛选 ID 的低 16 位;若筛选器工作在 16 位模式,它存储的就是一个完整的要筛选的 ID。

(3) FilterMaskIdHigh

FilterMaskIdHigh 存储的内容分两种情况,当筛选器工作在标识符列表模式时,它的功能与 FilterIdHigh 相同,都是存储要筛选的 ID;而当筛选器工作在掩码模式时,它存储的是 FilterIdHigh 成员对应的掩码,与 FilterIdLow 组成一组筛选器。

(4) FilterMaskIdLow

类似地, FilterMaskIdLow 存储的内容也分两种情况,当筛选器工作在标识符列表模式时,它的功能与 FilterIdLow 相同,都是存储要筛选的 ID;而当筛选器工作在掩码模式时,它存储的是 FilterIdLow 成员对应的掩码,与 FilterIdLow 组成一组筛选器。上面四个结构体的存储的内容很容易让人糊涂,请结合前面的图 39_0_15 和下面的表 39‑7 理解,如果还搞不清楚,再结合库函数 FilterInit 的源码来分析。

表不同模式下各结构体成员的内容

对这些结构体成员赋值的时候,还要注意寄存器位的映射,即注意哪部分代表 STID,哪部分代表 EXID 以及 IDE、RTR 位。

(5) FilterFIFOAssignment

本成员用于设置当报文通过筛选器的匹配后,该报文会被存储到哪一个接收 FIFO,它的可选值为 FIFO0 或 FIFO1(宏 CAN_FILTER_FIFO0/1)。

(6) FilterBank

本成员用于设置筛选器的编号,即本过滤器结构体配置的是哪一组筛选器,CAN 一共有 28 个筛选器,所以它的可输入参数范围为 0-27。

(7) FilterMode

本 成 员 用 于 设 置 筛 选 器 的 工 作 模 式, 可 以 设 置 为 列 表 模 式 (宏CAN_FILTERMODE_IDLIST) 及掩码模式 (宏 CAN_FILTERMODE_IDMASK)。

(8) FilterScale

本成员用于设置筛选器的尺度,可以设置为 32 位长 (宏 CAN_FILTERSCALE_32BIT)及 16 位长 (宏 CAN_FILTERSCALE_16BIT)。

(9) FilterActivation

本成员用于设置是否激活这个筛选器 (宏 ENABLE/DISABLE)。

三. CAN Cubemx配置

我们通过问题来熟悉下cubemx配置,你熟悉了这些问题基本就知道怎么配置了!

问题:Parameter Settings分别都是设置什么的?答案:如图
问题:怎么配置波特率呢?

答案:用我上面贴的工具(CAN波特率计算 f103AHP1_36M  f407AHP1_42M  采样点软件有说明.rar)直接配置,举两个个例子

例子1:我们要配置成500KHz,那么我们这样配置
我们用采集点为80%,所以BS1为4tq,BS2为2tq,分频系数为12,代进公式Fpclk1/((CAN_BS1+CAN_BS2+1)*CAN_Prescaler)=42M/(4+2+1)/12=500kHz
例子2:我们要配置成1M Hz,那么我们这样配置
我们用采集点为75%,所以BS1为3tq,BS2为2tq,分频系数为7,代进公式Fpclk1/((CAN_BS1+CAN_BS2+1)*CAN_Prescaler)=42M/(3+2+1)/7=1MHz
问题:Basic Parameter分别是啥意思呢?
Timer Triggered Communication Mode:否使用时间触发功能 (ENABLE/DISABLE),时间触发功能在某些CAN 标准中会使用到。

Automatic Bus-Off Management:用于设置是否使用自动离线管理功能 (ENABLE/DISABLE),使用自动离线管理可以在出错时离线后适时自动恢复,不需要软件干预。

Automatic Wake-Up Mode:用于设置是否使用自动唤醒功能 (ENABLE/DISABLE),使能自动唤醒功能后它会在监测到总线活动后自动唤醒。

Automatic Retransmission:用于设置是否使用自动重传功能 (ENABLE/DISABLE),使用自动重传功能时,会一直发送报文直到成功为止。

Receive Fifo Locked Mode:用于设置是否使用锁定接收 FIFO(ENABLE/DISABLE),锁定接收 FIFO 后,若FIFO 溢出时会丢弃新数据,否则在 FIFO 溢出时以新数据覆盖旧数据。

Transmit Fifo Priority:用于设置发送报文的优先级判定方法 (ENABLE/DISABLE),使能时,以报文存入发送邮箱的先后顺序来发送,否则按照报文 ID 的优先级来发送。配置完这些结构体成员后,我们调用库函数 HAL_CAN_Init 即可把这些参数写入到 CAN 控制寄存器中,实现 CAN 的初始化

问题:为啥CAN分为RX0,RX1中断呢?

答案:STM32有2个3级深度的接收缓冲区:FIFO0和FIFO1,每个FIFO都可以存放3个完整的报文,它们完全由硬件来管理。如果是来自FIFO0的接收中断,则用CAN1_RX0_IRQn中断来处理。如果是来自FIFO1的接收中断,则用CAN1_RX1_IRQn中断来处理,如图:

问题:CAN SCE中断时什么?

答案:status chanege error,错误和状态变化中断!

四.CAN分析工具的使用

下面我们会用到CAN分析工具,还是比较好用的,此部分使用作为自己使用

https://www.zhcxgd.com/h-col-112.html

五. 实验

1.Normal模式测试500K 波特率(定时发送,轮询接收)

1.1 CubeMx配置

1.2 设置Filter过滤,我们只使能FIFO0,并且不过滤任何消息

uint8_t bsp_can1_filter_config(void)
{
    CAN_FilterTypeDef filter = {0};
    filter.FilterActivation = ENABLE;
    filter.FilterMode = CAN_FILTERMODE_IDMASK;
    filter.FilterScale = CAN_FILTERSCALE_32BIT;
    filter.FilterBank = 0;
    filter.FilterFIFOAssignment = CAN_FILTER_FIFO0;
    filter.FilterIdLow = 0;
    filter.FilterIdHigh = 0;
    filter.FilterMaskIdLow = 0;
    filter.FilterMaskIdHigh = 0;
    HAL_CAN_ConfigFilter(&hcan1, &filter);
    return BSP_CAN_OK;
}

1.3 开启CAN(注意,默认Cubemx生成的代码并没有can start)

HAL_CAN_Start(&hcan1);

1.4 编写发送函数

我们开出了几个参数,id_type是扩展帧还是标准帧,basic_id标准帧ID(在标准帧中有效),ex_id扩展帧ID(在扩展帧中有效),data要发送的数据,data_len要发送的数据长度

uint8_t bsp_can1_send_msg(uint32_t id_type,uint32_t basic_id,uint32_t ex_id,uint8_t *data,uint32_t data_len)
{
    uint8_t index = 0;
    uint32_t *msg_box;
 uint8_t send_buf[8] = {0};
    CAN_TxHeaderTypeDef send_msg_hdr;
    send_msg_hdr.StdId = basic_id;
    send_msg_hdr.ExtId = ex_id;
    send_msg_hdr.IDE = id_type;
    send_msg_hdr.RTR = CAN_RTR_DATA;
    send_msg_hdr.DLC = data_len;
 send_msg_hdr.TransmitGlobalTime = DISABLE;
 for(index = 0; index < data_len; index++)
          send_buf[index] = data[index];
 
    HAL_CAN_AddTxMessage(&hcan1,&send_msg_hdr,send_buf,msg_box);
    return BSP_CAN_OK;
}

我们在main函数中1s发送一帧,标准帧跟扩展帧交叉调用,代码如下:

send_data[0]++;
send_data[1]++;
send_data[2]++;
send_data[3]++;
send_data[4]++;
send_data[5]++;
send_data[6]++;
send_data[7]++;
if(id_type_std == 1)
{
    bsp_can1_send_msg(CAN_ID_STD,1,2,send_data,8);
    id_type_std = 0;
}
else
{
    bsp_can1_send_msg(CAN_ID_EXT,1,2,send_data,8);
    id_type_std = 1;
}
HAL_Delay(1000);

我们通过CAN协议分析仪来抓下结果

1.5 编写轮询接收函数

uint8_t bsp_can1_polling_recv_msg(uint32_t *basic_id,uint32_t *ex_id,uint8_t *data,uint32_t *data_len)
{
 uint8_t index = 0;
 uint8_t recv_data[8];
    CAN_RxHeaderTypeDef header;
 
    while (HAL_CAN_GetRxFifoFillLevel(&hcan1, CAN_RX_FIFO0) != 0)
    {
        if (__HAL_CAN_GET_FLAG(&hcan1, CAN_FLAG_FOV0) != RESET)
            printf("[CAN] FIFO0 overrun!\n");

        HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &header, recv_data);
        if(header.IDE == CAN_ID_STD)
        {
            printf("StdId ID:%d\n",header.StdId);
        }
        else
        {
            printf("ExtId ID:%d\n",header.ExtId);
        }
        printf("CAN IDE:0x%x\n",header.IDE);
        printf("CAN RTR:0x%x\n",header.RTR);
        printf("CAN DLC:0x%x\n",header.DLC);
        printf("RECV DATA:");
        for(index = 0; index < header.DLC; index++)
        {
            printf("0x%x ",recv_data[index]);
        }
        printf("\n");
    }
}
实验一总结:

1.没用调用HAL_CAN_Start(&hcan1);使能CAN

2.没有编写Filter函数,我开始自认为不设置就默认不过滤,现在看来是我想多了,其实想想也合理,你如果不过滤分配FIFO,STM32怎么决定把收到的放到哪个FIFO中

待提升:

1.目前只用到FIFO0,待把FIFO1使用起来2.Normal模式测试500K 波特率(定时发送,中断接收)

2.1 CubeMx配置

步骤2,3,4跟polling完全一致,我们来直接说下中断怎么用(主要是使能notifity就行了)

static void MX_CAN1_Init(void)
{
  /* USER CODE BEGIN CAN1_Init 0 */
  /* USER CODE END CAN1_Init 0 */
  /* USER CODE BEGIN CAN1_Init 1 */
  /* USER CODE END CAN1_Init 1 */
  hcan1.Instance = CAN1;
  hcan1.Init.Prescaler = 12;
  hcan1.Init.Mode = CAN_MODE_NORMAL;
  hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan1.Init.TimeSeg1 = CAN_BS1_4TQ;
  hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;
  hcan1.Init.TimeTriggeredMode = DISABLE;
  hcan1.Init.AutoBusOff = ENABLE;
  hcan1.Init.AutoWakeUp = ENABLE;
  hcan1.Init.AutoRetransmission = DISABLE;
  hcan1.Init.ReceiveFifoLocked = DISABLE;
  hcan1.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN CAN1_Init 2 */
  bsp_can1_filter_config();
 HAL_CAN_Start(&hcan1);
 HAL_CAN_ActivateNotification(&hcan1,CAN_IT_RX_FIFO0_MSG_PENDING);
  /* USER CODE END CAN1_Init 2 */
}

下面我们来编写下中断函数

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
 uint8_t index = 0;
 uint8_t recv_data[8];
      CAN_RxHeaderTypeDef header;
 
 HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &header, recv_data);
 if(header.IDE == CAN_ID_STD)
 {
          printf("StdId ID:%d\n",header.StdId);
 }
 else
 {
          printf("ExtId ID:%d\n",header.ExtId);
 }
 printf("CAN IDE:0x%x\n",header.IDE);
 printf("CAN RTR:0x%x\n",header.RTR);
 printf("CAN DLC:0x%x\n",header.DLC);
 printf("RECV DATA:");
 for(index = 0; index < header.DLC; index++)
 {
          printf("0x%x ",recv_data[index]);
 }
 printf("\n");
}

参考内容:

1.[野火EmbedFire]《STM32 HAL库开发实战指南——基于野火挑战者开发板》.pdf
2.STM32F4参考手册.pdf
3.CAN入门书.pdf

原文:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252






码上报名

谈思实验室AutoSec智能汽车安全攻防实训课程,10月,上海

更多文章

智能网联汽车信息安全综述

华为蔡建永:智能网联汽车的数字安全和功能安全挑战与思考

汽车数据合规要点

车载以太网技术发展与测试方法

车载以太网防火墙设计

SOA:整车架构下一代的升级方向

软件如何「吞噬」汽车?

汽车信息安全 TARA 分析方法实例简介

汽车FOTA信息安全规范及方法研究

联合国WP.29车辆网络安全法规正式发布

滴滴下架,我却看到数据安全的曙光

从特斯拉被约谈到车辆远程升级(OTA)技术的合规

如何通过CAN破解汽

会员权益: (点击可进入)谈思实验室VIP会员



谈思实验室 深入专注智能汽车网络安全与数据安全技术,专属汽车网络安全圈的头部学习交流平台和社区。平台定期会通过线上线下等形式进行一手干货内容输出,并依托丰富产业及专家资源,深化上下游供需对接,逐步壮大我国汽车安全文化及产业生态圈。
评论 (0)
  • 什么是车用高效能运算(Automotive HPC)?高温条件为何是潜在威胁?作为电动车内的关键核心组件,由于Automotive HPC(CPU)具备高频高效能运算电子组件、高速传输接口以及复杂运算处理、资源分配等诸多特性,再加上各种车辆的复杂应用情境等等条件,不难发见Automotive HPC对整个平台讯号传输实时处理、系统稳定度、耐久度、兼容性与安全性将造成多大的考验。而在各种汽车使用者情境之中,「高温条件」就是你我在日常生活中必然会面临到的一种潜在威胁。不论是长时间将车辆停放在室外的高
    百佳泰测试实验室 2025-04-10 15:09 77浏览
  • 政策驱动,AVAS成新能源车安全刚需随着全球碳中和目标的推进,新能源汽车产业迎来爆发式增长。据统计,2023年中国新能源汽车渗透率已突破35%,而欧盟法规明确要求2024年后新能效车型必须配备低速提示音系统(AVAS)。在此背景下,低速报警器作为车辆主动安全的核心组件,其技术性能直接关乎行人安全与法规合规性。基于WT2003H芯片开发的AVAS解决方案,以高可靠性、强定制化能力及智能场景适配特性,正成为行业技术升级的新标杆。WT2003H方案技术亮点解析全场景音效精准触发方案通过多传感器融合技术
    广州唯创电子 2025-04-10 08:53 201浏览
  • 文/Leon编辑/侯煜‍关税大战一触即发,当地时间4月9日起,美国开始对中国进口商品征收总计104%的关税。对此,中国外交部回应道:中方绝不接受美方极限施压霸道霸凌,将继续采取坚决有力措施,维护自身正当权益。同时,中国对原产于美国的进口商品加征关税税率,由34%提高至84%。随后,美国总统特朗普在社交媒体宣布,对中国关税立刻提高至125%,并暂缓其他75个国家对等关税90天,在此期间适用于10%的税率。特朗普政府挑起关税大战的目的,实际上是寻求制造业回流至美国。据悉,特朗普政府此次宣布对全球18
    华尔街科技眼 2025-04-10 16:39 107浏览
  • ‌亥姆霍兹线圈‌是由两组相同的线圈组成,线圈之间的距离等于它们的半径。当电流同时流过这两个线圈时,会在它们中间形成一个几乎均匀的磁场。这种设计克服了普通线圈磁场不均匀的缺陷,能够在中心区域形成稳定、均匀的磁场‌。‌亥姆霍兹线圈的应用领域‌包括材料、电子、生物、医疗、航空航天、化学、应用物理等各个学科。由于其操作简便且能够提供极微弱的磁场直至数百高斯的磁场,亥姆霍兹线圈在各研究所、高等院校及企业中被广泛用于物质磁性或检测实验。‌亥姆霍兹线圈可以根据不同的标准进行分类‌:‌按磁场方向分类‌:‌一维亥
    锦正茂科技 2025-04-09 17:20 148浏览
  • 技术原理:非扫描式全局像的革新Flash激光雷达是一种纯固态激光雷达技术,其核心原理是通过面阵激光瞬时覆盖探测区域,配合高灵敏度传感器实现全局三维成像。其工作流程可分解为以下关键环节:1. 激光发射:采用二维点阵光源(如VCSEL垂直腔面发射激光器),通过光扩散器在单次脉冲中发射覆盖整个视场的面阵激光,视场角通常可达120°×75°,部分激光雷达产品可以做到120°×90°的超大视场角。不同于传统机械扫描或MEMS微振镜方案,Flash方案无需任何移动部件,直接通过电信号控制激光发射模式。2.
    robolab 2025-04-10 15:30 104浏览
  • 行业痛点:电动车智能化催生语音交互刚需随着全球短途出行市场爆发式增长,中国电动自行车保有量已突破3.5亿辆。新国标实施推动行业向智能化、安全化转型,传统蜂鸣器报警方式因音效单一、缺乏场景适配性等问题,难以满足用户对智能交互体验的需求。WT2003HX系列语音芯片,以高性能处理器架构与灵活开发平台,为两轮电动车提供从基础报警到智能交互的全栈语音解决方案。WT2003HX芯片技术优势深度解读1. 高品质硬件性能,重塑语音交互标准搭载32位RISC处理器,主频高达120MHz,确保复杂算法流畅运行支持
    广州唯创电子 2025-04-10 09:12 174浏览
  •   卫星故障预警系统软件:卫星在轨安全的智能护盾   北京华盛恒辉卫星故障预警系统软件,作为确保卫星在轨安全运行的关键利器,集成前沿的监测、诊断及预警技术,对卫星健康状况予以实时评估,提前预判潜在故障。下面将从核心功能、技术特性、应用场景以及发展走向等方面展开详尽阐述。   应用案例   目前,已有多个卫星故障预警系统在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润卫星故障预警系统。这些成功案例为卫星故障预警系统的推广和应用提供了有力支持。   核心功能   实时状态监测:
    华盛恒辉l58ll334744 2025-04-09 19:49 162浏览
  • 由西门子(Siemens)生产的SIMATIC S7 PLC在SCADA 领域发挥着至关重要的作用。在众多行业中,SCADA 应用都需要与这些 PLC 进行通信。那么,有哪些高效可行的解决方案呢?宏集为您提供多种选择。传统方案:通过OPC服务器与西门子 PLC 间接通信SIMATIC S7系列的PLC是工业可编程控制器,能够实现对生产流程的实时SCADA监控,提供关于设备和流程状态的准确、最新数据。S7Comm(全称S7 Communication),也被称为工业以太网或Profinet,是西门
    宏集科技 2025-04-10 13:44 92浏览
  •   卫星故障预警系统:守护卫星在轨安全的 “瞭望塔”   卫星故障预警系统作为保障卫星在轨安全运行的核心技术,集成多源数据监测、智能诊断算法与预警响应机制,实时监控卫星关键系统状态,精准预判故障。下面从系统架构、技术原理、应用场景以及发展趋势这四个关键维度展开深入解析。   应用案例   目前,已有多个卫星故障预警系统在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润卫星故障预警系统。这些成功案例为卫星故障预警系统的推广和应用提供了有力支持。   系统架构与组成   卫星故障
    华盛恒辉l58ll334744 2025-04-09 17:18 135浏览
  • 行业变局:从机械仪表到智能交互终端的跃迁全球两轮电动车市场正经历从“功能机”向“智能机”的转型浪潮。数据显示,2024年智能电动车仪表盘渗透率已突破42%,而传统LED仪表因交互单一、扩展性差等问题,难以满足以下核心需求:适老化需求:35%中老年用户反映仪表信息辨识困难智能化缺口:78%用户期待仪表盘支持手机互联与语音交互成本敏感度:厂商需在15元以内BOM成本实现功能升级在此背景下,集成语音播报与蓝牙互联的WT2605C-32N芯片方案,以“极简设计+智能交互”重构仪表盘技术生态链。技术破局:
    广州唯创电子 2025-04-11 08:59 134浏览
  •   天空卫星健康状况监测维护管理系统:全方位解析  在航天技术迅猛发展的当下,卫星在轨运行的安全与可靠至关重要。整合多种技术,实现对卫星的实时监测、故障诊断、健康评估以及维护决策,有力保障卫星长期稳定运转。  应用案例       系统软件供应可以来这里,这个首肌开始是幺伍扒,中间是幺幺叁叁,最后一个是泗柒泗泗,按照数字顺序组合就可以找到。  一、系统架构与功能模块  数据采集层  数据处理层  智能分析层  决策支持层  二、关键技术  故障诊断技术  
    华盛恒辉l58ll334744 2025-04-10 15:46 76浏览
  • 背景近年来,随着国家对资源、能源有效利用率的要求越来越高,对环境保护和水处理的要求也越来越严格,因此有大量的固液分离问题需要解决。真空过滤器是是由负压形成真空过滤的固液分离机械。用过滤介质把容器分为上、下两层,利用负压,悬浮液加入上腔,在压力作用下通过过滤介质进入下腔成为滤液,悬浮液中的固体颗粒吸附在过滤介质表面形成滤饼,滤液穿过过滤介质经中心轴内部排出,达到固液分离的目的。目前市面上的过滤器多分为间歇操作和连续操作两种。间歇操作的真空过滤机可过滤各种浓度的悬浮液,连续操作的真空过滤机适于过滤含
    宏集科技 2025-04-10 13:45 80浏览
  • ‌亥姆霍兹线圈‌是由两组相同的线圈组成,线圈之间的距离等于它们的半径。当电流同时流过这两个线圈时,会在它们中间形成一个几乎均匀的磁场。这种设计克服了普通线圈磁场不均匀的缺陷,能够在中心区域形成稳定、均匀的磁场‌。‌亥姆霍兹线圈的应用领域‌包括材料、电子、生物、医疗、航空航天、化学、应用物理等各个学科。由于其操作简便且能够提供极微弱的磁场直至数百高斯的磁场,亥姆霍兹线圈在各研究所、高等院校及企业中被广泛用于物质磁性或检测实验。‌‌亥姆霍兹线圈的用途非常广泛,主要包括以下几个方面‌:‌粒子物理实验‌
    锦正茂科技 2025-04-09 17:04 108浏览
  •   海上电磁干扰训练系统:全方位解析      海上电磁干扰训练系统,作为模拟复杂海上电磁环境、锻炼人员应对电磁干扰能力的关键技术装备,在军事、科研以及民用等诸多领域广泛应用。接下来从系统构成、功能特点、技术原理及应用场景等方面展开详细解析。   应用案例   系统软件供应可以来这里,这个首肌开始是幺伍扒,中间是幺幺叁叁,最后一个是泗柒泗泗,按照数字顺序组合就可以找到。   一、系统构成   核心组件   电磁信号模拟设备:负责生成各类复杂的电磁信号,模拟海上多样
    华盛恒辉l58ll334744 2025-04-10 16:45 122浏览
  •     前几天同事问我,电压到多少伏就不安全了?考虑到这位同事的非电专业背景,我做了最极端的答复——多少伏都不安全,非专业人员别摸带电的东西。    那么,是不是这么绝对呢?我查了一下标准,奇怪的知识增加了。    标准的名字值得玩味——《电流对人和家畜的效应》,GB/T 13870.5 (IEC 60749-5)。里面对人、牛、尸体分类讨论(搞硬件的牛马一时恍惚,不知道自己算哪种)。    触电是电流造成的生理效应
    电子知识打边炉 2025-04-09 22:35 196浏览
我要评论
0
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦