CAN通信

Posted 旭日初扬

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CAN通信相关的知识,希望对你有一定的参考价值。

一、CAN总线简介

1.1、概述

CAN是Controller Area Network的缩写(以下称为CAN),译为控制器区域网。是ISO国际标准化的串行通信协议。

1986年德国电气商博世公司开发出面向汽车的CAN通信协议。

CAN通过ISO11898及ISO11519进行了标准化。CAN是国际上引用最广泛的现场总线之一。

它的出现为分布式控制系统实现各节点之间实时、可靠的数据通信提供了强有力的技术支持。

CAN通信具有两根信号线,分别是CAN_H和CAN_L,CAN控制器根据这两根线上的电位差来判断总线电平。总线电平分为隐性电平和显性电平,两者必居其一。发送方通过使总线电平发生变化,将消息发送给接收方。

1.2、CAN协议的特点

1.2.1、多主控制

在总线空闲时,所有单元都可以发送消息(多主控制),二两个以上的单元同时开始发送消息时,根据标识符(Identifier以下称为ID)决定优先级。

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

两个以上的单元同时发送消息,对各消息ID的每个为进行逐个仲裁比较。仲裁获胜(被判定为优先级最高)的单元可继续发送消息,仲裁失利的单元则立刻停止发送而进行接收工作。

1.2.2、系统的柔软性

与总线相连的单元没有类似地址的信息。因此在总线上增加单元时,连接在总线上的其他单元的软硬件及应用层都不需要改变。

1.2.3、通信速度较快,通信距离远

最高 1Mbps(距离小于 40M),最远可达 10KM,(速率低于 5Kbps)。

1.2.4、具有错误检测、错误通知和错误恢复功能

所有单元都可以检测错误(错误检测功能),检测出错误的单元会立即同时通知其他所有单元(错误通知功能),
正在发送消息的单元一旦检测出错误,会强制结束当前的发送。强制结束发送的单元会不断反复地重新发送此消息直到成功发送为止(错误恢复功能)。

1.2.5、故障封闭功能

CAN 可以判断出错误的类型是总线上暂时的数据错误(如外部噪声等)还是持续的数据错误(如单元内部故障、驱动器故障、断线等)。
由此功能,当总线上发生持续数据错误时,可将引起此故障的单元从总线上隔离出去。

1.2.6、连接节点多

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

二、CAN总线的协议与结构

2.1、ISO11898与ISO11519

ISO11898 标准可以组建一个高速、短距离“闭环网络”,此标准要求总线最大长度为 40m,通信速度最高为 1Mbps,总线的两端各要求有一个“120 欧”的电阻,此电阻可作为阻抗匹配功能,以减少回波反射。

而 ISO11519-2 标准可以组建一个低速、远距离“开环网络”,它的最大传输距离为 1km,最高通讯速率为 125kbps,两根总线是独立的、不形成闭环,要求每根总线上各串联有一个“2.2 千欧”的电阻。

2.2、CAN网络的拓扑结构

从上图可以看到,CAN 总线和 CAN 控制器间需要一个 CAN 收发器将信号进行转换。我们开发板上使用的 CAN 收发器是 TJA1040(1044)

CAN 通信主要是通过 5 种类型的帧进行,分别是数据帧、遥控帧、错误帧、过载帧和帧间隔。

其中数据帧和遥控帧有标准格式和扩展格式两种格式。标准格式有 11 个位的标识符(ID),扩展格式有 29 个位的 ID。

数据帧一般有7个段构成

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

  • 图中 D 表示显性电平, R 表示隐形电平(下同)。
  • 帧起始是由 1 个位的显性电平表示,标准帧和扩展帧相同。
  • 仲裁段,表示数据优先级的段,标准帧和扩展帧格式在本段有所区别

  • 标准格式的 ID 有 11 个位。从 ID28 到 ID18 被依次发送。禁止高 7 位都为隐性(禁止设定: ID=1111111XXXX)。
  • 扩展格式的 ID 有29 个位。基本 ID 从 ID28 到 ID18,扩展 ID 由 ID17 到 ID0 表示。
  • 基本 ID和 标 准 格 式 的 ID 相 同 。 禁 止 高 7 位 都 为 隐 性 ( 禁 止 设 定 : 基 本ID=1111111XXXX)。
  • 其中 RTR 位用于标识是否是远程帧( 0,数据帧; 1,远程帧), IDE 位为标识符选择位( 0,使用标准标识符; 1,使用扩展标识符), SRR 位为代替远程请求位,为隐性位,它代替了标准帧中的 RTR 位。

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

