尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

I2C控制器高级功能实战:中断、DMA与唤醒机制详解

I2C控制器高级功能实战:中断、DMA与唤醒机制详解
📅 发布时间:2026/7/22 16:53:07

1. I2C控制器高级功能:从轮询到事件驱动的跨越

在嵌入式开发里,I2C总线就像连接MCU和各种传感器、存储芯片的“神经系统”。刚开始玩单片机那会儿,我写I2C驱动基本都是轮询——CPU像个监工一样,不停地去查“数据发完了没?”“收到了没?”,效率低不说,CPU啥也干不了,全耗在等待上了。后来项目复杂了,传感器多了,数据量大了,这种笨办法根本行不通。这时候,I2C控制器提供的中断、DMA和唤醒这些高级功能,就成了提升系统性能和降低功耗的关键。

简单来说,中断让I2C控制器在“有事”的时候(比如数据准备好了、传输出错了)主动喊CPU来处理,CPU平时可以去干别的活。DMA更进一步,它像个“数据搬运工”,能在I2C的FIFO(先入先出缓冲区)和系统内存之间直接搬数据,完全不用CPU插手,特别适合大批量、连续的数据传输。而唤醒机制,则是为低功耗场景设计的:当整个系统(包括CPU)都进入休眠模式以省电时,I2C控制器可以作为一个“哨兵”,在检测到特定的总线活动(比如有起始信号、或者自己的从机地址被呼叫)时,把整个系统从睡梦中叫醒。

理解并配置好这些功能,你的嵌入式系统才能算得上“高效”和“智能”。本文我们就以TI的I2C控制器为例,掰开揉碎了讲讲如何通过配置那些关键的寄存器,来实现这些高级功能。我会结合我踩过的坑和实战经验,让你不仅知道怎么配,更明白为什么要这么配。

2. 核心寄存器全景图与设计思路

在深入每个寄存器之前,我们得先有个全局观。I2C控制器的高级功能管理,本质上是通过几组“开关”和“状态机”来实现的。它们之间相互关联,构成了一个清晰的控制流。

2.1 寄存器功能分组与关联逻辑

我们可以把相关的寄存器分成几个核心小组:

  1. 中断管理组:这是事件响应的核心。

    • 状态寄存器 (I2C_IRQSTATUS_RAW):这是“发生了什么”的原始报告。无论你是否使能中断,只要事件发生,对应的状态位就会被硬件置1。它是最源头的信息。
    • 中断使能置位/清零寄存器 (I2C_IRQENABLE_SET/CLR):这是“我想关心什么”的开关。向SET寄存器的某位写1,就打开对应事件的中断;向CLR寄存器的某位写1,就关闭它。这种“置位/清零”分离的设计,避免了“读-改-写”操作可能引发的竞态问题,在多任务或中断环境中更安全。
  2. DMA管理组:这是解放CPU的“自动化”配置。

    • DMA使能置位/清零寄存器 (I2C_DMARX/TXENABLE_SET/CLR):控制是否启用接收或发送方向的DMA通道。注意,这只是局部开关。
    • 缓冲区配置寄存器 (I2C_BUF):这里的RDMA_EN和XDMA_EN位是DMA的“总开关”。必须和前面的使能寄存器配合使用。同时,这个寄存器还管理着FIFO的阈值(RXTRSH,TXTRSH),这个阈值直接决定了DMA请求(或中断)在何时触发,是性能调优的关键。
  3. 唤醒管理组:这是低功耗设计的“触发器”。

    • 唤醒使能寄存器 (I2C_WE):定义哪些事件可以将模块(乃至整个系统)从低功耗的“空闲模式”唤醒。很多事件和中断是重叠的,但唤醒发生在更底层的时钟域,允许在系统主时钟关闭时工作。
    • DMA唤醒使能寄存器 (I2C_DMARX/TXWAKE_EN):专门为DMA传输场景下的唤醒提供精细控制。
  4. 数据传输控制组:这是通信的“执行单元”。

    • 数据计数器 (I2C_CNT):在主机模式下,它决定了本次传输的字节数。计数器减到0会触发ARDY(寄存器访问就绪)事件。千万注意:数据手册用粗体警告,传输开始(STT置位)后到ARDY事件发生前,绝对不能修改此寄存器,否则行为不可预测。
    • 数据寄存器 (I2C_DATA):读写FIFO的入口。这里有个关键细节:读空FIFO或写满FIFO都会触发AERR(访问错误)中断。这在调试时非常有用。

