news 2026/7/21 22:19:52

TMS320F280013x I2C模块高级功能与寄存器配置实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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中的BC(Bit Count)字段定义,可以是1到8位。这意味着通信双方必须在通信开始前就预先约定好谁是发送方、谁是接收方,并且在整个传输过程中角色不能改变,因为数据流中没有包含方向控制位(R/W#)。

为什么需要这种模式?想象一个简单的场景:你的系统里有一块专用的、只负责输出固定格式状态数据的从设备(比如一个自定义的传感器模块),主设备只需要定期读取它。使用标准格式,每次通信都要发送从设备地址和读方向位。而启用FDF后,可以直接开始读取数据,节省了每次传输的地址帧开销,在需要高频、小数据块交换的场合能略微提升效率。但请注意,这种模式要求通信双方硬件和软件都必须明确支持并配置为FDF模式,兼容性不如标准格式。

配置步骤与核心寄存器操作:

  1. 主设备配置:首先,确保I2C模块处于复位状态(I2CMDR.IRS = 0)。配置I2CMDR寄存器:设置FDF=1,根据通信方向设置TRX(1为发送,0为接收),设置BC字段定义数据位宽(例如,8位数据则BC=000b)。然后,将IRS置1使能模块。作为主设备,你还需要配置I2CCLKL和I2CCLKH来设定SCL时钟频率。
  2. 从设备配置:同样,在IRS=0时配置I2CMDR。除了FDF=1和正确的BC,关键是将MST位设为0(从模式),并根据自身角色设置TRX。从设备的I2COAR(自身地址寄存器)在FDF模式下不会被用于地址匹配,但模块仍需要这个寄存器存在(可设为任意值,但建议设为实际地址以备切换模式)。
  3. 启动传输:主设备设置STT=1产生起始条件,随后即可向I2CDXR写入数据(发送模式)或准备从I2CDRR读取数据(接收模式)。

注意:数据手册中明确警告,自由数据格式在数字回环模式(DLB=1)下不被支持。如果你在调试时同时开启了FDF和DLB,通信将会失败。这是一个需要牢记的配置禁忌。

2.2 数字回环模式(DLB)的调试价值与实现细节

数字回环模式(Digital Loopback Mode)是嵌入式开发中极其宝贵的自测试和调试工具。通过设置I2CMDR.DLB = 1,I2C模块内部将发送数据通路(I2CDXR -> I2CXSR)与接收数据通路(I2CRSR -> I2CDRR)短接,形成一个闭环。这意味着,你写入I2CDXR的数据,会经过模块内部逻辑,在延迟n个模块时钟周期后,出现在I2CDRR中,而无需任何外部物理连接。这里的n = 8 * (SYSCLK) / (I2C module clock)

它的核心价值是什么?首先,硬件隔离验证。你可以在不焊接任何外部器件、甚至不连接SCL/SDA引脚的情况下,完整测试MCU的I2C模块驱动程序、中断服务例程和数据流处理逻辑是否正确。其次,简化早期开发。在PCB板投产前或外部I2C设备尚未就绪时,你可以利用DLB模式提前开发并验证绝大部分I2C通信代码。最后,它也是诊断复杂问题的利器。如果外部通信失败,可以先启用DLB模式,如果内部回环测试通过,那么问题很可能出在外部电路、上拉电阻或从设备上。

配置与使用要点:

  1. 基本配置:在IRS=0时,设置I2CMDR.DLB = 1。同时,必须将MST位设置为1(主模式),这是数据手册强调的操作前提。此时,发送到外部SDA引脚上的地址将是I2COAR寄存器中的值,但这在内部回环中无关紧要。
  2. 数据流验证:配置完成后,使能模块(IRS=1)。作为主发送器(TRX=1),向I2CDXR写入测试数据(如0x55、0xAA)。然后监控I2CSTR.RRDY位或等待接收中断,从I2CDRR中读取数据。比较发送和接收的数据是否一致,并确认时序符合预期。
  3. 结合FIFO:DLB模式完全可以与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位来实现。在非重复模式(RM=0)下,通常的流程是:设置STT=1启动,传输数据,最后设置STP=1产生停止条件。而在需要重复起始时,你需要在完成与第一个从设备的数据传输后(确保最后一个数据字节的ACK周期结束),不设置STP,而是直接设置STT=1。模块硬件会自动在当前传输结束后,产生一个重复起始条件,然后你可以更新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位的延迟清除:数据手册特别指出,在主机模式下,当你设置STP=1请求停止条件后,硬件会延迟清除此位,直到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所示。

中断使能与处理流程

  1. 使能:在I2CIER寄存器中,将对应事件的中断使能位(如XRDYINT、RRDYINT、ARDYINT、NACKINT、ARBLINT、SCDINT、AASINT)置1。
  2. 标志置位:当事件发生时,I2CSTR寄存器中对应的状态标志位(如XRDY、RRDY等)会被硬件置1。
  3. 中断产生:如果I2CIER中相应使能位也为1,则该中断请求会送入仲裁器,最终向CPU产生I2CINT1A中断。
  4. 中断服务:在中断服务程序(ISR)中,首先读取I2CISRC(中断源寄存器)。这个操作有两个作用:一是明确当前是哪个事件触发了中断(通过INTCODE字段判断),二是会自动清除I2CSTR中对应事件的标志位(ARDY、RRDY、XRDY这三个标志位除外,它们需要手动写1清除)。
  5. 清除标志:根据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)和接收(RX)FIFO,并配有独立的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类似,但RXFFINTRXFFST大于或等于RXFFIL时置位。