r0 和 r1 为保留位。保留位必须全部以显性电平发送,但接收方可以接收显性、隐性及其任意组合的电平。DLC 为数据长度码,数据长度码与数据的字节数的对应关系如下图所示:

数据的字节数必须为 0~8 字节。但接收方对 DLC = 9~15 的情况并不视为错误。
数据段,该段可包含 0~8 个字节的数据。从 MSB(最高位)开始输出,标准帧和扩展帧此段相同。

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

CRC 顺序是根据多项式生成的 CRC 值, CRC 的计算范围包括帧起始、仲裁段、控制段、数据段。接收方以同样的算法计算 CRC 值并进行比较,不一致时会通报错误。

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

发送单元在 ACK 段发送 2 个位的隐性位。接收到正确消息的单元在 ACK槽(ACK Slot)发送显性位, 通知发送单元正常接收结束。这称作“发送 ACK”或者“返回 ACK”。发送 ACK 的是在既不处于总线关闭态也不处于休眠态的所有接收单元中,接收到正常消息的单元(发送单元不发送 ACK)。所谓正常消息是指不含填充错误、格式错误、 CRC 错误的消息。

帧结束,它表示该帧的结束的段,由 7 个位的隐性位构成。标准帧和扩展帧此帧是相同的。

三、CAN位时序

由发送单元在非同步的情况下发送的每秒钟的位速率。一个位可分为4段。

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

这些段又由可称为 Time Quantum(时间段   以下称为 Tq)的最小时间单位构成。

  • 1 位分为 4 个段,每个段又由若干个 Tq 构成,这称为位时序。
  • 1 位由多少个 Tq 构成、每个段又由多少个 Tq 构成等,可以任意设定位时序。通过设定位时序,多个单元可同时采样,也可任意设定采样点。

各段的作用和 Tq 数如下图所示:

上图中的采样点是指读取总线电平,并将读到的电平作为位值的点。位置在PBS1 结束处。根据这个位时序,可以计算 CAN 通信的波特率。

在总线空闲态,最先开始发送消息的单元获得发送权。当多个单元同时开始发送时,各发送单元从仲裁段的第一位开始进行仲裁。连续输出显性电平最多的单元可继续发送。

单元 1 和单元 2 同时开始向总线发送数据,开始部分他们的数据格式是一样的,故无法区分优先级,直到图中红色部分时刻,单元 1输出隐性电平,而单元 2 输出显性电平,此时单元 1 仲裁失利,立刻转入接收状态工作,不再与单元 2 竞争,而单元 2 则顺利获得总线使用权,继续发送自己的数据。这就实现了仲裁,让连续发送显性电平多的单元获得总线使用权。

三、结构框图

框图中的“存储访问控制器”是由 CAN1 控制的,CAN2 无法直接访问存储区域,所以如果使用 CAN2 的时候必须先使能 CAN1 外设的时钟。

框图中主要包含 CAN 控制内核、发送邮箱、接收 FIFO 以及验收筛选器。

3.1、CAN控制内核

CAN控制内核包含了各种控制/状态寄存器,主要了解主控制寄存器CAM_MCR及位时序寄存器CAN_BTR

控制寄存器CAN_MCR

主控制寄存器CAN_MCR负责管理CAN的工作模式。

位时序寄存器CAN_BTR

用于配置测试模式、波特率以及各种位内的段参数。

测试模式

STM32 的 CAN 提供了测试模式,配置位时序寄存器 CAN_BTR的 SILM 及 LBKM 寄存器位可以控制使用正常模式、静默模式、回环模式及静默回环模式。

(1)正常模式

  • 一旦初始化完成,软件必须向硬件请求进入正常模式,这样才能在 CAN 总线上进行同步,并开始接收和发送。
  • 进入正常模式的请求可通过将 CAN_MCR 寄存器的 INRQ 位清零来发出。
  • bxCAN 进入正常模式,并与 CAN 总线上的数据传输实现同步后,即可参与总线活动。
  • 执行这一步时,需要等待出现一个由 11 个连续隐性位(总线空闲状态)组成的序列。
  • 硬件通过将 CAN_MSR 寄存器的 INAK 位清零,来确认切换到正常模式。

