3. CAN模块初始化与寄存器配置:模式选择、位时序与滤波器
好,咱们直接进入正题。CAN模块要正常工作,初始化这步必须走对。我见过太多板子调不通,最后发现是初始化顺序乱了,或者某个寄存器配错了。说白了,初始化就是给CAN控制器“立规矩”——告诉它用什么模式跑、跑多快、收谁的数据。
这一节,我带你手把手把三个核心环节捋清楚:模式选择、位时序配置、滤波器设置。你跟着走一遍,以后遇到初始化问题,心里就有底了。
3.1 CAN模式选择:正常、环回、静默
CMS32的CAN控制器支持三种工作模式。你想想看,刚上电调试时,总不能让板子直接往总线上发数据吧?万一干扰到其他节点就麻烦了。所以模式选择是第一步。
| 模式 | 发送 | 接收 | ACK应答 | 典型用途 |
|---|---|---|---|---|
| 正常模式 | 正常发送到总线 | 从总线接收 | 正常应答 | 产品最终运行 |
| 环回模式 | 发送到内部回路 | 接收自身发送 | 无外部应答 | 单板自测、调试 |
| 静默模式 | 禁止发送 | 从总线接收 | 不应答 | 总线监听、分析 |
寄存器配置上,CMS32通常通过 CAN_MODE 寄存器的 MODE[1:0] 位来选择:
// 伪代码示例
CAN_MODE = 0x00; // 正常模式
// CAN_MODE = 0x01; // 环回模式
// CAN_MODE = 0x02; // 静默模式
3.2 位时序寄存器(BTR)详解
位时序,说白了就是决定CAN通信的“节奏”。CAN总线是异步的,没有单独的时钟线,所有节点靠同步采样来解析数据。如果大家的节奏不一致,数据就全乱了。
CMS32的位时序寄存器 CAN_BTR 通常包含以下几个字段:
- BRP(Baud Rate Prescaler):波特率预分频器,决定一个时间量子(Tq)的长度。
- SEG1(时间段1):包含传播段和相位缓冲段1,通常占3~16个Tq。
- SEG2(时间段2):相位缓冲段2,通常占2~8个Tq。
- SJW(同步跳转宽度):用于补偿时钟偏差,通常设为1~4个Tq。
一个CAN位的时间 = (1 + SEG1 + SEG2) × Tq。波特率 = 1 / 位时间。
举个例子,假设系统时钟为48MHz,目标波特率500kbps:
- 先算Tq:Tq = (BRP + 1) / 48MHz。取BRP=3,则Tq = 4/48M = 83.3ns。
- 再算位时间:位时间 = 1/500k = 2000ns。
- 需要的Tq数 = 2000 / 83.3 ≈ 24。取SEG1=15,SEG2=8,则总Tq = 1+15+8 = 24。
- SJW通常取1~2,这里取1。
// 配置示例:500kbps,48MHz时钟
CAN_BTR = (3 << 0) // BRP = 3
| (15 << 8) // SEG1 = 15
| (8 << 16) // SEG2 = 8
| (1 << 24); // SJW = 1
为什么会强调采样点?因为总线有传输延迟,采样点太靠前,信号还没稳定;太靠后,可能错过边沿。我在一个项目中遇到过,两节点距离200米,波特率设了1M,结果丢包严重。后来把采样点从60%调到75%,问题就解决了。
3.3 滤波器配置(ACR/AMR)
CAN总线上报文很多,但你的节点可能只关心其中一部分。滤波器就是干这个的——只让符合条件的报文进入接收缓冲区。
CMS32的滤波器由两个寄存器配合工作:
- ACR(接收代码寄存器):期望接收的报文ID或数据模式。
- AMR(接收掩码寄存器):哪些位需要比较,哪些位忽略。0表示必须匹配,1表示忽略。
判断逻辑很简单:(接收到的ID & ~AMR) == (ACR & ~AMR)。说白了,AMR为1的位不参与比较,AMR为0的位必须和ACR一致。
| AMR位 | ACR位 | 接收ID位 | 结果 |
|---|---|---|---|
| 0 | 1 | 1 | 匹配 |
| 0 | 1 | 0 | 不匹配 |
| 1 | 任意 | 任意 | 匹配(忽略) |
举个例子,我想接收ID范围为0x100~0x10F的报文(标准帧,11位ID):
// 期望ID: 0x100 ~ 0x10F
// 二进制: 001 0000 0000 ~ 001 0000 1111
// 高3位固定为001,低8位任意
ACR = 0x100; // 001 0000 0000
AMR = 0x0FF; // 000 1111 1111(低9位忽略)
另外,CMS32通常有多个滤波器组(比如2组或4组)。你可以把不同ID范围分配给不同组,实现更灵活的过滤策略。比如一组收控制指令(ID=0x100),另一组收状态请求(ID=0x200~0x2FF)。
3.4 知识结构总览
下面这张图把初始化流程串起来了。你照着这个顺序走,基本不会漏。
嗯,到这里,CAN模块初始化的三个核心环节就讲完了。模式选择决定了你的调试策略,位时序决定了通信的可靠性,滤波器决定了数据的选择性。这三步配好了,CAN通信的基础就稳了。
下次你拿到一个新板子,按这个顺序走一遍,心里就有谱了。如果遇到问题,回头看看是不是哪一步漏了——我敢说,八成的问题都出在这三步里。