配置与使用流程(以发送为例)

  1. 初始化:在I2C模块复位(IRS=0)状态下,配置I2CFFTX。先设置TXFFIL(例如设为8,表示FIFO中数据少于等于8个时请求中断),然后使能FIFO(I2CFFEN=1),最后释放FIFO复位(TXFFRST=1)。务必注意顺序:如果先使能FIFO再设置阈值,可能会因为复位后TXFFST=0且TXFFIL=0而立即触发中断。
  2. 使能中断:设置TXFFIENA=1,并使能CPU级的I2CINT2A中断。
  3. 填充数据:在主程序中,你可以一次性向I2CDXR寄存器写入多达16个字节的数据(实际上是通过FIFO缓冲)。当FIFO中的数据被硬件逐步发送出去,使得剩余数据量(TXFFST)低于TXFFIL阈值时,TXFFINT标志置位,触发I2CINT2A中断。
  4. 中断服务:在I2CINT2A的ISR中,检查是TXFFINT还是RXFFINT触发(通过读取I2CFFTX和I2CFFRX的标志位)。如果是TXFFINT,说明FIFO有空闲空间,可以继续写入下一批数据。处理完后,必须写1清除TXFFINTCLR位
  5. 关闭FIFO中断:在数据发送的最后阶段,当最后一包数据写入FIFO后,你可能需要关闭TXFFIENA,转而使用基础中断的ARDY或XRDY来判断传输是否完全结束,因为FIFO中断只在数据量低于阈值时触发,无法感知“最后一笔数据已从移位寄存器发出”这个最终状态。

一个关键避坑点:数据手册在I2CFFRX的描述中特别警告:由于RXFFIL复位值为0,一旦使能接收FIFO(RXFFRST=1)且I2C模块退出复位(IRS=1),如果FIFO为空(RXFFST=0),但0 >= 0的条件成立,会立即置位RXFFINT标志!这可能导致一上电就误入接收中断。因此,安全的做法是:在设置RXFFRST=1同一条指令或之前,就将RXFFIL设置为一个非零值(例如1)。对于发送FIFO也有类似注意事项,需要在使能后立即清除可能误触的中断标志。

3.3 前向/后向兼容模式(FCM/BC)对时序的影响