(2)静默模式

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

(3)回环模式

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

(4)静默回环模式

可以通过将 CAN_BTR 寄存器的 LBKM 和 SILM 位置 1,将环回模式和静默模式组合起来。

该模式可用于“热自检”,也就是说, bxCAN 可以像在环回模式下一样进行检测,同时又不会影响与 CANTX 和 CANRX 引脚相连接的运行中的CAN 系统。在此模式下, CANRX 引脚与 bxCAN 断开连接, CANTX 引脚则保持隐性。

该模式下的 bxCAN 如下:

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

 

位时序及波特率

 

STM32F1 的 CAN 控制器定义的位时序与前面我们介绍的 CAN 标准位时序有一点区别,STM32F1 把传播时间段和相位缓冲段 1(STM32F1 称之为位段 1)合并了,所以 STM32F1 的 CAN 一个位只有 3 段。分别是:同步段 (SYNC_SEG)位段 1 (BS1)位段 2 (BS2)。STM32F7 的 CAN 的位时序如下图所示:

 

  • 同步段 (SYNC_SEG):位变化应该在此时间段内发生。它只有一个时间片的固定长度(1 x tCAN)。
  • 位段 1 (BS1):定义采样点的位置。它包括 CAN 标准的 PROP_SEG 和PHASE_SEG1。其持续长度可以在 1 到 16 个时间片之间调整(刚好等于我们前面介绍的传播时间段和相位缓冲段 1 之和),但也可以自动加长,以补偿不同网络节点的频率差异所导致的相位漂移。
  • 位段 2 (BS2):定义发送点的位置。它代表 CAN 标准的 PHASE_SEG2。其持续长度可以在 1 到 8 个时间片之间调整,但也可以自动缩短,以补偿负相位漂移。

 

通过配置位时序寄存器 CAN_BTR(为了避免编程错误,位时序寄存器 (CAN_BTR) 只能在器件处于待机模式时进行配置) 的 TS1[3:0]及 TS2[2:0]寄存器位设定 BS1 及BS2 段的长度后,我们就可以非常方便的计算 CAN 通信波特率,计算公式如下:

tPCLK 指 APB1 时钟,默认值为 36MHz,现在我们只要知道 BS1 和BS2 的设置值,就可以计算出波特率。比如设置 TS1=7、TS2=8 和 BRP=3,

在 APB1频率为 36Mhz 的条件下,即可得到 CAN 通信的波特率BoundRate=54000/[(8+9+1)*4]=500Kbps。

3.2、发送邮箱

发送邮箱,它含有 3 个发送邮箱,软件可通过三个发送邮箱设置消息。发送调度程序负责决定首先发送哪个邮箱的内容。

3.3、验收筛选器

 

  • 互联网型产品的 bxCAN 提供了 28 个可调整/可配置的标识符筛选器组
  • STM32F103ZET6 只有 14 个,用于选择软件所需的传入消息并丢弃其余消息。
  • 每个筛选器组由 2 个 32 为寄存器,CAN_FxR1 和 CAN_FxR2 组成。

根据筛选器尺度不同,一个筛选器组可以:

  1. 为 STDID[10:0]、 EXTID[17:0]、 IDE 和 RTR 位提供一个 32 位筛选器。
  2. 为 STDID[10:0]、 RTR、 IDE 和 EXTID[17:15] 位提供两个 16 位筛选。
  • 筛选器还可配置为掩码模式或标识符列表模式。
  • 在掩码模式下,标识符寄存器与掩码寄存器关联,用以指示标识符的哪些位“必须匹配”,哪些位“无关”。而在标识符列表模式下,掩码寄存器用作标识符寄存器。
  • 这时,不会定义一个标识符和一个掩码,而是指定两个标识符,从而使单个标识符的数量加倍。传入标识符的所有位都必须与筛选器寄存器中指定的位匹配。

通过 CAN_FMR 寄存器,可以配置过筛选器组的位宽和工作模式

