I2C总线从物理层到调试实战:协议细节与常见故障排查

发布时间:2026/10/13 17:43:25
I2C总线从物理层到调试实战:协议细节与常见故障排查
做嵌入式开发这些年我最常遇到的现象就是大家都在用库函数调i2c_write()一旦通信失败就只能对着波形发呆。I2C 协议在手册里就那么几页看起来非常简单——两根线、一个地址、一串数据。但真正动手排查时上拉电阻、电平转换、时钟拉伸、多主仲裁、ACK/NACK 这些细节全都会冒出来。这篇文章我想把 I2C 从物理层、时序、仲裁到调试实战完整拆开讲一遍让需要读芯片手册手写驱动、或者正在排查通信故障的朋友能有一套可以照着做的思路。我默认读者已经会用某个开发板的 I2C 外设但不一定清楚协议内部的运行机制。这篇文章不会只讲概念会结合我在模拟项目X里调试传感器、存储器、电源管理芯片时踩过的坑尽量把“为什么这样做”和“实际该怎样排查”都说清楚。1. 为什么两根线就能完成可靠的板级通信1.1 一根时钟一根数据怎么实现双向交互I2C 全称是 Inter-Integrated Circuit它只使用两根信号线SCL 提供时钟SDA 传输数据。和 SPI 不同I2C 不是“一主多从片选”模型而是共享总线加地址寻址。每个从设备有一个地址主机发起传输时先把地址放到总线上从设备收到地址并匹配成功后会在第九个时钟周期拉低 SDA 作为应答信号ACK。这个机制有点像打电话你拨号后对方接起来“喂”一声你确认有人在听才开始说正事。很多人第一次接触 I2C 会觉得奇怪只有一根数据线数据怎么双向传输答案是靠“分时复用”。在主机发送数据时从机只是监听当主机读取数据时主机释放 SDA由从机驱动这根数据线主机再逐位采样。也就是说I2C 是半双工通信同一时刻总线上的数据方向只有一个。但正因为同一根线可以双向复用芯片引脚可以省很多PCB 布线也可以做得非常精简。1.2 和 SPI、UART 对比什么时候更适合选 I2C这是项目选型时要先想清楚的问题。UART 是异步点对点通信两根线各管一个方向全双工但没法在一条总线上挂多个设备。SPI 速度快、全双工但每加一个从设备就要多一根片选线设备一多引脚占用就非常恐怖。I2C 的最大优势就是“总线化”只要地址不冲突几十个设备可以挂在同一组 SCL/SDA 上。我曾在一个模拟项目X里同时挂了 8 个 I2C 设备包括温湿度传感器、气压计、EEPROM、IO 扩展芯片整个总线只占了两个引脚。如果换成 SPI光片选就要 8 根线PCB 走线会显得非常紧张。当然I2C 也有代价速度上限远低于 SPI半双工也限制了大流量场景。一般来说温度、湿度、气压这类变化率不高的传感器I2C 完全够用如果是音频流、高速 ADC 采集我就会直接转向 SPI 或并行接口。2. 物理层细节上拉电阻、总线电容与电平转换这一章最容易被人忽略但实际通信不稳定八成出在物理层。2.1 为什么 I2C 引脚必须是开漏结构I2C 的 SCL 和 SDA 引脚都是开漏开集结构只能主动拉低不能主动拉高。要让信号回到高电平必须依靠外部上拉电阻。这样做有极其重要的原因如果多个设备都能同时输出高电平和低电平一个设备输出高、另一个设备输出低两条输出级就会形成短路电流直接烧毁芯片。开漏加线与逻辑后任何设备都能安全地把总线拉低不会发生电平冲突。你可以把总线想成一个会议室里的共用麦克风线所有人都可以把这条线拉低表示“我在说话”但没人能强行把它推高只有靠一个上拉“弹簧”把它恢复回高电平。这样大家都不会打架。2.2 上拉电阻怎么选计算而不是凭经验上拉电阻不是随便选一个 4.7kΩ 就完事。阻值太小总线拉低时灌入电流太大可能超过芯片的Iol限制还会增大功耗阻值太大总线电容充电太慢上升沿变缓高速模式下信号失真。I2C 规范对上升时间有要求标准模式是 1000ns快速模式是 300ns。上升时间近似可以用这个公式估算tr 0.8473 * Rp * Cbus其中Rp是上拉电阻Cbus是总线总电容。电阻最大值要满足上升时间限制最小值要满足器件输出低电平能力Rp(max) tr / (0.8473 * Cbus) Rp(min) (Vcc - Vol(max)) / Iol(max)举个例子。假设供电 3.3V某个器件手册上Vol(max)0.4VIol3mA那电阻不能小于(3.3-0.4)/0.003 ≈ 966Ω。再假设总线电容 200pF快速模式要求上升时间小于 300ns上限就是300 / (0.8473 * 200e-12) ≈ 1.77kΩ。取整后可以用 1.5kΩ 到 1.8kΩ。如果只是标准模式 100kHz上限可以放宽到 5.9kΩ这时取 4.7kΩ 是比较稳妥的选择。实际调试时我会用两个经验值作参考板内短走线、标准模式用 10kΩ快速模式或线上挂的设备较多用 2.2kΩ 到 4.7kΩ。如果遇到上升沿明显变缓我会优先降低电阻而不是盲目提高通信速度。2.3 总线电容、线缆长度和连接器距离I2C 规范一般建议总线电容不要超过 400pF。每根走线、每个引脚、每段连接器都会贡献电容设备多了之后电容会叠加。这也是为什么板内 I2C 很正常、一旦通过排线引到机箱另一端就频繁出错——排线和连接器大大增加了总线电容。要判断是不是电容问题最直接的办法是看示波器上的 SDA/SCL 上升沿是否呈明显圆弧状如果上升时间已经接近该模式下规范允许的极限就意味着余量不足了。此时可以把速度降回标准模式或者换更小的上拉电阻。长线缆场景我一般建议把速率降到 100kHz 以下并且在从设备端加上合适的上拉电阻两边共同上拉来减小等效阻抗。2.4 不同电压域设备混接时的双向电平转换现在很多传感器是 1.8V 供电主控却是 3.3V直接在总线上混接是非法的因为器件的钳位二极管会把高电平钳到电源电压附近轻则逻辑混乱重则损坏器件。常见的 I2C 双向电平转换方案是专用电平转换芯片或者用单个 N-MOS 管搭的经典电路两边各有一个上拉电阻MOS 管的源极接低压侧漏极接高压侧。当任一侧把总线拉低时MOS 管沟道导通把另一侧也拉低当两侧都释放时各自的上拉电阻把电平恢复到自己电源轨的高电平。这个电路利用开漏特性实现了方向自动切换在 I2C 这种低频总线上非常稳定。我在调试某块混合电压板卡时曾经发现这样的现象单独读 3.3V 侧的传感器没有问题读 1.8V 侧设备时偶尔数据全0xFF。后来用示波器对比两侧波形才发现低压侧上拉电阻取值偏大上升沿过缓逻辑分析仪有时采不到正确电平。把低压侧上拉电阻从 10kΩ 改成 4.7kΩ 后问题彻底消失。所以电平转换电路设计完成后一定要分别检查两侧的上升沿波形而不是只看有没有高电平。3. 时序拆解从 Start 到 Stop每一个沿都有严格规矩3.1 Start、Stop 与数据有效窗口I2C 的时序精髓可以用三句话概括SCL 高电平期间SDA 从高到低的变化表示 Start 条件。SCL 高电平期间SDA 从低到高的变化表示 Stop 条件。SCL 高电平期间SDA 上的电平必须是稳定的数据只能在 SCL 低电平期间变化。数据有效窗口这点特别重要。有时候 GPIO 模拟实现里如果用中断或延迟不当SDA 在 SCL 还没拉低时就变了从设备就会采到错误数据。我见过很多驱动代码调试不出来最后发现就是在写sda之后没有等待足够时间就把scl拉高了导致建立时间不足。I2C 规范对建立时间有明确要求标准模式至少 250ns快速模式至少 100ns虽然大多数器件留有余量但模拟实现时我还是会额外加一点延时宁慢勿快。3.2 一次完整写操作的字节流一次写入通常包含这些阶段主机发送 Start。主机发送从设备地址共 7 位最后一位是写标志0。从设备匹配地址后在第 9 个时钟拉低 SDA回复 ACK。主机发送寄存器地址或命令字节。从设备继续 ACK。主机发送要写入的数据可能是一个或连续多个字节。全部发完后主机发送 Stop。这里最容易出错的是地址拼接。芯片手册里常给一个 8 位写地址比如0xA0它其实就是 7 位地址0x50左移一位后在最低位补0。如果不查手册直接写0x50总线上的地址就是0x28从设备自然没有响应。我习惯在代码里把地址明确写成addr 1 | rw_bit这样可读性更好也不容易搞混。3.3 一次完整读操作的 Restart 用法读操作比写操作多一个环节。要从某个寄存器读取数据先要告诉从设备“我想读哪个寄存器”然后再切换成读模式。标准流程是Start 从设备地址 写标志。写寄存器地址ACK。再发一个 Repeat Start重复起始条件不发送 Stop。Start 从设备地址 读标志。从设备 ACK 后开始输出数据。主机读完最后一个字节后发送 NACK然后发送 Stop。为什么中间不能直接发 Stop 再重新 Start虽然功能上很多器件也能接受但 I2C 规范给出了 Repeat Start 正是为了在处理读切换时保持总线所有权避免释放总线的这段时间内被其他主机抢占。话虽如此实际驱动里很多硬件控制器也支持在同一个传输向量中配置读写段所以不必自己手动拼时序。3.4 ACK 与 NACK 的约定ACK 是第 9 个时钟周期中接收方将 SDA 拉低。发送方在第 9 个时钟的高电平期间采样 SDA读到低电平表示接收方已收到字节。NACK 有两种常见场景一是从设备地址不匹配或者从设备忙碌无法接收二是主机作为接收方在希望结束数据读取时最后一个字节回 NACK 释放总线。你要记住一个对应关系主机发送数据时是等着从机回 ACK主机读取数据时是主机自己在每读完一个字节后发出 ACK直到最后一个字节前发出 NACK。这个方向经常把人绕晕尤其是在用示波器看波形时。3.5 时钟拉伸从设备“拖住”主机等待处理时钟拉伸是很多驱动卡死的元凶。I2C 的老规矩是时钟信号本来应该由主机产生但允许从设备在需要处理数据时主动拉低 SCL把时钟“按住”直到它准备好再释放。这样主机检测到 SCL 一直为低就必须等待不能强行继续。有些环境传感器发起测量后需要几十毫秒才能产生结果在读取过程中就会进行明显的时钟拉伸。如果驱动库做了超时处理那没问题如果超时设置得太短或者等待循环写得不对就会误报总线错误。我的做法是所有 I2C 驱动都设置一个“等待 SCL 释放”的超时通常 20ms 到 50ms超过这个时间才认为总线异常。千万不要在等待 SCL 变高的循环里不加超时条件否则某个设备故障后整个系统会彻底卡死。3.6 标准、快速、高速模式怎么选I2C 在发展过程中定义了多个速度等级最常用的是标准模式 100kHz 和快速模式 400kHz还有快速模式 1MHz、高速模式 3.4MHz。高速模式需要主机先发高速握手码不是简单把时钟调高就能用的这一点要注意。选速度不是越快越好。长走线、多设备、宽电平范围都会限制速率。我一般先把新设备在标准模式下调通确认波形干净后再逐级提速。如果 400kHz 时数据出错我会用示波器看上升沿和建立时间而不是继续往上加。4. 多主仲裁与总线秩序为什么 I2C 不太容易“打架”4.1 线与逻辑与逐位仲裁理论上 I2C 支持多主机也就是总线上有多个控制器都能发起传输。某个主机 A 在发送数据的同时也在采样 SDA如果它发送的是高电平但发现 SDA 被拉低说明另一个主机 B 正在发送低电平那么 A 就输了仲裁立刻停止发送转入监听。这就是逐位仲裁利用了开漏结构与逻辑。这个机制和以太网的冲突检测有点像但它不需要随机退避因为仲裁是逐位进行的获胜的那个主机可以无缝继续自己的传输不会破坏已经进行的通信。这也意味着不同主机之间的数据传输不会互相干扰总线出现“两个设备同时传输导致乱码”的可能性其实很低。4.2 时钟同步以最慢者为准多主机同时工作时SCL 也会被多个主机驱动。因为 SCL 也是线与所以只要任何一个主机将 SCL 拉低整条总线就是低电平当所有主机都释放 SCL 时总线上才会恢复高电平。结果就是多个主机的时钟会“合并”成一个较慢的时钟低电平时间是所有主机中最长者高电平时间是所有主机中最早释放者。这个特性偶尔会给调试制造迷惑示波器上看到的 SCL 频率并不是某个主机设置的频率而是多个主机“协商”出的结果。如果总线上多挂了一个开发板而那个开发板用极慢的软件时钟源也在 I2C 总线上跑所有通信都会被拖慢。遇到这种情况先断开疑似多主的设备再重新测时钟频率能节省不少排查时间。4.3 多主场景下软件需要避开的雷虽然协议支持仲裁但很多实际使用的硬件 I2C 控制器并不完整支持多主仲裁或者只支持自己独占总线。这时如果软件在多个任务里同时发起 I2C 操作就会出现竞争。我建议任何用到 I2C 的工程都用一个互斥锁来保护总线访问。即使底层驱动支持 DMA也应在驱动层完成互斥把“传输完成”“错误处理”等状态都封装进去。这套机制比指望硬件仲裁可靠得多也能让代码在不同项目间复用。特别是含有 RTOS 的项目多个任务同时读同一个传感器没有互斥的话日志里就会出现各种莫名其妙的总线错误。5. 从零写一个最小 I2C Master 驱动两种实现思路5.1 什么时候真正需要 GPIO 模拟很多项目直接用硬件 I2C 外设就够了但以下几种场景我会选择 GPIO 模拟主控没有硬件 I2C 控制器或者控制器数量不够。需要把 I2C 引脚映射到任意 GPIO而不是固定引脚。连接的从设备时序非常特殊需要精确控制每个沿。在底层驱动还没起来时先用 GPIO 模拟跑通硬件验证。GPIO 模拟的代价是占用 CPU、无法硬件仲裁、延迟不稳定但它能帮你把协议的每个字节都看个透彻。缺点也很明显如果系统里有高优先级中断打断时序就可能产生不符合规范的波形。所以量产项目我一般还是优先使用硬件控制器GPIO 模拟用于测试和验证。5.2 模拟实现的时序骨架核心就两个函数拉高/拉低 SCL 和 SDA以及一个半周期延时。半周期延时的时间决定了总线的位速率假设目标 100kHz半个周期就是 5μs。下面给出一段用 C 描述的常见实现骨架不绑定具体平台核心逻辑可以直接迁移static void i2c_delay_half_period(void) { // 按目标速率和主频调整延时 for (volatile int i 0; i DELAY_LOOP; i) ; } static void i2c_start(void) { scl_high(); sda_high(); i2c_delay_half_period(); sda_low(); /* SCL 高电平期间SDA 下降沿表示 Start */ i2c_delay_half_period(); scl_low(); } static void i2c_stop(void) { scl_low(); sda_low(); i2c_delay_half_period(); scl_high(); i2c_delay_half_period(); sda_high(); /* SCL 高电平期间SDA 上升沿表示 Stop */ } static void i2c_send_bit(uint8_t bit) { if (bit) { sda_high(); } else { sda_low(); } i2c_delay_half_period(); scl_high(); i2c_delay_half_period(); scl_low(); i2c_delay_half_period(); } static uint8_t i2c_read_bit(void) { sda_input_mode(); /* 释放 SDA交给从设备驱动 */ i2c_delay_half_period(); scl_high(); i2c_delay_half_period(); uint8_t bit sda_read(); scl_low(); i2c_delay_half_period(); return bit; }写一字节就是循环 8 次发送位然后在第 9 个时钟里检测 ACK读一字节就是循环 8 次读取位然后根据参数决定发 ACK 还是 NACK。要注意的是发送数据前sda要设为输出模式读取前要切换为输入模式否则 GPIO 驱动能力互相冲突数据会变成恒低。5.3 硬件外设的配置要点如果使用硬件控制器我一般会重点检查几个配置项引脚复用是否正确、引脚是否配置成开漏模式、外设时钟是否开启、超时中断有没有打开。很多新手半天调不出来最后发现只是引脚复用没配对。硬件控制器通常带有 FIFO 和 DMA可以提高吞吐量但也会掩盖一些协议细节。比如 DMA 传输模式下某个从设备因时钟拉伸长时间拉低 SCL 时如果不处理总线超时中断系统也可能卡死。因此不管用不用 DMA超时和时间戳记录都要保留。5.4 驱动抽象让代码可以跨项目复用成熟的 I2C 驱动应该提供一个传输接口而不是让业务代码直接操作寄存器。我常用的数据结构是分段传输描述符typedef struct { uint16_t addr; /* 7位地址 */ uint8_t *write_buf; uint8_t *read_buf; uint16_t write_len; uint16_t read_len; uint32_t timeout_ms; } i2c_transfer_t;读写逻辑统一封装成i2c_transfer(transfer)函数。不同的芯片只需要实现底层master_xfer上层的传感器驱动可以做到平台无关。这样某款主控的市场寿命结束、切换到新平台时上层代码几乎不用改这才是驱动层该有的设计。6. 调试实录波形、地址、ACK 和隐藏的电平问题这一章是经验和坑的结合尽量按完整排查链路来写。6.1 环境搭建逻辑分析仪不一定够示波器也要上I2C 调试中逻辑分析仪能看到协议帧能解码出地址和数据但没有办法直观反映模拟信号的边沿质量。所以我的习惯是先用逻辑分析仪快速判断通信流程对不对再用示波器观察上升沿、下降沿、建立时间。特别在处理低速环境时逻辑分析仪采样率可以降低但 I2C 边沿过了采样率一样会采出错误结果。如果手头只有双通道示波器就把 CH1 接 SCLCH2 接 SDA触发条件设为 SDA 下降沿。Start 条件必然先下降这样每次通信都会稳定触发再配合时基调整就能看到整帧波形。不要直接接 SDA 高电平触发因为数据变化也会触发看波形会非常凌乱。6.2 故障现象与排查对照表我在实际调试中整理过一张问题对照表先检查哪个、后检查哪个顺序很重要现象优先检查项再检查项从设备完全不响应SCL 有波形SDA 无 ACK地址是否正确7位/8位、左移/读写作、器件供电是否正常地址引脚配置、设备是否处于复位状态读取数据全 0xFF但 ACK 正常SDA 是否正常被从设备驱动、读取期间是否切回输入模式示波器观察 SCL 高电平时 SDA 是否稳定通信时好时坏偶尔卡死上拉电阻阻值、总线电容、线缆长度时钟拉伸超时设置、供电电压跌落多个设备挂上后无法通信地址冲突、总线上有错误电平拉死各设备上拉电阻是否重复导致总阻值过小Stop 条件之后总线仍为低是否有设备故障将 SDA 锁低检查各设备使能状态用 9 个时钟脉冲复位总线这张表不能替代示波器但它能帮你在链路混乱时先锁定一个方向。我在调试时经常发现地址位数搞错是最隐形的问题因为波形上明明有 ACK 阶段只是 ACK 来自其他设备或者因为地址不匹配根本没有 ACK 低电平人眼却容易忽略。6.3 一个具体案例传感器读不到 ID 的排查过程之前调试某国产温湿度传感器时一直读不到设备 ID。初始现象是 SCL 有波形SDA 上能看到 Start但地址阶段之后没有任何 ACK。第一步我确认地址。手册写的是 7 位地址0x76我用的是0x76 1也就是写地址0xEC这看起来没错。第二步示波器看 SDA 在地址阶段的电平发现最后一个数据位之后SDA 一直为高说明确实是 NACK。第三步测量传感器供电引脚3.3V 正常但再测复位引脚发现被拉低传感器一直处在复位态。把该引脚正确配置为高后ACK 正常出现。这个案例想说明一点I2C 没有响应时不要反复怀疑时序先排除最基础的使能、复位、供电问题。很多所谓“通信问题”根因在芯片根本没进入工作状态总线只是被一个不响应的设备“晾着”了。6.4 总线锁死后的复位三板斧如果总线上有设备把 SDA 或 SCL 长期拉低最直接的恢复方式是给相关设备重新上电。但在现场不能断电时我会尝试连续发送 9 个以上时钟脉冲配合 Stop 条件让规范的设备释放总线。操作方法也很简单SCL 保持输出SDA 保持输入手动翻转 SCL 9 次第 9 个时钟时SDA 拉低再释放形成一个 Stop。这个过程能重置大多数从设备的状态机但解决不了物理层故障。如果 9 个时钟之后总线还是低就真得上电复位或者检查是不是某些引脚的推挽输出把总线拉死了。7. 从 I2C 到 SMBus 和 I3C协议家族里的实战差异7.1 SMBus 与 I2C 的区别很多电源管理芯片、电池管理芯片、以及一部分传感器使用 SMBus 协议。SMBus 基于 I2C 的物理层和大多数时序但多了不少硬性要求比如 SMBus 要求任何低电平时间超过 35ms 就判定为超时定义了主机通知协议、警报线、分组错误校验PEC等机制。I2C 本身对这些没有强制约束。实际项目中很多控制器把 SMBus 设备当普通 I2C 设备读写也能顺利工作因为大部分寄存器读写帧格式是一样的。但要注意两点第一如果通信的一方严格实现了 35ms 超时而你的 I2C 驱动里等待时间特别长就可能触发它的超时机制第二SMBus 设备常在启动阶段需要更严格的握手时序直接按照普通 I2C 初始化有时会失败。7.2 时序严格度差异和 PECSMBus 还规定了很多 I2C 没有明确的最小时间例如 SMBus 要求 SCL 低电平时间段最短为 4.7μs高电平最长为 50μs还定义了最小总线自由时间。I2C 标准模式虽然没有规定最大高电平但实际通信中如果你把时钟拉高后一直不拉低SMBus 设备就可能判定超时退出。因此对接 SMBus 设备时不要随意使用 GPIO 模拟里的“暂停”功能来躲延时那可能直接造成设备不响应。PEC 是 SMBus 里非常实用的校验机制它把地址、命令和数据通过多项式计算出一个校验字节放在传输末尾。这样能发现总线传输中偶发的位翻转错误。如果你的驱动支持建议在 SMBus 场景开启 PEC就算不开启至少要知道设备手册可能默认要求 PEC否则会在最后一步莫名收到 NACK。7.3 I3C 带来的变化以及为什么 I2C 仍然不可替代I3C 是 I2C 的现代继任者它保留了 I2C 的基本包络但速率大幅提升支持动态地址、带内中断、热加入等特性。I3C 可以兼容连接传统 I2C 从设备这种“新旧混挂”的能力挺实用。但现实是今天绝大多数传感器、存储器、IO 扩展器仍然是 I2C成本、生态、工具链都非常成熟。I3C 更多出现在高端传感器总线场景。所以做底层驱动时我建议把 I2C 作为必备技能I3C 作为加分项。把 I2C 的物理层行为和时序理解透了转 I3C 会很快反过来直接跳到 I3C 概念往往连基本的上拉电阻取值都判断不了。8. 我固定使用的 I2C 排查清单最后分享一份我自己每次排查 I2C 问题时都会过一遍的清单顺序很重要从物理层到协议层逐级排除用万用表量 SCL 和 SDA 静态电平确认两根线都能被上拉到高电平且不存在对地短路。确认总线上每一个设备的供电、复位、使能引脚状态排除“没上电”“被复位”这类低级问题。确认地址正确。重点关注 7 位地址和 8 位地址的区别以及写/读标志位的拼装。用示波器分别看 Start、地址段、ACK 段、数据段、Stop 段的波形对照数据手册逐位比对。检查上升沿是否过缓如果边沿斜率明显不足调整上拉电阻或者在电路板上就近补一个上拉。确认通信速率没有超出该模式下总线的实际能力。设备数量多、线缆长时优先降速。检查驱动里的超时设置确保等待 SCL 释放和等待 ACK 的逻辑不会造成死循环。软件层面加互斥锁防止多任务并发访问总线。清单看起来很基础但我发现大多数花好几个小时调试不出来的问题最终都落在了前四项里要么是引脚配置不对要么是地址搞错要么是总线上本来就没有合格的电平。等你把物理层全部排除协议层的问题也会更容易暴露出来这时再面对 NACK、时钟拉伸、时序违规就有了清晰的判断依据。I2C 之所以经久不衰是因为它在“简单可靠”和“功能够用”之间找到了平衡点。只要把这两根线上的规则吃透无论换成哪家主控、哪款传感器底层思路都是一样的。如果你正准备接手一个新的 I2C 设备我的建议是先别急着翻驱动库拿出芯片手册的时序图对着示波器把一次完整的读写过程亲眼确认一遍这个习惯比任何现成代码都值钱。