I2CEMDR寄存器中的两个位——FCM(Forward Compatibility Mode)和BC(Backwards Compatibility)——用于调整模块的某些行为以兼容���同的时序要求或旧有软件。

  • FCM位:此位主要影响发送就绪(XRDY)行为。当FCM=0(传统模式)时,一旦数据从I2CDXR复制到I2CXSR移位寄存器,XRDY位立即置位,表示可以写入下一个数据。这可能导致一个问题:如果一次传输事务在中途被异常终止(如仲裁丢失、收到NACK),I2CDXR中可能还存有未发送的“陈旧”数据,下次传输时会错误地再次发送。当FCM=1时,XRDY仅在总线事务真正需要新数据时才置位。具体来说,在主机模式下,是在收到地址字节的ACK之后;在从机模式下,是在地址匹配之后。后续的数据XRDY则在每个数据字节被ACK后置位。这种模式避免了陈旧数据的重用,但要求软件更精确地跟踪总线状态。
  • BC位:此位影响从发送器模式下XRDY和XSMT位的时序,具体关系见图17-18。它主要是为了与更早版本的I2C IP核行为保持兼容。如果你的代码是从旧平台移植过来的,并且对XRDY/XSMT的查询或中断时序有严格依赖,可能需要根据实际情况调整BC位的设置。对于全新开发,通常使用默认值(BC=1)即可。

配置建议:对于大多数新设计,如果你希望获得更可靠的数据传输,避免陈旧数据问题,建议在初始化时(在设置IRS=1之前)将FCM位设为1。但需要注意的是,这可能会改变你原有驱动程序中关于“何时填充下一个数据”的判断逻辑,需要相应调整。BC位通常保持默认即可,除非你有明确的兼容性需求。

4. NACK生成与模块复位机制

4.1 灵活控制NACK的生成

作为接收方(无论是主接收还是从接收),有时需要向发送方表明“我不再接收数据了”。这时就需要发送一个非应答位(NACK)。TMS320F280013x的I2C模块提供了多种生成NACK的方式,总结在表17-5中,我们需要理解其应用场景。

在从接收器模式下

  1. 允许溢出(RSFULL=1):当接收移位寄存器(I2CRSR)已满,而CPU还未读取I2CDRR中的旧数据时,新数据会覆盖I2CRSR,并导致RSFULL置位。此时模块会自动发送NACK。这是一种“被动”的NACK,通常表示从机处理不过来。
  2. 复位模块(IRS=0):这是最粗暴的方式,直接关闭I2C模块,当然会终止通信并产生NACK。仅在需要彻底停止通信时使用。
  3. 设置NACKMOD位:这是最常用、最可控的方式。在你打算接收的最后一个数据位的上升沿之前,将I2CMDR.NACKMOD位设置为1。那么,在该字节后的ACK周期,模块就会发出NACK信号。这是“主动”告知主机停止发送的标准方法。

在主接收器模式下: 除了上述设置NACKMOD和复位模块的方法外,还可以通过**生成停止条件(STP=1)**来间接产生NACK。在非重复模式(RM=0)下,如果STP=1,当内部数据计数器(I2CCNT)递减到0时,模块会在接收完最后一个字节后发送NACK,紧接着发出停止条件。如果STP=0,你也可以通过手动将STP置1来请求停止,这也会导致NACK的发送。

操作要点:使用NACKMOD是最精准的控制方式。关键在于时机:必须在当前接收字节的最后一个数据位的上升沿之前设置好NACKMOD。如果设置晚了,模块会照常发出ACK,导致主机继续发送下一个字节。你可以通过监控SCL线或利用位计数中断(如果支持)来精确把握这个时机。

4.2 模块复位与禁用

有两种方式可以复位或禁用I2C模块:

  1. 软件复位:将I2CMDR寄存器的IRS位写0。这会立即复位I2C模块的内部状态机,所有状态位(I2CSTR)恢复为默认值,SDA和SCL引脚进入高阻态。模块将保持禁用直到IRS被重新置1。这是最常用的复位方式,用于在配置更改前或错误恢复时重置模块。
  2. 硬件全局复位:拉低芯片的XRS引脚。这将复位整个设备,所有寄存器恢复默认值,IRS位也被清零。释放XRS后,模块仍处于复位状态,需要软件将IRS置1才能启用。

一个重要的实践原则在对I2C模块进行任何配置或重新配置(如修改时钟分频器I2CPSC、地址寄存器I2COAR/I2CSAR、模式寄存器I2CMDR等)之前,必须确保IRS=0。配置完成后,再将IRS置1。这样可以避免模块在配置过程中处于不确定状态,导致通信异常。将IRS强制清零也可用于在空闲时关闭模块以节省功耗。

5. 软件实例解析与开发实战指南

德州仪器在C2000Ware软件包中提供了丰富的I2C示例代码,这些是极佳的学习和开发起点。它们通常位于C2000Ware_<版本号>/driverlib/f280013x/examples/cpu1/i2c目录下。我们来剖析几个关键例子,看看理论如何转化为代码。