为了过滤出一组标识符,应该设置筛选器组工作在掩码模式
为了过滤出一个标识符,应该设置筛选器组工作在标识符列表模式
应用程序不用的过滤器组,应该保持在禁用状态。

  • 筛选器组中的每个筛选器,都被编号为(叫做筛选器号,上图中的 n)从 0 开始,到某个最大数值-取决于筛选器组的模式和位宽的设置。
  • 举个简单的例子,我们设置筛选器组 0 工作在:1 个 32 位筛选器-标识符掩码模式,然后设置 CAN_F0R1=0XFFFF0000, CAN_F0R2=0XFF00FF00。
  • 其中存放到 CAN_F0R1 的 值 就 是 期 望 收 到 的 ID , 即 我 们 希 望 收 到 的 ID(STID+EXTID+IDE+RTR)最好是: 0XFFFF0000。
  • 而 0XFF00FF00 就是设置我们需要必须关心的 ID,表示收到的 ID,其位[31:24]和位[15:8]这 16 个位的必须和 CAN_F0R1 中对应的位一模一样,而另外的 16 个位则不关心,可以一样,也可以不一样,都认为是正确的 ID,即收到的 ID 必须是 0XFFxx00xx,才算是正确的(x 表示不关心)。

3.4、CAN 接收 FIFO

  • 硬件使用两个接收 FIFO 来存储传入消息。每个 FIFO 中有三个邮箱用于存储三条完整消息。FIFO 完全由硬件管理。
  • FIFO 开始时处于空状态,在接收的第一条有效消息存储在其中后,变为Pending_1 状态。
  • 硬件通过将 CAN_RFR 寄存器的 FMP[1:0] 位置为 01b 来指示该事件。消息将在 FIFO 输出邮箱中供读取。
  • 软件将读取邮箱内容,并通过将CAN_RFR 寄存器的 RFOM 位置 1,来将邮箱释放。FIFO 随即恢复空状态。
  • 如果同时接收到新的有效消息,FIFO 将保持 Pending_1 状态,新消息将在输出邮箱中供读取。
  • 如果应用程序未释放邮箱,下一条有效消息将存储在 FIFO 中,使其进入Pending_2 状态(FMP[1:0] = 10b)。
  • 下一条有效消息会重复该存储过程,同时将FIFO 变为 Pending_3 状态(FMP[1:0] = 11b)。
  • 此时,软件必须通过将 RFOM 位置 1 来释放输出邮箱,从而留出一个空邮箱来存储下一条有效消息。否则,下一次接收到有效消息时,将导致消息丢失。
  • 一旦 FIFO 处于 Pending_3 状态(即三个邮箱均已满),则下一次接收到有效消息时,将导致上溢并丢失一条消息。

硬件通过将 CAN_RFR 寄存器的 FOVR位置 1 来指示上溢状况。丢失的消息取决于 FIFO 的配置:

  1. 如果禁止 FIFO 锁定功能( CAN_MCR 寄存器的 RFLM 位清零),则新传能访问到最新的消息。
  2. 如果使能 FIFO 锁定功能( CAN_MCR 寄存器的 RFLM 位置 1),则将丢弃最新的消息,软件将提供 FIFO 中最早的三条消息。

消息存储到 FIFO 中后,FMP[1:0] 位即会更新,如果 CAN_IER 寄存器的FMPIE 位置 1,将 产生中断请求。

FIFO 存满消息(即存储了第三条消息)后,CAN_RFR 寄存器的 FULL 位置 1,如果 CAN_IER 寄存器的 FFIE 位置 1,将产生中断。出现上溢时, FOVR 位将置 1,如果 CAN_IER 寄存器的 FOVIE 位置 1,将产生中断。入的消息将覆盖 FIFO 中存储的最后一条消息。在这种情况下,应用程序将始终

3.5、CAN2整体控制逻辑

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

 

四、CAN配置步骤

CAN 相关库函数在 stm32f10x_can.c 和 stm32f10x_can.h 文件中

4.1、使能CAN时钟,将对应引脚复用映射为CAN功能

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); // 使能端口A时钟

RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE);  // 使能CAN1 时钟  CAN1挂载在APB1总线上

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  // 上拉输入模式
GPIO_Init(GPIOA,&GPIO_InitStructure);          // 初始化 GPIO

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12;
GPIO_initStructure.GPIO_Mode = GPIO_Mode_AF_PP;  // 复用推挽输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz
GPIO_init(GPIOA,&GPIO_InitStructure);

(2)设置CAN工作模式、波特率等

使能了 CAN 时钟后,接下来就可以通过 CAN_MCR 寄存器配置其工作模式、波特率大小等参数。库函数中提供了 CAN_Init()函数用来完成这一步骤