它们之间的关系,可以用一个简单的决策流来理解:一个总线事件(如收到一个字节)发生 -> 更新IRQSTATUS_RAW-> 如果IRQENABLE对应位为1,则向CPU发出中断请求;同时,如果WE对应位为1且模块处于空闲模式,则发出唤醒信号;如果DMA总开关和对应通道使能位都打开,且FIFO数据量达到阈值,则向DMA控制器发出传输请求。

2.2 关键事件类型深度解析

手册里列出了十几种事件,刚开始看容易眼花。我们可以按功能把它们归为几大类,理解起来就清晰了:

  • 数据传输类:

    • XRDY(发送就绪):发送FIFO有空闲位置,可以写入下一个待发送字节了。
    • RRDY(接收就绪):接收FIFO中有数据,可以读取了。
    • ARDY(寄存器访问就绪):一次数据传输(由I2C_CNT定义的长度)完成。这是主机模式下判断一次“会话”结束的重要标志。
  • 总线状态与错误类:

    • AL(仲裁丢失):在多主机系统中,自己的输出电平与总线实际电平不一致,竞争失败。必须处理此事件,重新尝试发送。
    • NACK(无应答):发送的地址或数据字节未收到从机的应答信号。通常是地址错误、从机忙或从机不存在。
    • AERR(访问错误):软件试图读空FIFO或写满FIFO。通常意味着程序流控制有bug。
    • ROVR(接收溢出):接收FIFO已满,但总线又传来新数据,导致数据丢失。这是严重的错误,意味着CPU或DMA处理数据不够快。
    • XUDF(发送下溢):总线需要发送数据,但发送FIFO已空。这会导致SCL线被拉低,总线挂起。
  • 从机与总线监控类:

    • AAS(被寻址为从机):总线上有主机发送的地址与本机设置的从机地址匹配。
    • GC(通用呼叫):收到了广播地址0x00。
    • BF(总线空闲):SCL和SDA线都持续高电平超过一定时间,总线进入空闲状态。
    • STC(起始条件):检测到总线上出现了起始条件(SDA在SCL高时由高变低)。
  • FIFO深度管理类:

    • XDR(发送排空):发送FIFO中的数据量低于设定的阈值(TXTRSH)。用于在DMA或中断模式下,提前通知CPU/DMA准备更多数据,防止XUDF。
    • RDR(接收排空):一次传输结束(收到停止位)但接收FIFO中还有未读出的数据。用于确保所有数据都被处理。

理解这些事件的本质,是正确配置使能寄存器、编写中断服务程序或DMA回调函数的基础。

3. 中断机制详解与实战配置

中断是提高CPU效率最直接的手段。配置不当,要么是中断疯狂触发拖慢系统,要么是事件得不到及时响应。

3.1 中断使能寄存器的精妙操作

I2C_IRQENABLE_SET和I2C_IRQENABLE_CLR这两个寄存器是配对使用的。它们的每一位都对应I2C_IRQSTATUS_RAW寄存器中的一个状态位。

操作铁律:永远使用“置位寄存器”来开启中断,使用“清零寄存器”来关闭中断。直接向IRQENABLE_SET写入一个多位掩码来同时开启多个中断是安全的,因为写0无效。但切忌直接读写一个模拟的“IRQENABLE”值进行“读-改-写”,因为在多线程或中断嵌套场景下,你读到的值可能在你修改它之前已经被其他上下文改变,导致配置错误。