5.1 数字回环与FIFO中断例程分析

i2c_ex1_loopback.c为例,这个程序展示了如何利用数字回环模式和FIFO中断进行自测试。

核心流程

  1. 初始化:通过SysConfig图形化工具或代码初始化引脚复用(Pinmux),将对应的GPIO配置为I2C功能。初始化I2C模块时钟,配置I2CPSC、I2CCLKL/H以设定波特率。
  2. 配置回环与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已在上面使能
  3. 启动传输:程序准备一个数据模式(如0x0000, 0x0001, ...),并将其填入发送FIFO。由于开启了回环,这些数据会被自身接收。
  4. 中断服务:TX FIFO中断服务程序负责在FIFO空间空闲时补充数据;RX FIFO中断服务程序负责从接收FIFO中读取数据,并与发送的数据进行比较验证。
  5. 验证:通过比较发送和接收的数据流,可以验证I2C模块的数据通路、FIFO逻辑和中断处理是否正确。

这个例子的价值:它提供了一个完整的、无需外部硬件的测试框架。你可以基于此例,修改数据模式、测试边界情况(如FIFO满/空)、或者关闭回环模式,将其作为实际外部通信的驱动骨架。

5.2 EEPROM读写例程中的时序与协议实现

i2c_ex2_eeprom.ci2c_ex4_eeprom_polling.c等例子演示了与外部I2C EEPROM(如AT24C256)通信的实际操作。EEPROM读写通常涉及页写、字节读、顺序读等操作,对I2C时序有特定要求。

