资讯动态

MCP25625中文手册精讲:SPI转CAN控制器与收发器配置避坑指南

发布时间:2026/10/15 17:38:00 来源:尧图企业网站定制
简介MCP25625 中文文档是一份面向嵌入式开发者和汽车电子工程师的完整芯片技术资料系统讲解 Microchip MCP25625 这一集成 CAN 控制器与 CAN 收发器的解决方案。文档涵盖器件的引脚定义、封装类型、内部框图、典型应用电路与设计注意事项重点介绍如何通过 SPI 接口将 MCP25625 连接到 2.7V5.5V 单片机并满足最高 1 Mbps 的高速 CAN 通信需求。其中详细列出 3 个带优先级发送缓冲区、2 个接收缓冲区、6 个过滤器和 2 个屏蔽器等 CAN 控制器特性同时说明接地故障检测、过压保护、热关断保护以及 IEC61000-4-2 标准 ±8kV ESD 防护等收发器特性对实际硬件选型和电路设计很有参考价值。资源为 1 个 PDF 文件3.2MB已有 980 人学习。整份文档采用中文编译章节结构清晰适合需要快速上手 MCP25625 或进行汽车 CAN 节点设计的工程师作为手册式参考资料。1. MCP25625 中文文档拆解一颗芯片把 CAN 控制器和收发器都装下了拿到这份 MCP25625 中文文档时我最先想确认的不是它能跑多快而是它到底能不能把板上两颗芯片换成一颗。结论是可以而且这颗料把 CAN 2.0B 控制器和高速收发器封装到了一只 28 脚芯片里MCU 只要有 SPI 就能挂上 CAN 总线SPI 时钟最高 10MHzCAN 速率最高 1Mbps数字 I/O 直接兼容 2.7V~5.5V 单片机待机电流典型 10µA温度范围 -40°C~125°C。最典型的去处是汽车电子和工业现场总线尤其是 MCU 不带 CAN 外设、又不想换平台的方案。这篇笔记把手册拆成能直接落地的步骤工作模式切换、报文收发、过滤器配置和几条实测踩坑。2. 工作模式与初始化为什么必须先走配置模式MCP25625 的五种工作模式不是随便切的。第一次上电时芯片自动进入配置模式几乎所有关键寄存器都只能在配置模式下修改如果跳过这一步直接去写发送缓冲区写进去的数据可能根本不会按期望工作。这一章把五种模式的用途、切换机制和初始化顺序拆开讲。2.1 五种工作模式一张表分清该在哪个模式干哪件事手册里列了五种模式配置、正常、休眠、仅监听、环回。模式通过 CANCTRL 寄存器中的 REQOP 字段选择实际生效的模式通过读 CANSTAT 寄存器中的 OPMOD 字段确认。下表按「这个模式能干什么」整理工作模式REQOP 编码典型用途可修改的寄存器配置模式0x04上电初始化、波特率与过滤器设置CNF1~CNF3、TXRTSCTRL、验收过滤寄存器、屏蔽器正常模式0x00标准收发唯一能真正上总线发报文的模式全部可读写但配置类寄存器改动不生效休眠模式0x01低功耗待机SPI 读操作仍可用基本不写仅监听模式0x03总线监听、自动波特率检测接收相关配置环回模式0x02自测内部 TX 到 RX 不回总线接收相关配置上电或复位后芯片自动进入配置模式这是设计上的强制安全措施防止未初始化的节点一上电就往总线上乱发。常见做法是初始化代码先确认当前处于配置模式再开始写 CNF1、CNF2、CNF3 和验收过滤器最后切回正常模式。如果上来就写很多寄存器写入会静默失败读回来还是默认值这种问题用示波器查半天都查不出原因——寄存器写入根本没生效。2.2 初始化必须先进配置模式寄存器写入顺序先给一套可直接套用的 SPI 读写函数和模式切换封装。SPI 指令沿用 MCP2515 系列兼容定义0x02 写寄存器、0x03 读寄存器、0x05 位修改、0x80 系列为请求发送命令。/* 寄存器地址宏按手册存储器映射表填写示例沿用同系列惯例值 */ #define CANCTRL 0x0F #define CANSTAT 0x0E #define CNF1 0x2A #define CNF2 0x29 #define CNF3 0x28 #define MODE_CONFIG 0x04 #define MODE_NORMAL 0x00 #define MODE_SLEEP 0x01 #define MODE_LOOPBACK 0x02 #define MODE_LISTEN 0x03 void mcp25625_write(uint8_t addr, uint8_t val) { cs_low(); spi_xfer(0x02); /* 写命令 */ spi_xfer(addr); spi_xfer(val); cs_high(); } uint8_t mcp25625_read(uint8_t addr) { uint8_t val; cs_low(); spi_xfer(0x03); /* 读命令 */ spi_xfer(addr); val spi_xfer(0x00); cs_high(); return val; } void mcp25625_set_mode(uint8_t mode) { uint8_t reg mcp25625_read(CANCTRL); reg (reg 0x8F) | (mode 4); /* 保留 bit7 和 bit3:0写 REQOP 到 bit6:4 */ mcp25625_write(CANCTRL, reg); }写命令的时序是CS 拉低 → 发指令字节 → 发寄存器地址 → 发数据 → CS 拉高。MCP25625 支持 SPI 模式 0,0 和 1,1也就是 CPOL0/CPHA0 或 CPOL1/CPHA1MCU 侧 SPI 主模式配置成这两种之一即可。REQOP 字段位于 CANCTRL 的 bit6:4(reg 0x8F) | (mode 4)这行的作用是先把 bit7 和低四位原样保留再写入新模式编码避免把同寄存器的其他位冲掉。初始化顺序分五步上电进配置模式 → 写波特率寄存器 → 写验收过滤器 → 写中断使能 → 切回正常模式并验证。下面是一段带轮询确认的初始化函数void mcp25625_init(void) { /* 1. 确保处于配置模式 */ mcp25625_set_mode(MODE_CONFIG); while ((mcp25625_read(CANSTAT) 0xE0) ! (MODE_CONFIG 5)) ; /* OPMOD 在 CANSTAT bit7:5必须读到配置模式才继续 */ /* 2. 波特率配置16MHz 晶振、125kbps 的常用参数 */ mcp25625_write(CNF1, 0x47); /* BRP7SJW1 */ mcp25625_write(CNF2, 0x98); /* 传播段1TQ相位段14TQ */ mcp25625_write(CNF3, 0x01); /* 相位段22TQ采样点约75% */ /* 3. 过滤器、中断使能按业务配置此处略 */ /* 4. 切回正常模式并验证 */ mcp25625_set_mode(MODE_NORMAL); while ((mcp25625_read(CANSTAT) 0xE0) ! (MODE_NORMAL 5)) ; }这套参数对应波特率公式TQ 2×(BRP1)/FOSC 2×8/16MHz 1µs位时间 同步段1 传播段1 相位段1 的4 相位段2 的2 8TQ采样点落在 75%是 125kbps 的稳妥起点。如果总线拓扑较长或节点多优先把传播段调大采样点往后拉到 80%~85% 更抗干扰。2.3 模式切换不是即时的REQOP 与 OPMOD 的双向确认手册里有一句容易被忽略的话切换模式时在所有等待发送的报文发送完成前模式不会发生实际变化。这意味着 REQOP 写完只是「请求」不能立刻假设模式已经切过去。尤其是从正常模式切到配置模式时如果 TXB 里还压着待发报文切换会被延后。正确的做法是写 REQOP 后轮询 CANSTAT 的 OPMOD 字段确认读到目标编码才算切换完成。上面初始化代码里的两个 while 循环就是干这件事的。第二个坑是配置模式下修改 CNF1~CNF3 或过滤器寄存器后必须切回正常模式才生效但切回前记得把不需要的中断标志清一遍避免残留的 RXnIF 或 TXnIF 在正常模式下立刻触发一次假中断。3. 报文发送三缓冲区的装载顺序与三种启动方式MCP25625 给了三个发送缓冲区 TXB0~TXB2每个 14 字节。发送逻辑不复杂但装载顺序、优先级仲裁和启动方式有不少细节搞错了会出现「寄存器明明写了报文就是不上总线」的玄学问题。3.1 发送缓冲区布局14 字节里装了什么每个发送缓冲区在存储器映射里占 14 字节第一字节是控制寄存器接着 5 字节标识符仲裁区最后 8 字节数据偏移名称作用0TXBnCTRLTXREQ 发送请求位、TXP 优先级位、ABTF/MLOA/TXERR 状态位1TXBnSIDH标准标识符高 8 位2TXBnSIDL标准标识符低 3 位 EXIDE 扩展帧使能 扩展标识符高 3 位3TXBnEID8扩展标识符中间 8 位4TXBnEID0扩展标识符低 8 位5TXBnDLC数据长度码bit3:0 有效6~13TXBnD0~D78 个数据字节手册明确说至少要装载 TXBnSIDH、TXBnSIDL 和 TXBnDLC有数据字节还要写 TXBnD0~Dm用扩展帧要装 TXBnEID8、TXBnEID0并把 TXBnSIDL 的 EXIDE 位置 1。我一般建议无论是否用扩展帧把 5 字节标识符区全部写一遍避免烧录器里残留的旧数据影响仲裁字段。3.2 发送优先级TXP 位和缓冲区编号的仲裁规则三个发送缓冲区同时挂起时谁先发由两个因素决定。第一是 TXP1:0 优先级位11 最高00 最低。第二是缓冲区编号优先级相同时编号大的先发即 TXB2 TXB1 TXB0。这个规则与 CAN 协议本身的 ID 仲裁没有必然联系纯粹是控制器内部的排队顺序。实际工程里我习惯把周期报文放在 TXB0、突发报文放在 TXB2并给突发报文 TXP11周期报文 TXP01。这样既保证关键报文优先抢到发送机会又不会让周期报文饿死。3.3 三种启动发送的方式写寄存器、RTS 命令、引脚下降沿装载完缓冲区后把 TXBnCTRL 的 TXREQ 位置 1 即可标记「准备发送」。真正上总线还要等控制器检测到总线空闲所以 TXREQ 置位不等于立马上总线。启动发送有三种方式方式操作适用场景SPI 写寄存器写 TXBnCTRLTXREQ 与 TXP 一次写入常规发送最常用RTS 命令发 0x80/TXB0、0x81/TXB1、0x82/TXB20x87 全部减少 SPI 开销适合快速连续发送TXnRTS 引脚对应引脚下降沿锁存 TXREQ硬件触发可直连 RXnBF 做自动应答TXnRTS 引脚内部有标称 100kΩ 上拉设计上可以直接连接到 RXnBF 引脚接收缓冲区满引脚拉低后自动触发发送请求做成简单的请求-应答链路不需要 MCU 参与。RTS 命令是手册强调的「减少 SPI 开销」手段发一帧数据从三次 SPI 事务压缩到一次对高波特率的实时性有明显帮助。发送流程的时序是TXREQ 置 1 后若报文已开始发送但遇错TXERR 置位若仲裁丢失MLOA 置位发送成功后 TXREQ 自动清零CANINTF 的 TXnIF 置 1。如果报文发送失败TXREQ 会保持置 1 并等待自动重传非单触发模式下这是排查「发不出去」的关键状态位。void mcp25625_send_std_frame(uint16_t id, uint8_t dlc, const uint8_t *data) { /* 等待 TXB0 空闲TXREQ 位仍为 1 说明上次发送未完成 */ while (mcp25625_read(TXB0CTRL) 0x08) ; /* 装载标准标识符 */ mcp25625_write(TXB0SIDH, (uint8_t)(id 3)); /* ID 高 8 位 */ mcp25625_write(TXB0SIDL, (uint8_t)((id 0x07) 5)); /* ID 低 3 位 */ mcp25625_write(TXB0DLC, dlc 0x0F); /* 装载数据 */ for (uint8_t i 0; i dlc; i) { mcp25625_write(TXB0D0 i, data[i]); } /* TXREQ1 启动发送TXP11 最高优先级 */ mcp25625_write(TXB0CTRL, 0x08 | 0x03); }这段代码里TXB0CTRL 的 0x08 是 TXREQ 位0x03 是 TXP11。先轮询 TXREQ 清零再装载是为了避免上一帧还没发完就把缓冲区覆盖掉。标准帧 ID 装载时id 3放 SIDH(id 0x07) 5放 SIDL 的 bit7:5——这个移位很多人会写错低 3 位必须移到高 3 位因为 SIDL 的 bit7:5 才是标准 ID 的低 3 位。3.4 单触发模式与中止发送时隙敏感系统的两个开关默认情况下报文发送失败会自动重传普通总线够用但确定性系统如 TTCAN要求每个时隙只发一次这时要置位 CANCTRL 的 OSM 位进入单触发模式。单触发模式下一旦仲裁丢失或错误帧中断报文只尝试一次TXREQ 清零不会再把总线搞得乱糟糟。中止发送有两个层级。单缓冲区中止把对应 TXBnCTRL 的 TXREQ 清零全局中止置位 CANCTRL 的 ABAT 位。注意只有用 ABAT 全局中止且报文已经开始发送但未成功时ABTF 标志才会置 1。直接用 TXREQ 清零中止不会置 ABTF别拿这个位去判断单帧中止是否生效。4. 报文接收与验收过滤六个过滤器和两个屏蔽器怎么分配接收侧的资源是固定的两个接收缓冲区 RXB0/RXB1、六条验收过滤器 RXF0~RXF5、两个屏蔽器 RXM0/RXM1。分配不对会出现「ID 明明匹配却收不到」或者「什么报文都往缓冲区里塞」这两类极端。4.1 接收缓冲区与过滤器分配RXB0/RXB1 不对称的资源池RXB0 是优先级高的缓冲区绑定了 1 个屏蔽器 RXM0 和 2 条过滤器 RXF0、RXF1RXB1 绑定了 1 个屏蔽器 RXM1 和 4 条过滤器 RXF2~RXF5。报文从总线上过来先进 MAB报文组合缓冲区然后按 RXB0 的过滤条件先匹配匹配上了载入 RXB0RXB0 没匹配上再用 RXB1 的条件过滤。MAB 始终在收总线上下一条报文相当于第三个隐藏接收缓冲区。报文载入后CANINTF 里对应的 RXnIF 置 1。这个位必须由 MCU 清零它有正向锁定功能——不清零的话新报文即使满足过滤器条件也进不了缓冲区这是接收「丢帧」最常见的原因之一。4.2 屏蔽器与过滤器的匹配逻辑核对每一位的 AND 关系屏蔽器和过滤器配合工作的逻辑可以压成一句话屏蔽器某位为 1则该位必须与过滤器对应位一致屏蔽器某位为 0则该位不检查。换句话说屏蔽器决定「检查哪些位」过滤器决定「这些位必须是什么值」。工程上最常见的错误是只配了过滤器没配屏蔽器默认屏蔽器可能带了上次配置的残留值导致过滤范围莫名其妙变宽或变窄。我每次初始化都会把关联的屏蔽器一并写全不指望默认值。/* 配置 RXB0 接收单个标准帧 ID其他全屏蔽 */ void mcp25625_setup_rxb0_filter(uint16_t accept_id) { /* RXM0标准 ID 11 位全检查扩展 ID 和数据字节过滤位不检查 */ mcp25625_write(RXM0SIDH, 0xFF); /* 检查 ID 高 8 位 */ mcp25625_write(RXM0SIDL, 0xE0); /* 检查 ID 低 3 位 */ mcp25625_write(RXM0EID8, 0x00); /* 不检查扩展 ID */ mcp25625_write(RXM0EID0, 0x00); mcp25625_write(RXM0DLC, 0x00); /* 不检查数据过滤 */ /* RXF0填入期望接收的 ID */ mcp25625_write(RXF0SIDH, (uint8_t)(accept_id 3)); mcp25625_write(RXF0SIDL, (uint8_t)((accept_id 0x07) 5)); mcp25625_write(RXF0EID8, 0x00); mcp25625_write(RXF0EID0, 0x00); mcp25625_write(RXF0DLC, 0x00); /* RXB0CTRLRXM00 使用过滤器正常接收 */ mcp25625_write(RXB0CTRL, 0x00); }RXM0SIDH 写 0xFF 表示标识符高 8 位全部参与匹配RXM0SIDL 写 0xE0 表示低 3 位参与匹配两段合起来就是完整的 11 位标准 ID。RXF0 侧填入目标 ID低位同样要左移到 bit7:5。最后 RXB0CTRL 的 RXM00代表走正常过滤器接收流程。如果只想收一个 ID这条链路够了要收多个 ID就把 RXF1 也配上两条过滤器是「或」的关系。4.3 数据字节过滤标准帧也能过滤数据前两字节这是 MCP25625 比较容易被忽略的能力。接收标准数据帧时控制器会把通常用于扩展标识符的那 16 位屏蔽器和过滤器自动映射到数据字段的前 16 位也就是数据字节 0 和字节 1。这意味着不但可以按 ID 过滤还能按数据头两个字节过滤。典型场景是 DeviceNet 这类高层协议报文类型含义写在数据前两字节里。有了数据字节过滤MCU 不用把所有报文都收进来再软件判断硬件直接就把不关心的报文挡在外面。配置方法和 ID 过滤一样只是把 RXMnDLC 和 RXFnDLC 这两个字节当作数据前两字节的过滤器来写。4.4 滚存与 RXM 特殊模式溢出兜底和全收调试RXB0CTRL 的 BUKT 位控制滚存RXB0 已有一条报文未处理、又来一条新报文时新报文不看 RXB1 的过滤条件直接进 RXB1避免溢出标志 RX0OVR 置位。这是双缓冲区方案里性价比很高的兜底机制我建议默认打开。RXBnCTRL 的 RXM1:0 位提供三种特殊接收模式01 只收标准帧、10 只收扩展帧、11 接收所有报文包括错误帧。RXM11 模式下错误帧之前 MAB 里组合好的部分也会被载入缓冲区调试时很有用但手册也提醒这个模式一般不在实际系统中用。如果发现节点莫名其妙收到一堆 CRC 错误的报文先检查是不是调试完忘了把 RXM 从 11 切回 00。5. 避坑MCP25625 最容易翻车的五个地方这颗料整体皮实但有几个坑是项目里反复踩过的。按「现象 → 原因 → 解决」的顺序记录都是血泪经验。5.1 现象SPI 读写正常CAN 总线一帧都发不出去原因VDDA 没接 5V。MCP25625 有两套电源VDD 给控制器供电2.7V~5.5VVDDA 给收发器供电4.5V~5.5V。SPI 寄存器能读能写只能说明控制器部分活着收发器没供电自然推不动总线。另外 TXD/RXD 必须外部飞线连接到 TXCAN/RXCAN集成方案不代表这两个引脚在内部短接。解决VDDA 接 5VVDD 和 VIO 接 MCU 电源TXD→TXCAN、RXD→RXCAN 短接RESET 经 10kΩ 上拉到 VDD电源引脚各并 0.1µF 去耦电容。5.2 现象写了 REQOP 切模式读寄存器发现没切换成功原因模式切换不是瞬时的。如果当前有报文在队列里等待发送必须等这些报文处理完模式才真正切换而且 REQOP 只是请求位实际状态要看 OPMOD。很多初始化程序只写不读自然不知道模式还卡在上一状态。解决REQOP 写入后轮询 CANSTAT 的 OPMOD 字段确认目标模式。初始化函数里那两个 while 循环不能省工程上每次切换都要验证别拿延时硬扛。5.3 现象休眠唤醒后收不到第一帧过一阵又恢复正常原因休眠时内部振荡器停振唤醒后有 128 TOSC 的起振时间OST。在这期间到达的报文全部被忽略包括那个把节点唤醒的报文本身。另外收发器的唤醒滤波器使能时RXD 输出是延迟后的总线表示MCU 如果还按正常时序去读拿到的电平是滞后的。解决唤醒中断触发后先等 OST 窗口过去用定时器或简单延时再把 STBY 拉低让收发器回正常模式最后让控制器回正常模式。手册特别强调唤醒后控制器初始处于仅监听模式必须手动把两个部分都切回正常节点才能重新参与总线通信。5.4 现象标准帧过滤怎么配都不生效ID 匹配了还收到杂帧原因标准帧场景下扩展 ID 相关的 16 位屏蔽器/过滤器会自动映射到数据字节 0 和 1。很多人只写了 SIDH/SIDL 两个字节RXFnDLC 和 RXMnDLC 里残留了上电默认值或历史写入值导致过滤器实际在按错误的数据字节条件匹配。解决每个过滤器和屏蔽器都完整写 5 个字节而不是只写前两个。标准帧应用里把后三个字节统一清 0再按需配置数据字节过滤。这条也解释了为什么「我只配了一个 ID什么乱七八糟的报文都能进来」。5.5 现象节点跑在总线上错误计数器飙升甚至进入 BusOff原因大概率是调试环回或监听模式后RXM 位留在 11接收所有报文含错误帧或者 TXnRTS 引脚悬空受到干扰下降沿误锁存了 TXREQ。TXnRTS 内部虽有 100kΩ 上拉但强干扰环境下仍不够可靠。解决调试完逐项检查 RXBnCTRL 的 RXM 位是否回到 00BFPCTRL 引脚模式是否复位TXnRTS 在正式板卡上外部加上拉或将其配置为标准数字输入。上电进入正常模式前把 CANINTF 所有标志清一遍避免历史中断在模式切换瞬间触发误动作。6. 环回模式自测不接总线把收发链路跑通再上板环回模式是我拿到新板子时第一个跑的功能因为它的性价比最高不需要 CAN 总线、不需要对端节点、不需要 120Ω 终端电阻芯片内部把发送缓冲区的报文直接转给接收缓冲区ACK 位被忽略TXCAN 引脚保持隐性完全不碰外部物理层。自测步骤分四步。第一步REQOP 写入 0x02 切环回模式轮询 OPMOD 确认。第二步把 RXM0 和 RXM1 的 5 个字节全部清 0屏蔽器清零等于不过滤任何位任何报文都能进接收缓冲区——这是手册推荐的全收配置。第三步用普通发送函数发一帧已知数据。第四步轮询 CANINTF 的 RX0IF 或直接查接收缓冲区把数据读回来逐字节比对。uint8_t mcp25625_loopback_test(void) { uint8_t tx_data[8] {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; uint8_t rx_data[8]; uint8_t i; /* 切环回模式并确认 */ mcp25625_set_mode(MODE_LOOPBACK); while ((mcp25625_read(CANSTAT) 0xE0) ! (MODE_LOOPBACK 5)) ; /* 屏蔽器全零接收所有报文 */ for (i 0; i 5; i) { mcp25625_write(RXM0 i, 0x00); mcp25625_write(RXM1 i, 0x00); } /* 发一帧 8 字节标准帧 */ mcp25625_send_std_frame(0x123, 8, tx_data); /* 等待 RX0IF 置位超时则返回失败 */ uint32_t timeout 10000; while (!(mcp25625_read(CANINTF) 0x01)) { if (--timeout 0) return 0; } /* 从 RXB0 读回数据并比对 */ for (i 0; i 8; i) { rx_data[i] mcp25625_read(RXB0D0 i); if (rx_data[i] ! tx_data[i]) return 0; } /* 清中断为下一轮测试准备 */ mcp25625_write(CANINTF, 0x00); /* 回到正常模式 */ mcp25625_set_mode(MODE_NORMAL); return 1; }这段测试跑通了能证明几件事SPI 读写链路是通的、发送缓冲区的装载逻辑正确、TXREQ 置位和发送流程正常、MAB 到 RXB0 的接收路径完整、中断标志位的设置和清除没有问题。这些恰是后续所有 CAN 应用的地基。环回模式里过滤器可以全开真正按业务配过滤器的验证要等上了总线再测因为环回模式下没有真实的 ID 仲裁和错误帧逻辑。从那以后我每次焊完板子都强制走一遍环回自测不接总线先确认 SPI 和寄存器链路是通的再碰物理层这套流程帮我省下的找错时间远比跑这一遍花掉的多。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