CAN 配置
时钟源配置
CAN 的时钟源依赖 XTAL(40MHz),用户可调用 CAN_CoreClockSet() 来设置 XTAL 作为时钟源。
波特率与位时序参数配置
前面已经提到 CAN 总线的一个位(Bit)由四个时间段组成。为简化配置,CAN 控制器将传播段 (Prop_Seg)、相位缓冲段 1 (Phase_Seg1)合并为 TSEG1 ,将相位缓冲段 2 (Phase_Seg2)称为 TSEG2 。
备注
TSEG1 的设定是传播段 (Prop_Seg)、相位缓冲段 1 (Phase_Seg1)之和。
以 时钟源为 40MHz,要求 CAN 的通信速率为 1Mbaud/s ,采样点在 80%为例 ,各个段参数值计算如下:
采样点公式
采样点计算公式如下:
Sample Point (%) = (Sync_Seg + TSEG1) / (Sync_Seg + TSEG1 + TSEG2) × 100%
满足 80% 比例关系(4/5)的值有 8/10、12/15、16/20、20/25。
而单个 Bit 的 Tq 数量为:
Total Tq = Sync_Seg + TSEG1 + TSEG2
前面提到单个 Bit 总的 Tq 数量一般在 8 ~ 25,所以总 Tq 数量可选 10 或者 20,方便计算。
若选择 Tq 总数为 10,此时可以得到
Sync_Seg + TSEG1 = 8
Sync_Seg + TSEG1 + TSEG2 = 10
则 TSEG1 = 8 - 1 = 7 和 TSEG2 = 10 - 7 - 1 = 2 。
SJW 的值通常在 1 ~ 4 Tq,且不超过 TSEG1 和 TSEG2 的较小值。在此例中推荐设置为 1 Tq。
Bit 时序参数设置
波特率计算公式如下:
Baud Rate = core_clk / (BRP × Total Tq)
已知 1 Mbps 速率下,时钟源为 40 MHz,总 Tq 数为 10,则分频系数 BRP 为 4。
则可以配置以下各个段参数为:
参数 |
物理值 |
寄存器 |
备注 |
|---|---|---|---|
Clock |
40 MHz |
XTAL作为时钟源 |
|
BRP |
4 |
3 |
tq = 100ns |
NBT |
10 tq |
总位宽 |
|
TSEG1 |
7 tq |
6 |
包含 PropSeg + PhaseSeg1 |
TSEG2 |
2 tq |
1 |
PhaseSeg2 |
SJW |
1 tq |
1 |
|
结果 |
80% |
实际采样点 (1+7)/10 = 80% |
实际使用过程中,用户可直接调用 CAN_CalcBitTiming() 来计算目标波特率所需要的各个参数。
三点采样
当使能三点采样模式后,CAN 控制器会在三个不同的点对输入信号进行采样,每个采样点之间间隔 Tq,如下图所示。最终的逻辑电平由三个采样点中的多数电平决定。该方法可以有效地滤除信号中的毛刺,提高系统鲁棒性。
备注
一般在低速率模式(低于 125Kbps)下建议开启三点采样,此时每个 Tq 的时长较长,更容易因为外部毛刺而产生电平突变。
报文收发设置
CAN 模块通过管理报文(消息)缓冲区(message buffer,简称 MB)实现报文的发送和接收(包含过滤)。CAN 提供了一组寄存器作为公共接口(以下简称 RAM 接口 )来管理 报文缓冲区,如下图所示。
报文缓冲区管理
CAN 模块配备独立的 RAM 空间(352 × 32 bits),被划分为 16 个报文缓冲区(MB0~MB15),默认每个缓冲区占用 6 × 32 bits。
容量配置 : 每个缓冲区仅存储一条报文,但其大小可独立配置。
地址分配 : 设置每个缓冲区的基地址(Base Address)。 若 MB0 基地址设为 0x0,MB1 基地址设为 0x6,则 MB0 的大小即为 6 × 32 bits。
容量边界: 整个 RAM 的有效范围可单独指定。
报文发送和接收
报文发送流程
选定缓冲区:选择想要使用的报文缓冲区并使能
填充数据:将待发送的数据、ID、DLC 以及帧属性(IDE, RTR)写入 RAM 接口
配置模式:设定为发送模式
写入缓冲区:将上述参数设定和数据写入报文缓冲区
状态更新:报文缓冲区的状态位自动更新,以及上报中断(如果使能发送中断)
报文接收流程
选定缓冲区:选择想要使用的报文缓冲区并使能
配置过滤规则:设置 RAM 接口 的 ID、掩码(MASK)、IDE 和 RTR 位,定义该缓冲区期望接收的报文特征
配置模式:设定为接收模式
写入缓冲区:将上述参数设定写入报文缓冲区
数据接收和存储:当总线收到报文并通过 CRC 校验后,处理器扫描所有接收缓冲区,执行过滤匹配。若匹配成功且无错误,报文存入对应缓冲区。
状态更新:报文缓冲区的状态位自动更新,以及上报中断(如果使能接收中断,用户可在中断内读取缓冲区报文)。
有关 CAN 的使用示例可参考 CAN example。
缓冲区优先级
当多个缓冲区同时满足发送或接收条件时,硬件依据缓冲区编号(0-15)执行仲裁:
发送优先级 (Tx Priority): 低编号优先。编号越小(如 MB0),发送优先级越高。
接收优先级 (Rx Priority): 高编号优先。编号越大(如 MB15),在接收匹配时的优先级越高。
报文过滤设定
ISO 11898 标准采用广播通信机制,总线上没有物理地址的概念。节点通过 “报文过滤” 机制来决定是否接收总线上的数据帧。
CAN 模块可通过组合设置 接收标识符(ID) 和 接收掩码(Acceptance Mask) ,实现硬件级报文筛选,减轻 CPU 处理非相关报文的负担。
配置寄存器如下图所示:
CAN 报文过滤设置
接收所有报文
仅设置 ARB 寄存器的接收标识符,不配置 MASK 接收掩码。这表明无需关注接收标识符设置,接收所有报文
接收部分报文
设置 ARB 和 MASK 寄存器的接收标识符,配置 MASK 掩码。例如图 CAN 报文过滤设置,过滤标准帧时,如果 ARB 中的位 [28:18] 设置为 0x1,MASK 中的位 [28:18] 设置为 0x7FC,表明标准帧的 ID 低两位无需严格匹配,基址 ID 0x00、0x01、0x02 和 0x03 都将被接收。
接收指定报文
设置 ARB 寄存器的接收标识符,并配置 MASK 所有掩码位为 1。此时将严格匹配接收 ID,只有指定 ID 的报文可以被接收。
小技巧
用户还可以设定 MASK 中的以下属性来进一步匹配帧类型:
RTR 属性:是否严格匹配 ARB 中的 RTR 设定(接收数据帧还是远程帧)
IDE 属性:是否严格匹配 ARB 中的 IDE 设定(接收标准帧还是扩展帧)
FIFO 模式
CAN 支持将 RAM 顶部的 4 个缓冲区(MB12~MB15)合并为一个先进先出(FIFO)队列,以增强连续接收能力。
启用机制 : 启用 FIFO 后,MB12~MB15 被保留作为 FIFO 存储空间。
过滤规则 : FIFO 统一使用 MB12 的配置(ID, IDE, RTR 及掩码)作为过滤标准。
最高优先级 : FIFO 拥有最高的接收优先级,高于普通接收缓冲区。
溢出处理 : 当 FIFO 已满(MB12~MB15 均有数据)且收到新报文时,FIFO 执行滚动覆盖策略。最早接收的数据(原 MB12)将丢失,原 MB13 的数据移至 MB12,以此类推,新报文将被存入 MB15。同时触发溢出状态标志。
状态监控 (CAN_FIFO_STS):
fifo_msg_empty: FIFO 为空fifo_msg_full: FIFO 已满(存有 4 帧未读报文)fifo_msg_overflow: 溢出(满状态下继续接收新报文)fifo_msg_lvl: 当前 FIFO 内的报文数量
备注
FIFO 模式已经默认开启,如不需要可关闭。
使用 DMA 接收报文
CAN 模块支持通过通用直接内存访问控制器(GDMA)进行数据接收,并且支持两种流控模式:由 GDMA 作为流控制器,或由 CAN 作为流控制器。
当启用 DMA 时,报文缓冲区(Message Buffer )中的数据,包含仲裁段(ARB)、控制段(CS)及数据段(DATA),会依次通过 GDMA 传输至目标 Memory 地址。
配置过程如下:
CAN 侧配置:
在 Rx DMA 配置寄存器中,设置 Rx DMA 所有权的归属,并配置
rxdma_src_msize,通常设为 1。rxdma_owner = 0,所有权属于 GDMArxdma_owner = 1,所有权属于 CAN
在要使用的报文缓冲区控制寄存器中,使能该 Buffer 的 DMA 功能
在 CAN 全局控制寄存器中,开启 Rx DMA 使能。
GDMA 侧配置:
配置 GDMA 的源地址、目标地址、DMA 传输方向、块大小 (block size) 等参数。
备注
Rx DMA 每次传输操作仅针对一个报文缓冲区。
GDMA 的 Source Burst 大小 必须与 CAN 侧配置的
rxdma_src_msize保持一致。
自动重传
ISO 11898-1 标准规定,如果控制器在发送报文过程中未能成功发送(即未收到 ACK、发生错误或仲裁失败),控制器可配置自动重新发送该报文。使能自动重传后,软件只需写入一次发送请求,硬件会自动处理后续的重传逻辑。这一过程对上层软件(Application Layer)通常是透明的。
备注
不支持设定具体的重传次数。
使能自动重传
在 CAN 模块中, CAN_AutoReTxEn 控制位用于决定是否遵循标准的 ISO 自动重传流程:
使能 (
CAN_AutoReTxEn= 1): 标准模式 。当发送失败(如仲裁丢失或产生发送错误)时,硬件会自动重新参与总线竞争,尝试再次发送同一帧报文,直到发送成功或节点因错误过多进入“总线关闭(Bus Off)”状态。禁止 (
CAN_AutoReTxEn= 0): 单次发送模式 。CAN 控制器只尝试发送一次报文。无论发送成功与否(即使发生错误或丢失仲裁),硬件都不会尝试重传。
触发自动重传的场景
当自动重传功能使能时,以下三种场景会触发重传:
仲裁丢失 (Arbitration Lost) :
当前节点在发送 ID 阶段,检测到总线电平与自己发送的电平不一致(自己发隐性 1,总线显性 0),说明有更高优先级的节点正在发送。当前节点立即停止发送,转为接收状态。一旦总线空闲,硬件会立即再次尝试发送该报文。
发送错误 (Transmission Error) :
发送过程中检测到位错误(Bit Error)、填充错误(Stuff Error)、格式错误(Form Error)或 CRC 错误,发送节点会发送错误帧破坏当前传输,待总线空闲时重新发送。
ACK 错误 (ACK Error) :
发送节点在 ACK Slot 发送隐性电平(1),但总线上没有检测到显性电平(0)。这意味着总线上没有任何节点正确响应该报文(即回复 ACK)。发送节点判定为 ACK Error,随后发送错误帧。待总线空闲时,重新发送该报文。
低功耗唤醒
CAN 模块支持低功耗休眠模式,休眠类型仅 支持 CG(Clock gating)模式 。在此模式下,模块的主时钟停止,但内部集成的 唤醒检测电路 仍然工作。
CAN 使用低频时钟 (OSC4M) 驱动唤醒电路。当 CPU 及 CAN 模块进入休眠模式时,系统需保持 OSC4M 处于开启状态以支持监测功能。有关休眠模式配置可参考 省电配置 。
唤醒示意图
唤醒电路的工作流程如下:
启用条件:
唤醒检测仅在 CAN 进入休眠模式(
can_sleep_en置位)且唤醒滤波功能开启(can_wakepin_flt_en置位)时有效。检测原理:
电路持续监测 Rx 引脚上显性电平持续时长,与预设的阈值
can_wakepin_flt_length比较,判断是否为有效的唤醒信号。如 唤醒示意图 所示,显性电平持续时长 t(即 Rx pin 上的逻辑电平 0 的持续时长) 大于设定的阈值(can_wakepin_flt_length/OSC4M),即可唤醒 CAN 模块及整个系统。触发动作:
唤醒:如果检测到的显性电平持续时间超过预设阈值,唤醒电路将生成唤醒信号,重新激活 CAN 模块及整个系统。
保持:如果显性电平持续时间未达到阈值,模块与系统继续保持休眠状态
备注
唤醒时并不关心协议帧的具体内容 :唤醒 CAN 模块的显性电平来自一笔有效协议帧,该协议帧无法被接收。
唤醒时收发器应正常工作:部分收发器可能有待机/休眠(standby/sleep)模式,确保唤醒 CAN 模块前,收发器已经正常工作。
唤醒与丢包(Wake-up & Frame Loss):
由于系统从休眠恢复到主时钟稳定需要一定时间,CAN 模块 必然会错过触发唤醒的那一帧报文 。后续能否收到数据取决于发送方的重传机制:
若总线上无其他节点应答(ACK) :
发送节点因未收到 ACK 而判定发送失败,若其使能了自动重传机制,会立即重发该帧。此时 CAN 模块已完成唤醒初始化,可以正常接收这笔 重传 的报文。
若总线上有其他节点应答(ACK) :
发送节点收到 ACK 后认为报文发送成功,不会重传。此时,当前节点(CAN)虽然被成功唤醒,但 无法接收到该帧数据 (即发生了单帧丢失)。
测试模式
测试模式有两种,分为:
静默模式(Silence):即 ISO 11898-1 中的总线监控模式 (Bus Monitoring Mode),用于在不干扰总线的情况下分析流量。可正常接收所有帧,但是模块不会发送任何帧、也不会发送 ACK。
回环模式:用于验证 CAN 控制器本身是否工作正常,可细分为
外部回环模式:该模式下,数据帧会被发送到 TX 端,可通过外部分析仪抓取协议帧
内部回环模式:该模式数据帧完全在 CAN 控制器内部传输,不会被发送到外部
静默模式
外部回环模式
内部回环模式