uint8_t CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef*CAN_InitStruct);
typedef struct
{
uint16 CAN_Prescaler;
uint_8 CAN_Mode;
uint_8 CAN_SJW;
uint_8 CAN_BS1;
uint_8 CAN_BS2;
FunctionalState CAN_TTCM;
FunctionalState CAN_ABOM;
FunctionalState CAN_AWUM;
FunctionalState CAN_NART;
FunctionalState CAN_RFLM;
FunctionalState CAN_FxFP;

}
  •  CAN_Prescaler:用于设置 CAN 外设的时钟分频,它可控制时间片 tq 的时间长度,这里设置的值最终会加 1 后再写入 BRP 寄存器位。
  •  CAN_Mode:用于设置 CAN 的工作模式,可设置为:
  1. 正常模式(CAN_Mode_Normal)
  2. 回环模式(CAN_Mode_LoopBack)
  3. 静默模式(CAN_Mode_Silent)
  4. 回环静默模式(CAN_Mode_Silent_LoopBack)
  •  CAN_SJW:用于置 SJW (再同步跳转宽度)的极限长度,即 CAN 重新同步时单次可增加或缩短的最大长度,它可以被配置为 1-4tq(CAN_SJW_1/2/3/4tq)。

假设:CAN总线的一个位时间中包含两个缓冲段BS1和BS2:

在两个缓冲段中间的位置,即是读取总线电平的采样点位置,当检测到总线上存在相位差的时候,通过延长BS1段或缩短BS2段来获得同步,这样的方式称为重新同步。

这两个相位缓冲段的延长时间或缩短时间上限由再同步跳转宽度(SJW)给定。采样点是接收节点判断信号逻辑的位置,CAN通讯属于异步通讯,需要通过不断的重新同步才能保证收发节点的采样准确,

  •  CAN_BS1:用于设置 CAN 位时序中的 BS1 段的长度,它可以被配置为 1-16个 tq 长度(CAN_BS1_1/2/3…16tq)。
  •  CAN_BS2:用于设置 CAN 位时序中的 BS2 段的长度,它可以被配置为 1-8个 tq 长度(CAN_BS2_1/2/3…8tq)。
  • FunctionalState CAN_TTCM:用于设置是否使用时间触发功能,ENABLE 为使能,DISABLE 为失能。时间触发功能在某些 CAN 标准中会使用到。
  • FunctionalState CAN_ABOM:用于设置是否使用自动离线管理(ENABLE/DISABLE),使用自动离线管理可以在节点出错离线后适时自动恢复,不需要软件干预。
  • FunctionalState CAN_AWUM:用于设置是否使用自动唤醒功能(ENABLE/DISABLE),使能自动唤醒功能后它会在监测到总线活动后自动唤醒。
  • FunctionalState CAN_NART:用于设置是否使用自动重传功能(ENABLE/DISABLE),使用自动重传功能时,会一直发送报文直到成功为止。
  • FunctionalState CAN_RFLM:用于设置是否使用锁定接收 FIFO(ENABLE/DISABLE),锁定接收FIFO 后,若 FIFO 溢出时会丢弃新数据,否则在 FIFO 溢出时以新数据覆盖旧数据。
  • FunctionalState CAN_FxFP:用于设置发送报文的优先级判定方法(ENABLE/DISABLE),使能时,以报文存入发送邮箱的先后顺序来发送,否则按照报文 ID 的优先级来发送。

设置好 CAN_Prescaler、CAN_BS1和 CAN_BS2 的值,带入到 CAN 波特率计算公式:

CAN 波特率=Fpclk1/((CAN_BS1+CAN_BS2+1)*CAN_Prescaler)

CAN设置为工作模式,波特率为500kbps

CAN_InitTypeDef  CAN_InitStructure;
CAN_InitStructure.CAN_TTCM = DISABLE; // 非时间触发通信模式
CAN_InitStructure.CAM_ABOM = DISABLE; // 软件自动离线管理
CAN_InitStructure.CAN_AWUM = DISABLE; // 睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP为)
CAN_InitStructure.CAN_NART = ENABLE;  // 使用报文自动传送
CAN_InitStructure.CAN_RFLM = DISABLE; // 报文不锁定,新的覆盖旧的
CAN_InitStructure.CAN_TXFP = DISABLE; // 优先级由报文标识符决定
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; // 模式设置
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;  //  重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位CAN_SJW_1tq ~ CAN_SJW_4tq