关键操作步骤(以页写为例)

  1. 发送设备地址和写命令:主机发送START条件,接着发送EEPROM的7位设备地址(如0x50)加上写位(R/W# = 0)。
  2. 发送内存地址:EEPROM需要两个字节的内存地址(对于24C256)。主机依次发送地址的高字节和低字节。
  3. 发送数据:主机连续发送要写入的数据字节。EEPROM会在收到每个字节后回复ACK。需要注意的是,大多数EEPROM有“页”的限制(如64字节一页),跨页写入需要处理页边界。
  4. 发送停止条件:数据发送完毕后,主机产生STOP条件。EEPROM收到STOP条件后,开始内部写周期(t~WR~),在此期间不会响应新的访问。必须等待这个写周期完成,通常可以通过发送START后查询ACK(轮询)或延时来实现。
  5. 读取验证:写入完成后,可以发起一个读操作来验证数据。读操作通常由“哑写”和“当前地址读”或“随机读”组成:先发送设备地址+写命令和内存地址,然后发送重复起始条件(Sr),再发送设备地址+读命令,接着就可以连续读取数据。

代码中的寄存器操作

// 1. 配置为主发送器,准备写入 I2caRegs.I2CMDR.all = 0x0020; // IRS=1, MST=1, TRX=1, STT=1, STP=0 (先不发停止) // 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不会回复ACK(SDA保持高)。你可以利用这一点进行“ACK轮询”:持续发送START和设备地址+写,直到收到ACK,说明内部写周期结束。但要注意,过于频繁的轮询可能会干扰总线上的其他设备。
  • 页边界:连续写入时不能跨越页边界。如果你的写入起始地址+数据长度超过了当前页的末尾,超出的部分会从该页的开头“卷绕”写入,覆盖之前的数据。必须在软件中处理页边界分割。
  • 时钟拉伸:虽然EEPROM通常不拉伸时钟,但一些低速的I2C从设备会。TMS320F280013x的I2C模块作为主机时,能自动处理从机的时钟拉伸,无需额外代码。

5.3 主从设备中断通信例程剖析

i2c_ex5_controller_target_interrupt.c展示了两个TMS320F280013x芯片之间(或同一芯片的两个I2C模块之间)进行主从通信的完整框架,并且使用了FIFO中断。

场景:假设I2CA作为主控制器(Controller),I2CB作为从目标(Target)。

  1. 主设备(I2CA)配置:配置为主模式(MST=1),使能TX/RX FIFO及其中断,设置好SCL时钟频率。在发送场景下,将TRX设为1(发送器)。
  2. 从设备(I2CB)配置:配置为从模式(MST=0),设置自身的从机地址(I2COAR),使能RX FIFO及其中断(如果是接收方)。使能AAS中断(被寻址中断),以便在收到自己的地址时做出响应。
  3. 通信流程
    • 主设备启动传输(STT=1),发送从设备地址+R/W位。
    • 从设备的AAS中断被触发,在中断服务程序中,它根据接收到的R/W位,将自己配置为接收器(TRX=0)或发送器(TRX=1),并准备好FIFO。
    • 数据通过FIFO在主从之间流动。主设备的TX FIFO中断用于补充发送数据,RX FIFO中断用于读取接收数据;从设备亦然。
    • 传输结束,主设备发送停止条件。

这个例子的高级之处在于它演示了双向通信角色动态切换。例如,主设备可以先作为发送器向从设备写入命令,然后发送重复起始条件(Sr),切换为接收器,从从设备读取数据。整个过程通过中断异步驱动,CPU开销很低。

开发此类应用的建议

  • 状态机设计:主从设备的程序最好基于状态机实现。状态包括:空闲、地址已发送等待ACK、发送数据中、接收数据中、等待重复起始、错误处理等。中断服务程序只负责设置状态标志和搬运FIFO数据,主循环根据状态标志执行高级逻辑。
  • 超时机制:务必为所有等待操作(如等待ARDY、等待STP清除、等待从机应答)添加超时机制。否则,一旦从设备无响应或总线故障,程序将永远挂起。
  • 错误处理:在中断服务程序中,不仅要处理正常事件(XRDY, RRDY),更要检查错误标志(NACK, ARBL)。一旦发现错误,应立即记录错误类型,复位相关状态,并根据应用需求决定是否重试。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/20 14:35:39

Streamlink Twitch GUI:跨平台Twitch直播浏览器的终极解决方案

Streamlink Twitch GUI&#xff1a;跨平台Twitch直播浏览器的终极解决方案 【免费下载链接】streamlink-twitch-gui A multi platform Twitch.tv browser for Streamlink 项目地址: https://gitcode.com/gh_mirrors/st/streamlink-twitch-gui 你是否厌倦了Twitch官方网页…

作者头像 李华
网站建设 2026/7/20 14:34:46

Solaris 10动态链接与反汇编工具ldd、pvs、dis详解

1. Solaris 10环境下ldd、pvs和dis命令解析在Solaris 10操作系统中&#xff0c;ldd、pvs和dis是三个重要的系统工具命令&#xff0c;它们分别用于分析动态链接库依赖关系、查看ELF文件版本信息以及反汇编可执行文件。这些命令对于系统管理员和开发人员来说都是不可或缺的调试和…

作者头像 李华
网站建设 2026/7/20 14:34:05

TMS320F28002x ERAD模块实战:硬件断点、计数器与CRC的嵌入式调试利器

1. 项目概述&#xff1a;TMS320F28002x ERAD模块深度解析在嵌入式实时控制系统的开发过程中&#xff0c;尤其是面对电机控制、数字电源这类对时序和可靠性要求近乎苛刻的应用&#xff0c;传统的软件断点和打印调试往往力不从心。你可能会遇到这样的困境&#xff1a;一个偶发的、…

作者头像 李华
网站建设 2026/7/20 14:32:27

把DeepSeek部署在你的电脑上(保姆级教程)

一、什么情况下&#xff0c;适合把大模型部署在自己电脑上&#xff1f; 把大模型部署在自己的电脑上&#xff0c;有很多好处&#xff0c;但我要先泼一盆冷水。 如果你之前没用过AI产品&#xff0c;或者平时用AI也不多&#xff0c;不推荐搞本地部署。有更简单的方法&#xff0…

作者头像 李华
网站建设 2026/7/20 14:32:16

Passinote:支持拖放堆叠分区导出,打造随思维而变的笔记桌面!

Passinote&#xff1a;打破传统的笔记新体验Passinote 为用户带来了全新的笔记记录方式。它是一个永远不会空间不足&#xff0c;也不会让用户丢失记录位置的桌面。其核心功能包括拖放、堆叠、分区和导出。在拖放方面&#xff0c;用户可以在任意位置拖放任意内容&#xff0c;如笔…

作者头像 李华