TMS320F280013x I2C模块高级功能与寄存器配置实战指南 1. I2C总线协议核心原理与TMS320F280013x模块概览I2C总线这个在嵌入式世界里无处不在的“老将”以其简洁的两线制SDA数据线、SCL时钟线和灵活的主从多设备架构成为了连接传感器、存储器、IO扩展器等外设的首选方案。它的优雅之处在于所有通信都由主设备发起的时钟信号SCL来同步数据则在SDA线上按位传输配合起始S、停止P条件和应答ACK/NACK机制构建了一套可靠的低速串行通信体系。对于像TI的TMS320F280013x这类面向实时控制与数字电源的C2000系列微控制器而言其内置的I2C模块不仅仅是实现标准协议更通过一系列增强型寄存器为开发者提供了从基础通信到高效数据流管理的完整工具箱。当你拿到TMS320F280013x的数据手册翻到I2C模块章节可能会被那几十个寄存器搞得有点头大。别慌其实它们可以归为几类核心功能模式与命令控制如I2CMDR、数据交换I2CDXR/I2CDRR、时钟配置I2CPSC, I2CCLKL/H、状态监控与中断I2CSTR, I2CIER, I2CISRC以及提升效率的FIFO控制I2CFFTX/RX。理解这些寄存器的协同工作方式是驾驭这个模块的关键。整个通信流程可以概括为主设备通过配置I2CMDR的MST、STT位发起起始条件和地址帧从设备地址匹配后双方根据TRX位确定数据传输方向并依靠I2CSTR中的状态位如XRDY、RRDY和中断来同步数据吞吐。下面我们就从几个关键的高级功能切入看看如何通过寄存器配置来解锁I2C模块的全部潜力。2. 关键工作模式深度解析与寄存器配置实战2.1 自由数据格式FDF的应用场景与配置陷阱自由数据格式Free Data Format是一种特殊的I2C通信模式通过设置I2CMDR寄存器的FDF位为1来启用。与标准格式最根本的区别在于它跳过了地址帧的传输。如图17-12所示起始条件S之后直接就是数据字节每个数据字节后跟随一个ACK位。数据字节的长度由I2CMDR中的BCBit Count字段定义可以是1到8位。这意味着通信双方必须在通信开始前就预先约定好谁是发送方、谁是接收方并且在整个传输过程中角色不能改变因为数据流中没有包含方向控制位R/W#。为什么需要这种模式想象一个简单的场景你的系统里有一块专用的、只负责输出固定格式状态数据的从设备比如一个自定义的传感器模块主设备只需要定期读取它。使用标准格式每次通信都要发送从设备地址和读方向位。而启用FDF后可以直接开始读取数据节省了每次传输的地址帧开销在需要高频、小数据块交换的场合能略微提升效率。但请注意这种模式要求通信双方硬件和软件都必须明确支持并配置为FDF模式兼容性不如标准格式。配置步骤与核心寄存器操作主设备配置首先确保I2C模块处于复位状态I2CMDR.IRS 0。配置I2CMDR寄存器设置FDF1根据通信方向设置TRX1为发送0为接收设置BC字段定义数据位宽例如8位数据则BC000b。然后将IRS置1使能模块。作为主设备你还需要配置I2CCLKL和I2CCLKH来设定SCL时钟频率。从设备配置同样在IRS0时配置I2CMDR。除了FDF1和正确的BC关键是将MST位设为0从模式并根据自身角色设置TRX。从设备的I2COAR自身地址寄存器在FDF模式下不会被用于地址匹配但模块仍需要这个寄存器存在可设为任意值但建议设为实际地址以备切换模式。启动传输主设备设置STT1产生起始条件随后即可向I2CDXR写入数据发送模式或准备从I2CDRR读取数据接收模式。注意数据手册中明确警告自由数据格式在数字回环模式DLB1下不被支持。如果你在调试时同时开启了FDF和DLB通信将会失败。这是一个需要牢记的配置禁忌。2.2 数字回环模式DLB的调试价值与实现细节数字回环模式Digital Loopback Mode是嵌入式开发中极其宝贵的自测试和调试工具。通过设置I2CMDR.DLB 1I2C模块内部将发送数据通路I2CDXR - I2CXSR与接收数据通路I2CRSR - I2CDRR短接形成一个闭环。这意味着你写入I2CDXR的数据会经过模块内部逻辑在延迟n个模块时钟周期后出现在I2CDRR中而无需任何外部物理连接。这里的n 8 * (SYSCLK) / (I2C module clock)。它的核心价值是什么首先硬件隔离验证。你可以在不焊接任何外部器件、甚至不连接SCL/SDA引脚的情况下完整测试MCU的I2C模块驱动程序、中断服务例程和数据流处理逻辑是否正确。其次简化早期开发。在PCB板投产前或外部I2C设备尚未就绪时你可以利用DLB模式提前开发并验证绝大部分I2C通信代码。最后它也是诊断复杂问题的利器。如果外部通信失败可以先启用DLB模式如果内部回环测试通过那么问题很可能出在外部电路、上拉电阻或从设备上。配置与使用要点基本配置在IRS0时设置I2CMDR.DLB 1。同时必须将MST位设置为1主模式这是数据手册强调的操作前提。此时发送到外部SDA引脚上的地址将是I2COAR寄存器中的值但这在内部回环中无关紧要。数据流验证配置完成后使能模块IRS1。作为主发送器TRX1向I2CDXR写入测试数据如0x55、0xAA。然后监控I2CSTR.RRDY位或等待接收中断从I2CDRR中读取数据。比较发送和接收的数据是否一致并确认时序符合预期。结合FIFODLB模式完全可以与FIFO功能协同工作。你可以配置TX FIFO和RX FIFO并利用其中断来测试大数据块的吞吐能力验证FIFO控制逻辑是否正确。实操心得在DLB模式下调试时建议先使用查询方式Polling检查RRDY/XRDY状态位确保基本数据通路畅通。然后再启用中断和FIFO进行复杂测试。这样能分层排除问题如果查询模式都不通那中断和FIFO配置肯定有问题。另外记得DLB模式下的时钟是模块内部提供的无需关心外部时钟同步问题。2.3 重复起始条件Repeated START与总线仲裁机制在标准I2C通信中主设备与一个从设备完成交易后通常会发送一个停止条件P来释放总线。但如果主设备需要与多个从设备连续通信且不希望总线在中间被释放以免其他主设备抢占就可以使用重复起始条件Repeated START。如图17-13所示主设备在完成与第一个从设备的数据传输后不发送停止条件而是直接发送一个新的起始条件Sr紧接着寻址第二个从设备。这样整个通信序列在逻辑上是一个连续的、不被中断的传输过程。寄存器层面的操作在TMS320F280013x中这主要通过控制I2CMDR寄存器的STT和STP位来实现。在非重复模式RM0下通常的流程是设置STT1启动传输数据最后设置STP1产生停止条件。而在需要重复起始时你需要在完成与第一个从设备的数据传输后确保最后一个数据字节的ACK周期结束不设置STP而是直接设置STT1。模块硬件会自动在当前传输结束后产生一个重复起始条件然后你可以更新I2CSAR中的从机地址开始下一轮通信。总线仲裁Arbitration则是多主系统中的安全士。当两个或更多主设备几乎同时发起传输时仲裁机制确保只有一方能赢得总线控制权。其原理基于SDA线的“线与”特性。如图17-15所示主设备在发送地址或数据时会同时监听SDA线。如果某个主设备发送了高电平‘1’但检测到SDA线被拉低为‘0’它就意识到有另一个主设备在发送‘0’。根据“低电平优先”的规则发送‘1’的设备会立即失去仲裁关闭其SDA输出驱动器并切换到从接收模式同时I2CSTR.ARBL标志位会被置位。赢得仲裁的设备则继续完成传输。时钟同步Clock Synchronization是仲裁的伴生机制。在仲裁期间多个主设备的SCL线也被“线与”。如图17-14所示任何一个设备将SCL拉低都会强制所有设备的时钟低电平期开始。SCL线将保持低电平直到所有设备都结束了自己的低电平期。最终SCL的高电平期由最快的设备决定低电平期由最慢的设备决定。这保证了在仲裁过程中所有设备的时钟依然是同步的从而可以可靠地比较SDA线上的数据。开发中的注意事项仲裁丢失处理在你的中断服务程序中必须检查I2CSTR.ARBL位。如果仲裁丢失模块会自动将MST位清零变为从机并产生ARBL中断。你的代码需要妥善处理这一情况通常包括清除错误标志、可能的重试逻辑等。STP位的延迟清除数据手册特别指出在主机模式下当你设置STP1请求停止条件后硬件会延迟清除此位直到I2CSTR.SCD停止条件检测位被置位。因此在发起一次新的传输前务必等待STP位被硬件自动清零否则可能会扰乱I2C状态机。RM位重复模式的妙用对于需要连续发送或接收大量数据且字节数不确定的场景可以将RM设为1。在此模式下I2CCNT寄存器被忽略数据传输完全由向I2CDXR写数据或从I2CDRR读数据以及手动设置STP来驱动。ARDY中断在每个字节传输结束后都会产生非常适合流式数据传输。3. 中断系统与FIFO机制详解3.1 基础中断请求与优先级管理TMS320F280013x的I2C模块提供了两路CPU中断基础I2C中断I2CINT1A和I2C FIFO中断I2CINT2A。基础中断涵盖了通信流程中最关键的事件其源和优先级如表17-6所示。中断使能与处理流程使能在I2CIER寄存器中将对应事件的中断使能位如XRDYINT、RRDYINT、ARDYINT、NACKINT、ARBLINT、SCDINT、AASINT置1。标志置位当事件发生时I2CSTR寄存器中对应的状态标志位如XRDY、RRDY等会被硬件置1。中断产生如果I2CIER中相应使能位也为1则该中断请求会送入仲裁器最终向CPU产生I2CINT1A中断。中断服务在中断服务程序ISR中首先读取I2CISRC中断源寄存器。这个操作有两个作用一是明确当前是哪个事件触发了中断通过INTCODE字段判断二是会自动清除I2CSTR中对应事件的标志位ARDY、RRDY、XRDY这三个标志位除外它们需要手动写1清除。清除标志根据I2CISRC的值跳转到对应的处理子程序。处理完毕后如果需要手动清除ARDY/RRDY/XRDY标志。中断优先级仲裁器内部的优先级是固定的从高到低为ARBLINT仲裁丢失 NACKINT无应答 ARDYINT寄存器就绪 RRDYINT接收就绪 XRDYINT发送就绪 SCDINT停止条件检测 AASINT被寻址为从机。高优先级中断可以打断低优先级中断的服务这在处理总线错误如仲裁丢失、无应答时尤为重要需要优先处理以恢复总线状态。关于ARDY、RRDY、XRDY的特别说明这三个标志位在读取I2CISRC时不会自动清除。这是一个常见的坑点。如果你在ISR中依赖这些标志位进行状态判断并且在处理完后没有手动写1清除它们那么即使中断事件已处理标志位依然为1可能导致程序逻辑误判。正确的做法是在ISR中在处理完对应事件后执行I2CSTR.bit.ARDY 1;这样的操作来清除标志。3.2 FIFO中断配置与高效数据搬运对于需要批量传输数据的应用频繁的字节级中断会带来巨大的CPU开销。TMS320F280013x的I2C模块集成了16级深度的发送TX和接收RXFIFO并配有独立的FIFO中断I2CINT2A可以极大提升数据传输效率。FIFO相关核心寄存器I2CFFTX发送FIFO控制寄存器I2CFFEN总FIFO功能使能位。必须置1才能使用TX或RX FIFO。TXFFRST发送FIFO复位/使能。0复位并保持1使能FIFO操作。TXFFST只读位指示当前发送FIFO中有多少字节数据。TXFFINT发送FIFO中断标志。当TXFFST小于或等于TXFFIL设定的阈值时置位。TXFFINTCLR写1清除TXFFINT标志。TXFFIENA发送FIFO中断使能。TXFFIL发送FIFO中断水平阈值设置。可设为0-16。I2CFFRX接收FIFO控制寄存器字段与I2CFFTX类似但RXFFINT在RXFFST大于或等于RXFFIL时置位。配置与使用流程以发送为例初始化在I2C模块复位IRS0状态下配置I2CFFTX。先设置TXFFIL例如设为8表示FIFO中数据少于等于8个时请求中断然后使能FIFOI2CFFEN1最后释放FIFO复位TXFFRST1。务必注意顺序如果先使能FIFO再设置阈值可能会因为复位后TXFFST0且TXFFIL0而立即触发中断。使能中断设置TXFFIENA1并使能CPU级的I2CINT2A中断。填充数据在主程序中你可以一次性向I2CDXR寄存器写入多达16个字节的数据实际上是通过FIFO缓冲。当FIFO中的数据被硬件逐步发送出去使得剩余数据量TXFFST低于TXFFIL阈值时TXFFINT标志置位触发I2CINT2A中断。中断服务在I2CINT2A的ISR中检查是TXFFINT还是RXFFINT触发通过读取I2CFFTX和I2CFFRX的标志位。如果是TXFFINT说明FIFO有空闲空间可以继续写入下一批数据。处理完后必须写1清除TXFFINTCLR位。关闭FIFO中断在数据发送的最后阶段当最后一包数据写入FIFO后你可能需要关闭TXFFIENA转而使用基础中断的ARDY或XRDY来判断传输是否完全结束因为FIFO中断只在数据量低于阈值时触发无法感知“最后一笔数据已从移位寄存器发出”这个最终状态。一个关键避坑点数据手册在I2CFFRX的描述中特别警告由于RXFFIL复位值为0一旦使能接收FIFORXFFRST1且I2C模块退出复位IRS1如果FIFO为空RXFFST0但0 0的条件成立会立即置位RXFFINT标志这可能导致一上电就误入接收中断。因此安全的做法是在设置RXFFRST1的同一条指令或之前就将RXFFIL设置为一个非零值例如1。对于发送FIFO也有类似注意事项需要在使能后立即清除可能误触的中断标志。3.3 前向/后向兼容模式FCM/BC对时序的影响I2CEMDR寄存器中的两个位——FCMForward Compatibility Mode和BCBackwards Compatibility——用于调整模块的某些行为以兼容同的时序要求或旧有软件。FCM位此位主要影响发送就绪XRDY行为。当FCM0传统模式时一旦数据从I2CDXR复制到I2CXSR移位寄存器XRDY位立即置位表示可以写入下一个数据。这可能导致一个问题如果一次传输事务在中途被异常终止如仲裁丢失、收到NACKI2CDXR中可能还存有未发送的“陈旧”数据下次传输时会错误地再次发送。当FCM1时XRDY仅在总线事务真正需要新数据时才置位。具体来说在主机模式下是在收到地址字节的ACK之后在从机模式下是在地址匹配之后。后续的数据XRDY则在每个数据字节被ACK后置位。这种模式避免了陈旧数据的重用但要求软件更精确地跟踪总线状态。BC位此位影响从发送器模式下XRDY和XSMT位的时序具体关系见图17-18。它主要是为了与更早版本的I2C IP核行为保持兼容。如果你的代码是从旧平台移植过来的并且对XRDY/XSMT的查询或中断时序有严格依赖可能需要根据实际情况调整BC位的设置。对于全新开发通常使用默认值BC1即可。配置建议对于大多数新设计如果你希望获得更可靠的数据传输避免陈旧数据问题建议在初始化时在设置IRS1之前将FCM位设为1。但需要注意的是这可能会改变你原有驱动程序中关于“何时填充下一个数据”的判断逻辑需要相应调整。BC位通常保持默认即可除非你有明确的兼容性需求。4. NACK生成与模块复位机制4.1 灵活控制NACK的生成作为接收方无论是主接收还是从接收有时需要向发送方表明“我不再接收数据了”。这时就需要发送一个非应答位NACK。TMS320F280013x的I2C模块提供了多种生成NACK的方式总结在表17-5中我们需要理解其应用场景。在从接收器模式下允许溢出RSFULL1当接收移位寄存器I2CRSR已满而CPU还未读取I2CDRR中的旧数据时新数据会覆盖I2CRSR并导致RSFULL置位。此时模块会自动发送NACK。这是一种“被动”的NACK通常表示从机处理不过来。复位模块IRS0这是最粗暴的方式直接关闭I2C模块当然会终止通信并产生NACK。仅在需要彻底停止通信时使用。设置NACKMOD位这是最常用、最可控的方式。在你打算接收的最后一个数据位的上升沿之前将I2CMDR.NACKMOD位设置为1。那么在该字节后的ACK周期模块就会发出NACK信号。这是“主动”告知主机停止发送的标准方法。在主接收器模式下 除了上述设置NACKMOD和复位模块的方法外还可以通过**生成停止条件STP1**来间接产生NACK。在非重复模式RM0下如果STP1当内部数据计数器I2CCNT递减到0时模块会在接收完最后一个字节后发送NACK紧接着发出停止条件。如果STP0你也可以通过手动将STP置1来请求停止这也会导致NACK的发送。操作要点使用NACKMOD是最精准的控制方式。关键在于时机必须在当前接收字节的最后一个数据位的上升沿之前设置好NACKMOD。如果设置晚了模块会照常发出ACK导致主机继续发送下一个字节。你可以通过监控SCL线或利用位计数中断如果支持来精确把握这个时机。4.2 模块复位与禁用有两种方式可以复位或禁用I2C模块软件复位将I2CMDR寄存器的IRS位写0。这会立即复位I2C模块的内部状态机所有状态位I2CSTR恢复为默认值SDA和SCL引脚进入高阻态。模块将保持禁用直到IRS被重新置1。这是最常用的复位方式用于在配置更改前或错误恢复时重置模块。硬件全局复位拉低芯片的XRS引脚。这将复位整个设备所有寄存器恢复默认值IRS位也被清零。释放XRS后模块仍处于复位状态需要软件将IRS置1才能启用。一个重要的实践原则在对I2C模块进行任何配置或重新配置如修改时钟分频器I2CPSC、地址寄存器I2COAR/I2CSAR、模式寄存器I2CMDR等之前必须确保IRS0。配置完成后再将IRS置1。这样可以避免模块在配置过程中处于不确定状态导致通信异常。将IRS强制清零也可用于在空闲时关闭模块以节省功耗。5. 软件实例解析与开发实战指南德州仪器在C2000Ware软件包中提供了丰富的I2C示例代码这些是极佳的学习和开发起点。它们通常位于C2000Ware_版本号/driverlib/f280013x/examples/cpu1/i2c目录下。我们来剖析几个关键例子看看理论如何转化为代码。5.1 数字回环与FIFO中断例程分析以i2c_ex1_loopback.c为例这个程序展示了如何利用数字回环模式和FIFO中断进行自测试。核心流程初始化通过SysConfig图形化工具或代码初始化引脚复用Pinmux将对应的GPIO配置为I2C功能。初始化I2C模块时钟配置I2CPSC、I2CCLKL/H以设定波特率。配置回环与FIFO// 置位DLB使能数字回环同时必须置位MST I2caRegs.I2CMDR.bit.DLB 1; I2caRegs.I2CMDR.bit.MST 1; I2caRegs.I2CMDR.bit.IRS 1; // 使能模块 // 配置发送FIFO I2caRegs.I2CFFTX.bit.TXFFIL 4; // 设置中断阈值当FIFO中数据4时触发中断 I2caRegs.I2CFFTX.bit.TXFFIENA 1; // 使能TX FIFO中断 I2caRegs.I2CFFTX.bit.TXFFRST 1; // 使能并复位TX FIFO I2caRegs.I2CFFTX.bit.I2CFFEN 1; // 使能I2C FIFO模式 // 配置接收FIFO I2caRegs.I2CFFRX.bit.RXFFIL 12; // 设置中断阈值当FIFO中数据12时触发中断 I2caRegs.I2CFFRX.bit.RXFFIENA 1; // 使能RX FIFO中断 I2caRegs.I2CFFRX.bit.RXFFRST 1; // 使能并复位RX FIFO // 注意I2CFFEN已在上面使能启动传输程序准备一个数据模式如0x0000, 0x0001, ...并将其填入发送FIFO。由于开启了回环这些数据会被自身接收。中断服务TX FIFO中断服务程序负责在FIFO空间空闲时补充数据RX FIFO中断服务程序负责从接收FIFO中读取数据并与发送的数据进行比较验证。验证通过比较发送和接收的数据流可以验证I2C模块的数据通路、FIFO逻辑和中断处理是否正确。这个例子的价值它提供了一个完整的、无需外部硬件的测试框架。你可以基于此例修改数据模式、测试边界情况如FIFO满/空、或者关闭回环模式将其作为实际外部通信的驱动骨架。5.2 EEPROM读写例程中的时序与协议实现i2c_ex2_eeprom.c和i2c_ex4_eeprom_polling.c等例子演示了与外部I2C EEPROM如AT24C256通信的实际操作。EEPROM读写通常涉及页写、字节读、顺序读等操作对I2C时序有特定要求。关键操作步骤以页写为例发送设备地址和写命令主机发送START条件接着发送EEPROM的7位设备地址如0x50加上写位R/W# 0。发送内存地址EEPROM需要两个字节的内存地址对于24C256。主机依次发送地址的高字节和低字节。发送数据主机连续发送要写入的数据字节。EEPROM会在收到每个字节后回复ACK。需要注意的是大多数EEPROM有“页”的限制如64字节一页跨页写入需要处理页边界。发送停止条件数据发送完毕后主机产生STOP条件。EEPROM收到STOP条件后开始内部写周期t~WR~在此期间不会响应新的访问。必须等待这个写周期完成通常可以通过发送START后查询ACK轮询或延时来实现。读取验证写入完成后可以发起一个读操作来验证数据。读操作通常由“哑写”和“当前地址读”或“随机读”组成先发送设备地址写命令和内存地址然后发送重复起始条件Sr再发送设备地址读命令接着就可以连续读取数据。代码中的寄存器操作// 1. 配置为主发送器准备写入 I2caRegs.I2CMDR.all 0x0020; // IRS1, MST1, TRX1, STT1, STP0 (先不发停止) // 2. 等待ARDY表示地址寄存器就绪可以写入从机地址 while(I2caRegs.I2CSTR.bit.ARDY 0); I2caRegs.I2CSAR 0x0050; // 写入EEPROM地址(0x50 1) | 0 左移一位是因为SAR寄存器存放的是7位地址 // 3. 再次等待ARDY然后写入内存地址高字节 while(I2caRegs.I2CSTR.bit.ARDY 0); I2caRegs.I2CDXR memAddressHigh; // 4. 写入内存地址低字节 while(I2caRegs.I2CSTR.bit.ARDY 0); I2caRegs.I2CDXR memAddressLow; // 5. 写入数据字节 while(I2caRegs.I2CSTR.bit.ARDY 0); I2caRegs.I2CDXR dataByte; // 6. 所有数据写入后设置STP位产生停止条件 I2caRegs.I2CMDR.bit.STP 1; // 7. 等待STP位被硬件清除即停止条件已发出 while(I2caRegs.I2CMDR.bit.STP 1);避坑指南ACK polling在写周期t~WR~内如果你尝试向EEPROM发送设备地址写命令EEPROM不会回复ACKSDA保持高。你可以利用这一点进行“ACK轮询”持续发送START和设备地址写直到收到ACK说明内部写周期结束。但要注意过于频繁的轮询可能会干扰总线上的其他设备。页边界连续写入时不能跨越页边界。如果你的写入起始地址数据长度超过了当前页的末尾超出的部分会从该页的开头“卷绕”写入覆盖之前的数据。必须在软件中处理页边界分割。时钟拉伸虽然EEPROM通常不拉伸时钟但一些低速的I2C从设备会。TMS320F280013x的I2C模块作为主机时能自动处理从机的时钟拉伸无需额外代码。5.3 主从设备中断通信例程剖析i2c_ex5_controller_target_interrupt.c展示了两个TMS320F280013x芯片之间或同一芯片的两个I2C模块之间进行主从通信的完整框架并且使用了FIFO中断。场景假设I2CA作为主控制器ControllerI2CB作为从目标Target。主设备I2CA配置配置为主模式MST1使能TX/RX FIFO及其中断设置好SCL时钟频率。在发送场景下将TRX设为1发送器。从设备I2CB配置配置为从模式MST0设置自身的从机地址I2COAR使能RX FIFO及其中断如果是接收方。使能AAS中断被寻址中断以便在收到自己的地址时做出响应。通信流程主设备启动传输STT1发送从设备地址R/W位。从设备的AAS中断被触发在中断服务程序中它根据接收到的R/W位将自己配置为接收器TRX0或发送器TRX1并准备好FIFO。数据通过FIFO在主从之间流动。主设备的TX FIFO中断用于补充发送数据RX FIFO中断用于读取接收数据从设备亦然。传输结束主设备发送停止条件。这个例子的高级之处在于它演示了双向通信和角色动态切换。例如主设备可以先作为发送器向从设备写入命令然后发送重复起始条件Sr切换为接收器从从设备读取数据。整个过程通过中断异步驱动CPU开销很低。开发此类应用的建议状态机设计主从设备的程序最好基于状态机实现。状态包括空闲、地址已发送等待ACK、发送数据中、接收数据中、等待重复起始、错误处理等。中断服务程序只负责设置状态标志和搬运FIFO数据主循环根据状态标志执行高级逻辑。超时机制务必为所有等待操作如等待ARDY、等待STP清除、等待从机应答添加超时机制。否则一旦从设备无响应或总线故障程序将永远挂起。错误处理在中断服务程序中不仅要处理正常事件XRDY, RRDY更要检查错误标志NACK, ARBL。一旦发现错误应立即记录错误类型复位相关状态并根据应用需求决定是否重试。