CAN_InitStructure.CAN_BS1_7tq;  //  Tbs1范围CAN_BS1_1tq ~ CAN_BS1_8tq
CAN_InitStructure.CAN_BS2_6tq;  //  Tbs2范围CAN_BS2_1tq  ~ cAN_BS2_8tq

CAN_InitStructure.CAN_Prescaler = 6;
CAN_Init(CAN1,&CAN_InitStructure);//初始化CAN1

(3)设置CAN筛选器

通过CAN_FMR寄存器设置CAN筛选器,库函数中提供了CAN_FilterInit()函数此操作

函数原型

void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct);
typedef struct
{
uint16_t CAN_FilterIdHigh;
uint16_t CAN_FilterIdLow;
uint16_t CAN_FilterMaskIdHigh;
uint16_t CAN_FilterMaskIdLow;
uint16_t CAN_FilterFIFOAssignment;
uint8_t  CAN_FilterNumber;
uint8_t  CAN_FilterMode;
uint8_t  CAN_FilterScale;
FunctionalState CAN_FilterActivation;
}CAN_FilterInitTypedef;
  • CAN_FilterIdHigh:用于存储要筛选的 ID,若筛选器工作在 32 位模式,它存储的是所筛选 ID 的高 16 位;若筛选器工作在 16 位模式,它存储的就是一个完整的要筛选的 ID。
  • CAN_FilterIdLow:同上一个成员一样,它也是用于存储要筛选的 ID,若筛选器工作在 32 位模式,它存储的是所筛选 ID 的低 16 位;若筛选器工作在 16位模式,它存储的就是一个完整的要筛选的 ID。
  • CAN_FilterMaskIdHigh:用于存储要筛选的 ID 或掩码。CAN_FilterMaskIdHigh 存储的内容分两种情况,当筛选器工作在标识符列表模式时,它的功能与 CAN_FilterIdHigh 相同,都是存储要筛选的 ID;而当筛选器工作在掩码模式时,它存储的是 CAN_FilterIdHigh 成员对应的掩码,与CAN_FilterIdLow 组成一组筛选器。
  • CAN_FilterMaskIdLow:同上一个成员一样,用于存储要筛选的 ID或掩码,只不过这里对应存储 CAN_FilterIdLow 的成员。
  • CAN_FilterFIFOAssignment:用于设置当报文通过筛选器的匹配后,该报文会被存储到哪一个接收 FIFO,它的可选值为 FIFO0 或FIFO1(CAN_Filter_FIFO0/1)。
  • CAN_FilterNumber:用于设置筛选器的编号,即使用的是哪个筛选器。CAN 一共有 28 个筛选器,所以它的可输入参数范围为 0-27。
  • CAN_FilterMode:用于设置筛选器的工作模式,可以设置为列表模式(CAN_FilterMode_IdList)及掩码模式(CAN_FilterMode_IdMask)。
  • CAN_FilterScale:用于设置筛选器的位宽,可以设置为 32 位长(CAN_FilterScale_32bit)及 16 位长(CAN_FilterScale_16bit)。
  • CAN_FilterActivation:用于设置是否激活这个筛选器(ENABLE/DISABLE)。

使用滤波器组0,工作在32为标识符屏蔽位模式

CAN_FilterInitTypeDef CAN_FilterInitStructure;

// 配置筛选器
CAN_FilterInitStructure.CAN_FilterNumber = 0; // 过滤器 0
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; // 设置筛选器工作模式
/*
工作模式可设置:
列表模式(CAN_FilterMode_IdList)
掩码模式(CAN_FilterMode_IdMask)
*/

CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32 位  设置筛选器的位宽
CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;//32 位 ID   存储要筛选的ID  高16ID
CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;// 存储要筛选的ID,低16位的ID
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32 位 MASK
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器 0关联到 FIFO0
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器 0
CAN_FilterInit(&CAN_FilterInitStructure);//滤波器初始化

 

以上是关于CAN通信的主要内容,如果未能解决你的问题,请参考以下文章

java.util.MissingResourceException: Can't find bundle for base name init, locale zh_CN问题的处理(代码片段

[react] Module not found: Can't resolve 'schedule' in 'C:Usersadcaldvmtn7myapp (代码片段

qt上 上下位机can总线通信

无法通过接口获取与片段通信的活动

无法保留嵌套片段

CAN 总线通信 简要概括