实战配置示例:假设我们需要在主机发送模式下,使能“发送���绪”(XRDY)和“无应答”(NACK)中断,并关闭其他所有中断。

// 假设 I2C0_BASE 是 I2C 控制器的基础地址 #define I2C0_IRQENABLE_SET (*(volatile uint32_t *)(I2C0_BASE + 0x2C)) #define I2C0_IRQENABLE_CLR (*(volatile uint32_t *)(I2C0_BASE + 0x30)) // 首先,清除所有可能已使能的中断(写入1到CLR寄存器对应位) // 通常我们会直接写0xFFFF到CLR寄存器来关闭所有中断,但需注意保留位。 // 根据手册,bit15,12,7,4是保留的。安全起见,我们使用明确的掩码。 uint32_t clear_all_mask = (1 << 14) | (1 << 13) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 6) | (1 << 5) | (1 << 3) | (1 << 2) | (1 << 1) | (1 << 0); I2C0_IRQENABLE_CLR = clear_all_mask; // 然后,使能我们需要的两个中断 uint32_t enable_mask = (1 << 4) | // XRDY_IE: 位4 (1 << 1); // NACK_IE: 位1 I2C0_IRQENABLE_SET = enable_mask;

注意:在使能中断前,务必先清除I2C_IRQSTATUS_RAW中可能已经挂起的旧中断标志位(通常通过向I2C_IRQSTATUS寄存器对应的位写1来清除),否则可能会一使能就立刻进入中断。

3.2 中断服务程序(ISR)编写要点与避坑指南

中断服务程序的核心任务是:快速识别事件、处理必要操作、清除中断标志。

一个典型的主机发送模式中断服务程序骨架如下:

void I2C0_IRQHandler(void) { uint32_t status = I2C0_IRQSTATUS_RAW; // 读取原始状态 // 处理无应答错误(高优先级) if (status & (1 << 1)) { // NACK // 1. 记录错误日志 // 2. 可能需要产生停止条件来终止异常传输 // 3. 设置错误标志,让主程序知道传输失败 i2c_error_flag = ERROR_NACK; // 4. 清除中断标志(向IRQSTATUS对应位写1) I2C0_IRQSTATUS = (1 << 1); // 通常发生NACK后需要软件干预复位状态,可能还需要清除STT位等 return; // 发生错误,优先处理 } // 处理发送就绪 if (status & (1 << 4)) { // XRDY // 检查是否还有数据要发送 if (tx_data_index < tx_data_length) { I2C0_DATA = tx_data_buffer[tx_data_index++]; // 写入一个字节到FIFO } else { // 所有数据已装入FIFO,可以关闭XRDY中断,等待ARDY I2C0_IRQENABLE_CLR = (1 << 4); } // 清除中断标志 I2C0_IRQSTATUS = (1 << 4); } // 处理寄存器访问就绪(一次传输完成) if (status & (1 << 2)) { // ARDY // 本次CNT设定的传输已完成 // 如果是最后一个数据包,可能需要产生停止条件(如果CON.STP=1则自动产生) i2c_transfer_done = true; // 清除中断标志 I2C0_IRQSTATUS = (1 << 2); } // ... 处理其他可能使能的中断 }

避坑指南:

  1. 中断标志清除顺序:务必在处理完事件之后再清除标志位。特别是对于ARDY这类标志,清除它有时会触发硬件状态转移。如果先清除再处理,可能会错过关键状态。
  2. FIFO访问:在XRDY中断中向DATA寄存器写数据前,理论上FIFO有空位,但极端情况下(如中断响应延迟极大),写入前最好再判断一下发送缓冲区状态(如果有相关寄存器)。对于RRDY,读数据前亦然。
  3. 性能考量:中断处理函数应尽可能短小。如果单次传输数据量很大,频繁进入XRDY/RRDY中断(每个字节一次)开销很大。此时应结合FIFO阈值和DMA来优化。

4. DMA配置与FIFO阈值调优

当需要传输几十、上百个字节时,DMA是必不可少的。它能将CPU从繁琐的字节搬运中彻底解放出来。

4.1 DMA使能的双重开关机制

I2C控制器的DMA使能设计得有点“绕”,但很严谨。它有两个层级的开关:

  1. 全局(从机)使能:位于I2C_BUF寄存器中的RDMA_EN(接收)和XDMA_EN(发送)位。这是DMA功能的“总闸”。
  2. 通道使能:通过I2C_DMARXENABLE_SET和I2C_DMATXENABLE_SET寄存器控制。这是具体请求的“分闸”。

必须两者都打开,DMA请求才会产生。这种设计提供了灵活性,你可以在全局开启DMA的情况下,动态开关某个方向的DMA通道。

DMA配置流程:

// 1. 首先配置系统DMA控制器(这里以内存到外设发送为例) // 假设已配置好DMA源地址(内存数组)、目的地址(I2C_DATA寄存器)、传输数据量等 setup_dma_channel(); // 2. 配置I2C的FIFO阈值。这是决定DMA请求触发时机的关键! // 例如,设置发送阈值TXTRSH为8。当发送FIFO中剩余空间>=8时,就会触发DMA请求。 I2C0_BUF = (0 << 8) | (0x08 << 0); // 假设RXTRSH=0, TXTRSH=8 (位5-0) // 3. 打开I2C的DMA全局使能和通道使能 // 先设置BUF寄存器,注意保留位和FIFO清除位通常写0 uint32_t buf_val = (1 << 15) | // RDMA_EN = 1 (假设也开接收DMA) (1 << 7) | // XDMA_EN = 1 (0x08 << 0); // TXTRSH = 8 I2C0_BUF = buf_val; // 然后使能发送DMA通道 I2C0_DMATXENABLE_SET = 0x1; // 写1到DMATX_ENABLE_SET位(位0) // 4. 启动I2C传输(设置从机地址、CNT、CON寄存器,置位STT等) start_i2c_transfer(); // 5. 启动DMA传输 enable_dma_channel();

之后,每当发送FIFO的空闲位置达到或超过8个时,I2C控制器就会自动向DMA控制器发出请求,DMA则从内存搬运8个字节的数据到I2C_DATA寄存器,填满FIFO。如此循环,直到完成I2C_CNT设定的所有字节传输,产生ARDY中断通知CPU完成。

4.2 FIFO阈值选择的艺术与权衡

RXTRSH和TXTRSH的配置直接影响系统性能和响应延迟。

  • 阈值设得太小(比如1或2):DMA请求或中断会非常频繁。对于DMA,虽然CPU不参与搬运,但每次DMA请求和传输都有总线仲裁、地址切换等开销,过于频繁的请求会占用系统总线带宽。对于中断,则会导致CPU频繁被打断。
  • 阈值设得太大(接近FIFO深度,如60):请求触发不频繁,总线利用率高。但风险很大!对于发送,如果初始FIFO是空的,你需要先手动写入至少(深度-阈值)个数据来启动第一次请求,否则总线会等待。更严重的是,一旦DMA传输稍有延迟,FIFO就可能被掏空,引发XUDF(下溢)错误,导致总线挂起。对于接收,如果数据涌入很快,FIFO可能在你第一次处理之前就满了,导致ROVR(溢出)错误。

经验值:

  • 对于低速设备(如传感器,<100kHz),阈值可以设小一些(如4-8),因为数据间隔长,风险低。
  • 对于高速设备(如摄像头,>400kHz)或大数据量传输,阈值应设大一些(如FIFO深度的一半或三分之二,例如32或48),并确保DMA源/目标内存是连续的,且位于高速RAM中,以减少DMA传输延迟。
  • 必须进行压力测试:在最大通信速率下,传输超大数据包(如1KB),监控是否出现ROVR或XUDF错误。如果出现,需要优化DMA优先级、提高CPU/DMA时钟,或者适当降低I2C总线速度。

一个关键陷阱:数据手册在I2C_BUF的Note2中强调:“在传输进行中(STT置位后到收到ARDY前),绝对不能更改阈值!”修���阈值会导致FIFO指针和阈值比较逻辑混乱,引发不可预知的数据错误或丢失。配置阈值必须在传输开始前完成。

5. 低功耗唤醒机制深入剖析

在电池供电的设备中,MCU大部分时间处于休眠模式。I2C控制器可以作为唤醒源,让系统在需要通信时才醒来。

5.1 唤醒使能寄存器(I2C_WE)的特殊性

I2C_WE寄存器的位定义与I2C_IRQENABLE非常相似,但它们的应用场景有本质区别:

  • 中断:用于模块处于活动模式(时钟开启)时,通知CPU处理事件。
  • 唤醒:用于模块处于空闲/休眠模式(功能时钟可能关闭)时,将模块乃至整个系统拉回活动模式。

重要限制(手册I2C_WE部分的Note):

  1. AERR(访问错误)没有唤醒事件。因为访问错误只发生在模块处于活动模式时(CPU试图访问FIFO),此时不需要唤醒。
  2. 除了STC(起始条件),其他所有唤醒事件都需要功能时钟(Functional Clock)已启用。这意味着,如果你想被“总线空闲”(BF)或“被寻址”(AAS)唤醒,模块必须配置为在空闲模式下保持功能时钟开启(I2C_SYSC.ClockActivity相关配置)。
  3. STC唤醒是异步检测的。即使功能时钟关闭,硬件也能通过异步逻辑检测SDA和SCL线上的起始条件。但手册也警告,这可能会因为毛刺(glitch)而误触发。因此,在噪声较大的环境中使用STC唤醒要谨慎。

5.2 典型低功耗从机唤醒配置

假设一个温度传感器节点作为I2C从机,平时MCU深度睡眠,I2C模块处于低功耗状态。当主机发送起始条件并呼叫其地址时,它需要被唤醒并响应。

// 1. 进入休眠前的配置 // 使能 I2C 模块的功能时钟在空闲模式下保持活动(具体取决于芯片的电源管理配置) // 例如,配置 I2C_SYSC.CLOCKACTIVITY = 0x01 (仅OCP接口时钟关闭) // 2. 配置自身的从机地址 I2C0_SADR = MY_SLAVE_ADDR; // 3. 配置唤醒使能寄存器:我们希望被起始条件和地址匹配唤醒 uint32_t wake_en = 0; wake_en |= (1 << 6); // STC_WE: 起始条件唤醒 wake_en |= (1 << 9); // AAS_WE: 被寻址为从机唤醒 // 注意:根据手册,AAS_WE需要功能时钟,所以必须确保时钟在空闲模式下可用。 I2C0_WE = wake_en; // 4. 确保全局唤醒使能开启(如果存在这样的系统级控制位,例如I2C_SYSC.ENAWAKEUP) // I2C0_SYSC |= (1 << ENAWAKEUP_BIT); // 5. 将MCU和I2C模块置于指定的低功耗模式(具体指令依芯片而定) // enter_low_power_mode(); // 系统现在休眠... // 当总线上出现起始条件(STC)或呼叫本机地址(AAS)时,I2C模块会产生唤醒信号。 // 硬件会自动将模块和系统时钟恢复到活动状态。 // 6. 唤醒后的处理(在唤醒后的初始化代码中) // 首先,检查IRQSTATUS_RAW寄存器,看具体是哪个事件唤醒了系统。 // 如果是AAS,说明主机在呼叫我们,接下来需要准备接收或发送数据。 // 此时再使能RRDY或XRDY等数据传输中断。 uint32_t status = I2C0_IRQSTATUS_RAW; if (status & (1 << 9)) { // AAS // 清除唤醒/中断标志 I2C0_IRQSTATUS = (1 << 9); // 配置为接收或发送模式,并使能数据中断 // ... 后续数据处理流程 }

特别注意:I2C_DMARX/TXWAKE_EN寄存器用于DMA场景下的唤醒。例如,在休眠前启动了DMA接收,并设置了RDR_WE(接收排空唤醒),那么当DMA将FIFO中的数据搬空,但一次传输还未结束(未收到停止位)时,模块可以唤醒CPU来检查或处理后续事务。这实现了DMA与低功耗的协同。

6. 系统集成、调试与常见问题排查

把中断、DMA、唤醒组合到一个实际应用中,需要清晰的流程和严谨的初始化顺序。

6.1 完整的主机发送带DMA流程

  1. 初始化阶段:

    • 配置I2C引脚复用、时钟。
    • 配置I2C总线速度(I2C_PSC,I2C_SCLL,I2C_SCLH)。
    • 配置I2C_BUF:设置FIFO阈值(TXTRSH),先不要开启XDMA_EN。
    • 配置I2C_CON:设置为主机发送模式(MST=1,TRX=1)。
    • 清除所有中断和状态标志(I2C_IRQSTATUS)。
    • 配置DMA控制器:源地址(内存数据缓冲区)、目的地址(I2C_DATA)、传输宽度(字节)、传输总量。
  2. 传输准备阶段:

    • 将目标从机地址和R/W位写入I2C_SA。
    • 将本次要发送的字节数写入I2C_CNT。
    • 开启DMA总开关:I2C_BUF.XDMA_EN = 1。
    • 使能DMA通道:I2C_DMATXENABLE_SET = 1。
    • 使能必要的错误中断(如NACK,AL)和完成中断(ARDY)。
  3. 启动传输:

    • 启动DMA通道(使能DMA控制器)。
    • 向I2C_CON寄存器写入配置,并同时置位STT位,产生起始条件。
    • CPU此时可以去执行其他任务。
  4. 传输进行中:

    • I2C控制器产生起始位,发送地址。
    • 发送FIFO空,触发DMA请求,DMA搬运第一批数据(TXTRSH个字节)填入FIFO。
    • I2C控制器逐个字节发送数据,FIFO数据减少。当空闲位置再次达到TXTRSH时,再次触发DMA请求,直到所有数据搬完。
    • DMA传输完成(搬运了CNT指定的字节数)后,DMA控制器可能产生自己的完成中断。
  5. 传输结束:

    • I2C控制器发送完最后一个字节,如果I2C_CON.STP=1,则自动产生停止条件。
    • ARDY中断标志置位,如果使能了,则触发CPU中断。
    • 在ARDY中断服务程序中,清除中断标志,关闭DMA通道(I2C_DMATXENABLE_CLR = 1),并通知主程序传输完成。

6.2 常见问题排查速查表

在实际开发中,以下问题非常典型:

问题现象可能原因排查步骤与解决方案
根本收不到中断1. 中断向量表或控制器未正确配置。
2. CPU全局中断未开启。
3.I2C_IRQENABLE未正确使能。
4. 中断标志在使能前已置位且未清除。
1. 检查MCU的中断控制器配置,确保I2C中断线已映射并开启。
2. 检查CPU的全局中断使能位(如Cortex-M的PRIMASK)。
3. 单步调试,查看I2C_IRQENABLE_SET写入后的值。
4. 在使能中断前,先读取并清除I2C_IRQSTATUS_RAW。
DMA不搬运数据,总线挂起1.I2C_BUF.XDMA_EN或RDMA_EN未开启。
2.I2C_DMATX/RXENABLE_SET未写入。
3. FIFO阈值TXTRSH/RXTRSH设置不合理(如太大)。
4. DMA控制器本身未正确配置(地址、模式、使能)。
1. 确认I2C_BUF寄存器值,XDMA_EN/RDMA_EN位应为1。
2. 确认I2C_DMATXENABLE_SET等寄存器已写入1。
3. 尝试将阈值设为较小的值(如4),并确保传输开始前FIFO中有足够数据(对于TX)。
4. 使用调试器检查DMA控制器的状态寄存器,看是否有请求信号、是否使能。
出现ROVR(接收溢出)或XUDF(发送下溢)错误1. CPU/DMA处理速度跟不上I2C总线速度。
2. FIFO阈值设置过高,导致响应不及时。
3. 中断被长时间关闭或优先级太低。
4. 系统总线带宽不足,DMA传输延迟大。
1.降低I2C时钟频率,这是最直接的验证方法。
2.减小FIFO阈值,让请求更早触发。
3. 提高I2C中断或DMA的优先级。
4. 优化DMA源/目标内存位置(使用更快的内存),或减少其他高带宽外设的活动。
从机无法被唤醒1.I2C_WE寄存器未正确配置。
2. 系统未进入支持该唤醒源的低功耗模式。
3.I2C_SYSC.CLOCKACTIVITY配置错误,导致所需时钟在空闲模式下被关闭。
4. 总线上的起始条件或地址不符合预期。
1. 确认I2C_WE中对应事件位已置1。
2. 查阅芯片手册,确认当前低功耗模式是否保持I2C模块供电和时钟。
3. 对于AAS、BF等唤醒,尝试配置I2C_SYSC.CLOCKACTIVITY让功能时钟在空闲时保持活动。
4. 用逻辑分析仪抓取总线波形,检查起始条件和地址是否正确。
传输字节数不对1.I2C_CNT寄存器配置错误或在传输中被修改。
2. 在ARDY中断产生前就误判传输结束。
3. 错误处理导致传输提前终止(如NACK后未妥善恢复)。
1.严格遵守手册警告:在STT置位后、ARDY产生前,绝对不要写I2C_CNT。
2. 主程序应等待ARDY中断标志或查询I2C_IRQSTATUS.RAW的ARDY位,作为传输完成的唯一可靠标志。
3. 在NACK或AL错误中断服务程序中,要执行完整的错误恢复流程,可能包括复位I2C模块、重新初始化。

调试时,逻辑分析仪是必不可少的工具。不仅要抓取SDA/SCL波形看时序和地址数据,更要利用其同步数字通道,连接MCU的GPIO,在代码关键位置(如中断入口、DMA回调、标志位判断处)设置GPIO toggle,从而直观看到软件响应与总线事件的时序关系,这对于诊断ROVR、XUDF或唤醒失败等问题至关重要。

最后,关于I2C_SYSS.RDONE位,它指示内部复位是否完成。在任何对I2C模块进行软复位(通过I2C_SYSC.SRST)或重新使能(I2C_CON.I2C_EN从0到1)后,在访问其他寄存器前,最好先轮询此位,确保模块已准备好。虽然很多驱动库省略了这一步,但在严谨或低功耗快速唤醒的场景下,检查它是良好的习惯。

相关新闻

  • TI C2000平台异步电机无传感器FOC增量式构建与调试实战
  • HugeGraph【部署】Linux单机部署
  • 可复用项目脚手架应该包含什么

最新新闻

  • 从0到1搭建inject.dart项目:Flutter应用架构设计实例
  • 嵌入式常用第三方库部署:libcurl、sqlite、mqtt 适配
  • Kimi网页解析能力深度拆解(工程师内部调试日志首次公开)
  • HarmonyOS应用开发实战:萌宠日记 - 用Stack绘制自定义图表
  • LangGraph 深度解析:stream\_mode messages 与 values 核心区别(含HITL适配与代码实战)
  • 关于 springmvc 中的 ResponseBody 和 RequestBody 两个注解的差别

日新闻

  • AI云原生实战05-金融AI上云最难的不是技术,是“不出事“——TCE银行风控架构拆解
  • 2026年GEOSEO优化公司选型深度测评:五大硬核标准严选,这六家重塑搜索增长新格局 - 品牌前沿专家
  • **核验!2026年7月卡地亚香港**售后网点地址及服务电话公告 - 卡地亚服务中心

周新闻

  • SaaS软件行业GEO实践:AI搜索时代的品牌可见性与获客新路径
  • 什么是PCTFE?医药高端包装的“防潮王牌“材料
  • 【JVM调优实战】16-可视化利器-JConsole-VisualVM-JMC

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号