I2C控制器寄存器深度解析:从协议到硬件驱动的实战指南 1. I2C控制器从协议到硬件的深度解析在嵌入式系统开发中I2C总线协议因其简洁的两线制SDA数据线和SCL时钟线和灵活的多主多从架构成为了连接各类传感器、存储器和外设的“血管”。但很多开发者往往停留在调用现成库函数的层面一旦通信异常面对底层寄存器配置便束手无策。今天我们就以德州仪器TI某款处理器的I2C控制器模块为例彻底拆解其核心寄存器的工作原理与配置逻辑。这不仅仅是阅读数据手册更是理解硬件如何将I2C协议规范“翻译”成可编程控制逻辑的过程。无论你是正在调试I2C通信不稳定问题还是希望从零编写一个可靠的I2C驱动掌握这些寄存器级别的细节都能让你从“会用”进阶到“精通”。2. I2C控制器架构与核心寄存器概览一个完整的I2C控制器硬件模块其本质是一个状态机它负责自动处理I2C协议中繁琐的时序、仲裁、应答等底层细节为上层软件CPU提供一个清晰的寄存器接口。软件工程师通过读写这些寄存器来发起传输、配置参数、查询状态而硬件则负责在总线上产生精确的时序波形。TI的这款I2C控制器设计得非常典型其寄存器大致可以分为四类配置类、数据类、状态类和辅助测试类。配置类寄存器如I2C_CON决定了控制器的基础工作模式数据类寄存器如I2C_DATA、I2C_CNT用于存放要传输的数据和数量状态类寄存器如I2C_IRQSTATUS则反馈传输过程中的各种事件辅助类如I2C_SYSTEST主要用于芯片生产和系统级调试。理解这些寄存器的关键在于建立“软件配置”与“硬件行为”的映射关系。例如当你设置I2C_CON寄存器的MST位为1时硬件内部的时钟生成电路便会接管SCL引脚开始输出时钟脉冲当你写入从设备地址到I2C_SA寄存器并置位STT启动位后硬件状态机便会自动完成起始条件、发送地址字节、检测应答这一系列操作。这种分工让CPU得以从低级的位操作中解放出来。在开始逐个击破寄存器细节前我们必须牢记一条贯穿所有操作的“黄金法则”在活跃的传输阶段即从STT位被置1开始到ARDY中断状态位被置起表示传输结束为止绝对不要修改I2C_CON、I2C_OA、I2C_SA、I2C_PSC、I2C_SCLL、I2C_SCLH等关键配置寄存器。硬件正在依据这些寄存器的当前值驱动总线此时修改它们会导致不可预测的行为通常是通信失败或总线锁死。3. 核心配置寄存器I2C_CON深度拆解I2C_CON寄存器是整个I2C控制器的“大脑”和“控制面板”几乎所有全局性的工作模式都由它定义。它是一个32位寄存器但并非所有位都有效。我们按功能分组逐位剖析其作用与配置逻辑。3.1 模块使能与基础模式选择I2C_EN (Bit 15): 模块使能位这是控制器的总开关。上电或复位后该位默认为0整个I2C模块处于复位状态。此时内部的发送和接收FIFO会被清空所有状态标志位恢复为默认值。但需要注意的是所有配置寄存器如I2C_CON自身、I2C_OA、I2C_SA等的值并不会被复位它们保持软件上一次写入的值。这带来一个重要的实操细节在初始化流程中你应该先配置好所有必要的参数如时钟、地址最后再置位I2C_EN来启动模块。反之在需要彻底复位模块时应先清除I2C_EN等待至少几个系统时钟周期后再重新配置并开启。OPMODE (Bits 13-12): 操作模式选择这两位用于选择I2C的工作速度模式。根据数据手册目前仅支持0h标准/快速模式。1h、2h、3h均为保留值。这里的“标准/快速模式”对应I2C协议中的Standard-mode最高100kbps和Fast-mode最高400kbps。具体运行在哪种速率实际上是由I2C_PSC、I2C_SCLL、I2C_SCLH这三个时钟配置寄存器共同决定的OPMODE更像是一个模式开关。在大多数应用场景下我们直接将其设置为00即可。STB (Bit 11): 起始字节模式这是一个相对特殊的功能仅在I2C主模式下有效。当此位置1时控制器会工作在“起始字节模式”。在此模式下控制器在发送常规的起始条件S后会先发送一个特殊的“起始字节”0x01然后再发送从设备地址。这种模式主要用于连接那些没有I2C硬件接口、需要通过软件轮询SDA线来检测起始条件的微控制器。在绝大多数与标准I2C从设备如EEPROM、传感器通信的场景中此位应保持为0普通模式。3.2 主从模式与数据传输方向MST (Bit 10): 主/从模式选择这是区分控制器角色的关键位。0代表从模式此时控制器等待外部主设备提供的SCL时钟并监听总线上的地址是否与自己的地址匹配。1代表主模式控制器将主动产生SCL时钟并控制整个传输流程。这里有一个极易踩坑的硬件自动行为根据数据手册描述在两种情况下即使软件将MST设为1硬件也会自动将其清零。传输结束当检测到总线上的停止条件P时。仲裁丢失在多主系统中如果本机在发送地址或数据时发现总线上电平与自己驱动的不符即仲裁失败硬件会清除MST位退出主模式。被寻址为从机当本机被配置为主模式但总线上有其他主设备发送了与本机地址匹配的地址时硬件也会清除MST位切换为从模式响应。 这意味着在一次主模式传输完成后如果你希望控制器继续作为主设备发起下一次传输必须在每次发起传输前重新检查并确认MST位为1。一个稳健的编程习惯是在置位STT启动传输之前先写MST1。TRX (Bit 9): 发送/接收模式选择此位仅在主模式下有意义MST1。它决定了本次数据传输的方向。0表示主设备将作为接收方Master Receiver从从设备读取数据1表示主设备作为发送方Master Transmitter向从设备写入数据。对于从模式MST0传输方向由主设备发送的地址字节中的读写位R/W#决定TRX位在从模式下会被硬件忽略。MST与TRX的组合定义了四种基本操作模式如下表所示MSTTRX操作模式描述0x从接收器 (Slave Receiver)控制器作为从设备接收来自主设备的数据。0x从发送器 (Slave Transmitter)控制器作为从设备向主设备发送数据。方向由地址字节的R/W#位决定。10主接收器 (Master Receiver)控制器作为主设备从从设备读取数据。11主发送器 (Master Transmitter)控制器作为主设备向从设备写入数据。3.3 地址扩展模式XSA (Bit 8): 扩展从设备地址当需要与支持10位地址的从设备通信时需要将此位置1。此时I2C_SA寄存器中的SA[9:0]全部有效用于存放10位从设备地址。如果使用标准的7位地址此位应清零此时I2C_SA寄存器中只有SA[6:0]有效SA[9:7]必须由软件写0。XOA0, XOA1, XOA2, XOA3 (Bits 7, 6, 5, 4): 扩展自身地址0~3这四位分别对应控制器自身的四个可编程地址OA0,OA1,OA2,OA3。OA0是基础自身地址通过I2C_OA寄存器设置OA1~OA3是三个附加自身地址分别通过I2C_OA1、I2C_OA2、I2C_OA3寄存器设置。当某个XOAx位置1时对应的地址寄存器将被解释为10位地址清零则解释为7位地址。这允许同一个I2C控制器硬件响应多个不同的从设备地址在多角色或网关应用中非常有用。3.4 总线控制与传输流程STP (Bit 1): 停止条件控制此位仅在主模式下有效。软件通过写1来请求硬件在适当的时候通常是当前数据计数DCOUNT减到0时在总线上产生一个停止条件P。一旦硬件成功产生了停止条件会自动将此位清零。这里有一个关键的超时与总线锁死机制如果在一个传输结束DCOUNT0时STP位没有被软件置1那么硬件将不会产生停止条件而是将SCL线持续拉低使总线处于忙状态。此时控制器可以通过再次置位STT来发起一次重复起始条件Sr或新的传输。这个特性可以用来实现“复合格式”的传输如写寄存器地址后紧接收数据。但如果软件忘记处理就会导致SCL被一直拉低整个I2C总线锁死。STT (Bit 0): 起始条件控制此位仅在主模式下有效。软件通过写1来命令硬件在总线上产生一个起始条件S。硬件产生起始条件后会自动清零此位。STT和STP位的组合直接决定了单次总线事务的格式数据手册给出了清晰的说明STTSTP条件总线活动序列说明10起始S-A-D仅产生起始条件发送地址和数据不产生停止条件。用于复合格式的第一部分。01停止P仅产生停止条件用于结束总线事务。11起始-停止 (DCOUNTn)S-A-D..(n)..D-P产生一个完整的传输帧起始条件、地址、n个数据字节、停止条件。10起始 (DCOUNTn)S-A-D..(n)..D产生起始条件、地址、n个数据字节但不产生停止条件。这里的DCOUNT是I2C_CNT寄存器中的数据计数值。A代表地址字节含R/W#位D代表数据字节。理解这个表是编写正确传输流程的基础。例如要实现一个典型的“写入-读取”操作先写寄存器地址再读数据流程应该是1) 配置为主发送器设置DCOUNT为寄存器地址长度置STT1, STP0发送地址和寄存器地址。2) 配置为主接收器设置DCOUNT为要读取的数据长度置STT1, STP1发送重复起始条件和从设备地址读然后接收数据并以停止条件结束。4. 地址与时钟通信的基石4.1 地址寄存器组详解I2C控制器支持多达4个自身地址这增强了其在复杂系统中的灵活性。I2C_OA是基础自身地址寄存器I2C_OA1、I2C_OA2、I2C_OA3是三个附加地址寄存器。它们的结构完全一致高22位保留低10位OA[9:0]用于存储地址。当对应的XOAx扩展位在I2C_CON中为0时使用7位地址模式此时只有OA[6:0]有效OA[9:7]必须由软件写0。当XOAx为1时使用10位地址模式OA[9:0]全部有效。I2C_SA寄存器用于在主模式下设置要访问的从设备地址。其位域定义与自身地址寄存器类似。同样需要注意当XSA位为07位地址模式时SA[9:7]必须写0。重要提示I2C_OA、I2C_OA1-3、I2C_SA寄存器同样受“活跃传输阶段不可修改”的规则约束。这意味着如果你需要在运行时动态切换通信的从设备地址必须在一次传输完全结束通过ARDY中断或轮询状态确认后修改I2C_SA再发起下一次传输。I2C_ACTOA寄存器是一个只读的状态寄存器用于在控制器作为从设备时指示当前是哪个自身地址被外部主设备匹配并激活。当OAx_ACT位为1时表示对应的自身地址OAx被寻址。这个寄存器在实现多地址响应的从机逻辑时非常有用软件可以读取此寄存器来判断本次通信是针对哪个逻辑功能。I2C_SBLOCK寄存器提供了一个高级功能时钟阻塞。当控制器作为从设备并且OAx_EN位置1时如果它被对应的自身地址OAx寻址它会在地址相位Address Phase之后自动将SCL线拉低阻塞时钟。这相当于从设备向主设备说“我收到你的呼叫了但我现在还没准备好请等待。” 主设备会检测到SCL被拉低而进入等待状态。从设备的CPU在准备好数据后需要向对应的OAx_EN位写0来释放SCL时钟通信才能继续。这个机制为从设备提供了硬件级的流控能力确保从设备有足够时间准备数据避免溢出。4.2 时钟系统配置精度与稳定性的关键I2C通信的时序精度完全由时钟配置寄存器决定。TI的这款控制器使用一个三级分频系统来产生精确的SCL时钟。I2C_PSC寄存器预分频器这是第一级分频。其输入是系统时钟SCLK输出是内部采样时钟ICLK。计算公式为ICLK SCLK / (PSC 1)。PSC是一个8位值范围0-255因此分频系数为1到256。ICLK是控制器内部逻辑的工作时钟其频率必须远高于最终的SCL时钟频率通常至少是SCL频率的几十倍以确保内部状态机有足够的分辨率来产生精确的时序。I2C_SCLL与I2C_SCLH寄存器SCL高低电平时间这是第二级分频基于ICLK周期来定义SCL线的低电平时间tLOW和高电平时间tHIGH。这两个寄存器仅在主模式下有效。SCLL (低电平时间):tLOW (SCLL 7) * T_ICLK。其中T_ICLK是ICLK的周期。SCLH (高电平时间):tHIGH (SCLH 5 floor(t_rise / T_ICLK)) * T_ICLK。这里多了一个t_rise它是SCL信号在物理线上的上升时间由总线电容和上拉电阻决定。floor表示向下取整。SCL时钟频率的计算 最终的SCL时钟周期T_SCL tLOW tHIGH。 SCL时钟频率F_SCL 1 / T_SCL。配置实例假设系统时钟SCLK 48 MHz目标SCL频率为400kHzFast-mode估算总线上升时间t_rise 100ns。首先确定ICLK。为了有足够的调节精度通常让ICLK在10-20MHz左右。我们选择PSC 3则ICLK 48MHz / (31) 12 MHzT_ICLK ≈ 83.33 ns。计算目标T_SCL 1 / 400kHz 2500 ns。分配tLOW和tHIGH。根据I2C规范高低电平时间需满足一定比例。我们暂定tLOW tHIGH 1250 ns。计算SCLLSCLL tLOW / T_ICLK - 7 1250 / 83.33 - 7 ≈ 15 - 7 8。计算SCLH先计算floor(t_rise / T_ICLK) floor(100 / 83.33) 1。然后SCLH tHIGH / T_ICLK - 5 - 1 1250 / 83.33 - 6 ≈ 15 - 6 9。验证tLOW (87)*83.33 1250 nstHIGH (951)*83.33 15*83.33 ≈ 1250 nsT_SCL 2500 nsF_SCL 400 kHz。配置PSC3,SCLL8,SCLH9。实操心得实际配置时由于计算涉及取整最终频率可能与目标有微小偏差。应使用逻辑分析仪或示波器测量实际的SCL波形进行校准。另外I2C_PSC、I2C_SCLL、I2C_SCLH这三个寄存器在模块使能I2C_EN1期间绝对不能修改修改必须在模块禁用后进行。5. 数据流、状态与FIFO管理5.1 数据计数与传输控制I2C_CNT寄存器数据手册片段未详细列出但提及中的DCOUNT字段至关重要。它指定了在主模式下本次传输需要发送或接收的数据字节数。每成功传输一个字节包括地址字节后的ACK/NACKDCOUNT值会自动减1。当DCOUNT减到0时意味着预设的数据传输量已完成此时如果STP位被置1硬件将自动产生停止条件。DCOUNT与STT/STP的配合是实现不同长度、不同格式传输的基础。5.2 缓冲区状态与FIFO深度I2C_BUFSTAT寄存器提供了发送和接收FIFO缓冲区的实时状态信息。FIFODEPTH (Bits 15-14): 只读字段指示内部FIFO的深度。不同型号的控制器可能配置了不同深度的FIFO如8、16、32、64字节。软件在初始化时可以读取此值以决定自己的数据搬移策略如DMA触发阈值。RXSTAT (Bits 13-8): 只读字段指示接收FIFO中当前有多少字节的数据可供读取。当接收就绪RDR中断发生时软件应读取此字段以确定需要读取多少数据。TXSTAT (Bits 5-0): 只读字段指示还有多少数据字节需要写入发送FIFO。它等于I2C_CNT.DCOUNT的初始值减去已经通过OCP接口写入TX FIFO的字节数。在发送过程中监控此字段可以了解发送进度。FIFO的存在大大减轻了CPU的负担。例如在发送大量数据时CPU可以一次性将多个字节写入I2C_DATA寄存器它们会暂存在TX FIFO中由硬件控制器按顺序发送出去。同样接收时硬件会将收到的字节存入RX FIFO攒够一定数量或超时后再通知CPU一次性读取。这避免了为每一个字节都产生中断提升了系统效率。5.3 中断与状态管理虽然输入材料未详细列出中断寄存器但I2C_IRQSTATUS_RAW等寄存器是驱动程序中事件处理的核心。典型的中断状态位包括ARDY(Access Ready): 当一次寄存器访问配置或数据传输准备就绪时触发。通常用于标志一次传输的结束。RRDY(Receive Ready): 接收FIFO中有数据可读时触发。XRDY(Transmit Ready): 发送FIFO有空闲位置可写数据时触发。NACK(Not Acknowledge): 当发送地址或数据后没有收到从设备的应答信号时触发。AL(Arbitration Lost): 在多主竞争总线时本机仲裁失败时触发。一个健壮的驱动应该基于这些中断状态来构建状态机而不是单纯依赖延时等待。例如在发送流程中可以先检查XRDY状态再将数据写入I2C_DATA在接收流程中等待RRDY中断再读取数据每次传输完成后检查ARDY和NACK来判断传输成功与否。6. 系统测试与调试寄存器I2C_SYSTEST寄存器是给芯片测试和系统调试留下的“后门”在正常的I2C功能操作中绝对不应该启用它。数据手册也明确警告“Never enable this register for normal I2C operation”。但在开发调试阶段尤其是当硬件通信完全不通时它可以提供宝贵的底层信号访问能力。ST_EN (Bit 15): 系统测试使能位。只有将此位置1才能设置该寄存器的其他测试位。TMODE (Bits 13-12): 测试模式选择。00: 功能模式默认。10b(2h): SCL计数器测试模式。在此模式下SCL引脚会输出一个连续的时钟信号其频率由I2C_PSC、I2C_SCLL、I2C_SCLH配置决定。这可以用来在不连接从设备的情况下验证SCL时钟配置是否正确用示波器测量频率和占空比。11b(3h): 回环模式 SDA/SCL IO模式。这是最强大的调试模式。回环模式仅在主发送模式下有效。写入I2C_DATA的数据会通过内部路径直接环回到接收FIFO。这可以测试控制器内核的数据通路、FIFO和中断逻辑是否正常完全独立于外部物理总线。SDA/SCL IO模式在此模式下可以通过SCL_I/SDA_I位读取SCL和SDA引脚的实际电平通过SCL_O/SDA_O位强制驱动SCL和SDA引脚为高电平或低电平高阻态。这相当于获得了对I2C总线的“手动”控制权可以用来模拟起始、停止条件发送特定比特流或者检测总线上是否有信号是排查总线短路、对地拉死等硬件问题的终极工具。FREE (Bit 14): 自由运行模式用于调试断点。当CPU调试器遇到断点时此位决定I2C控制器的行为。0表示立即停止在完成当前比特传输后1表示自由运行但FIFO满/空后SDA线会保持低电平。这保证了在单步调试时I2C总线状态是可预测的。调试流程建议当通信失败时可以遵循以下步骤利用I2C_SYSTEST寄存器禁用I2C模块首先确保I2C_EN0。进入SCL计数器测试模式设置ST_EN1,TMODE2h。用示波器测量SCL引脚确认时钟频率和波形符合预期。这排除了时钟配置错误。进入IO模式设置TMODE3h。通过读写SCL_O、SDA_O、SCL_I、SDA_I手动控制总线电平检查总线是否能被正常拉高、拉低外部上拉是否有效。这排除了硬件连接问题。进入回环测试模式配置控制器为主发送模式设置TMODE3h同时使能回环。写入测试数据到I2C_DATA检查是否能从接收FIFO读到相同数据并触发正确的中断。这排除了控制器内核和软件驱动逻辑的问题。退出测试模式调试完毕后务必将ST_EN清零恢复到正常功能模式再进行正常的I2C通信。7. 实战配置流程与常见问题排查7.1 一个完整的主模式初始化与传输流程假设我们需要以主模式100kHz标准模式向一个7位地址为0x50的EEPROM写入3个字节数据{0x00, 0x01, 0x02}。步骤1模块禁用与基础配置// 1. 确保模块禁用并等待复位完成 I2C_CON_REG ~(1 15); // 清除I2C_EN位 delay_us(10); // 短暂延时确保复位稳定 // 2. 配置时钟假设系统时钟SCLK24MHz目标SCL100kHz // ICLK SCLK/(PSC1)。取PSC11 ICLK24MHz/122MHz, T_ICLK500ns。 // tLOW tHIGH 1/(2*100kHz)5us。 // SCLL tLOW/T_ICLK -7 5000ns/500ns -7 10-73。 // 忽略上升时间SCLH tHIGH/T_ICLK -5 10-55。 I2C_PSC_REG 11; I2C_SCLL_REG 3; I2C_SCLH_REG 5; // 3. 配置自身地址作为主设备通常不需要响应但可设一个不冲突的地址 I2C_OA_REG 0x08; // 设置自身7位地址为0x08 // 确保XOA0为0 (7位模式)已在复位值0 // 4. 配置从设备地址 I2C_SA_REG 0x50; // 设置目标从设备7位地址为0x50 // 确保XSA为0 (7位模式)步骤2配置控制寄存器并启动传输// 5. 配置I2C_CON寄存器 uint32_t con_val 0; con_val | (1 15); // I2C_EN 1, 使能模块 con_val | (0 13); // OPMODE[1:0] 00, 标准/快速模式 con_val | (0 11); // STB 0, 普通模式 con_val | (1 10); // MST 1, 主模式 con_val | (1 9); // TRX 1, 发送模式 con_val | (0 8); // XSA 0, 7位从地址 // ... 其他位保持默认0 I2C_CON_REG con_val; // 6. 设置数据计数 I2C_CNT_REG 3; // 准备发送3个字节数据 // 7. 将要发送的数据写入数据寄存器通常通过FIFO或循环写入 I2C_DATA_REG 0x00; // 第一个数据字节 I2C_DATA_REG 0x01; // 第二个数据字节 I2C_DATA_REG 0x02; // 第三个数据字节 // 8. 发起传输产生起始条件并在传输结束后产生停止条件 // 先确保MST1 (已在步骤5设置) I2C_CON_REG | (1 0); // 置位STT产生起始条件 // 同时置位STP使得传输完DCOUNT个字节后自动产生停止条件 I2C_CON_REG | (1 1); // 置位STP步骤3等待传输完成与错误处理// 9. 轮询等待传输完成实际应用中建议使用中断 while(!(I2C_IRQSTATUS_RAW_REG (1 ARDY_BIT))) { // 可选检查NACK、仲裁丢失等错误位 if(I2C_IRQSTATUS_RAW_REG (1 NACK_BIT)) { // 处理无应答错误 handle_nack_error(); break; } } // 10. 传输完成清除中断标志位具体寄存器操作取决于设计可能是写1清零 I2C_IRQSTATUS_CLEAR_REG (1 ARDY_BIT);7.2 典型问题排查速查表问题现象可能原因排查步骤与解决方案通信完全无响应SCL/SDA一直为高1. 模块未使能。2. 引脚复用配置错误I2C功能未映射到物理引脚。3. 外部上拉电阻缺失或阻值过大。1. 确认I2C_CON[15](I2C_EN) 已置1。2. 检查芯片的PinMux配置确保对应引脚的I2C功能已开启。3. 用万用表测量SCL/SDA电压应为上拉电源电压如3.3V。标准模式上拉电阻通常为4.7kΩ快速模式为2.2kΩ。SCL时钟频率不对或波形畸形1.I2C_PSC、SCLL、SCLH计算或配置错误。2. 系统时钟(SCLK)频率与预期不符。3. 总线电容过大导致上升沿太缓。1. 使用I2C_SYSTEST的SCL计数器测试模式输出时钟并用示波器测量校准寄存器值。2. 确认提供给I2C控制器模块的系统时钟源频率正确。3. 减小上拉电阻阻值但需在驱动能力范围内或降低通信频率。能发送起始条件和地址但收不到ACKNACK1. 从设备地址错误。2. 从设备电源或未复位。3. 从设备忙或处于写保护状态。4. 时序不满足从设备要求如建立保持时间。1. 用逻辑分析仪抓取波形核对发送的地址字节含R/W位是否正确。2. 检查从设备电源、复位引脚。3. 查阅从设备数据手册确认其就绪时间、写使能要求。4. 适当增加SCL低电平时间增大SCLL确保数据稳定。通信随机失败偶尔成功1. 电源噪声或地线干扰。2. 总线竞争多主仲裁。3. 软件流程问题在“活跃传输阶段”修改了配置寄存器。4. FIFO溢出/下溢。1. 检查电源滤波确保地线连接良好总线走线远离噪声源。2. 检查I2C_IRQSTATUS的仲裁丢失(AL)标志。3.严格检查代码确保在STT1到ARDY1之间绝不写I2C_CON、I2C_SA、I2C_PSC等寄存器。4. 优化中断服务程序或DMA设置确保及时读写FIFO数据。总线锁死SCL被持续拉低1. 从设备故障拉低SCL。2. 主设备未在传输结束时产生停止条件STP未置位。3. 通信过程被意外中断如看门狗复位。1. 依次断开从设备定位故障器件。2. 检查代码逻辑确保在DCOUNT减为0前或传输完成中断中正确置位了STP。3. 实现总线恢复程序在初始化时尝试发送多个时钟脉冲通过I2C_SYSTEST手动控制SCL直到SDA释放然后发送一个停止条件。作为从设备无法被寻址1. 自身地址(I2C_OA)配置错误。2. 模块未使能或配置为从模式(MST0)。3. 总线被其他设备持续占用。1. 确认I2C_OA寄存器值正确且XOA0位与地址位数匹配。2. 确认I2C_EN1且MST0。3. 用逻辑分析仪监控总线看是否有其他主设备长期占用。7.3 高级技巧与注意事项中断与DMA配合对于高速或大数据量传输务必使用DMA配合中断。配置DMA在XRDY时自动从内存搬运数据到I2C_DATA在RRDY时从I2C_DATA搬运到内存。ARDY中断用于通知一次DMA传输的完成。这能极大降低CPU负载。10位地址模式使用10位地址时除了设置XSA1和填写完整的10位地址到I2C_SA其通信序列也与7位不同。地址需要分两个字节发送第一个字节是11110xx其中xx是10位地址的最高两位 R/W#位第二个字节是地址的低8位。控制器硬件会自动处理这个序列但软件需要知道这个差异。时钟延展Clock Stretching这是I2C协议允许从设备拉低SCL以延长时钟低电平的机制。TI的这款控制器在从模式下支持此功能。当从设备需要更多时间处理数据时它会自动拉低SCL主设备会等待。驱动程序需要处理因此导致的传输延时。电源与复位管理在SoC进入低功耗模式时I2C控制器模块可能被断电。唤醒后必须重新初始化所有寄存器因为断电后寄存器值会丢失。不要依赖休眠前保存的配置。寄存器访问顺序最安全的初始化顺序是先配置所有静态参数地址、时钟分频最后使能模块(I2C_EN1)。修改任何关键配置前先禁用模块(I2C_EN0)修改完成后再使能。