行业资讯

Tiva™ TM4C129X GPTM定时器中断:从GPTMRIS到GPTMICR的精准控制

发布时间:2026/7/27 8:33:16
Tiva™ TM4C129X GPTM定时器中断:从GPTMRIS到GPTMICR的精准控制 1. GPTM中断系统架构与核心寄存器概览在嵌入式实时系统开发中定时器中断的精准管理是衡量一个系统是否“可靠”和“实时”的关键标尺。想象一下你正在设计一个四轴飞行器的姿态控制循环或者一个工业机械臂的运动轨迹插补器系统需要在毫秒甚至微秒级别对特定事件做出响应。如果依赖软件轮询去检查“时间到了没”CPU的绝大部分精力都将浪费在无意义的等待和查询上真正的计算任务反而得不到及时处理轻则导致控制精度下降重则引发系统崩溃。硬件定时器中断机制正是为了解决这一核心矛盾而生——它让定时器这个“闹钟”在预设时间到达时主动、强硬地打断CPU当前的工作流迫使CPU立即转向处理更紧急的时间相关任务。Tiva™ TM4C129X系列微控制器内置的通用定时器模块GPTM提供了一套非常灵活且功能强大的定时与中断管理框架。而理解这套框架的“中枢神经”即中断状态与控制逻辑是进行任何高级定时应用开发的先决条件。很多开发者在初次接触时往往只关注如何配置定时周期和启动定时器却对中断产生后如何被记录、如何被筛选、以及如何被安全清除一知半解结果就是程序运行时中断行为诡异比如中断只触发一次后便“沉默”或者在不该触发的时候莫名触发调试起来令人头疼。GPTM的中断管理主要围绕三个核心状态寄存器展开它们构成了一个清晰的三级流水线GPTMRIS原始中断状态寄存器、GPTMMIS屏蔽中断状态寄存器和GPTMICR中断清除寄存器。你可以把它们理解为一个工厂的质量检测线GPTMRIS是生产线末端所有产品的原始检验报告无论好坏所有事件都被记录在案GPTMIMR中断屏蔽寄存器虽未在输入资料中详述但它是关键前提就像质检员手中的一份“免检清单”清单上的项目即使有问题也被忽略GPTMMIS则是经过“免检清单”过滤后真正需要上报给管理层CPU的“重大问题报告”而GPTMICR就是管理层批示“已处理”的盖章动作只有盖了这个章对应的报告状态才会被清空等待下一次问题出现。这个机制的精妙之处在于职责分离。GPTMRIS是纯硬件的、客观的状态记录器只要硬件事件发生如定时器溢出、匹配成功、捕获事件对应的位就会被置1它完全不受软件配置的干扰。这保证了开发者任何时候都能读到最真实的硬件状态对于调试和复杂状态机的实现至关重要。而是否将这个硬件状态转换为能惊动CPU的中断信号则由GPTMIMR和GPTMMIS共同决定。这种设计给了软件极大的灵活性你可以在不干扰硬件状态记录的前提下动态地开启或关闭某些中断源实现精细化的中断管理。注意在阅读官方数据手册时务必建立“GPTM中断信号产生与传递路径”的全局概念。路径是硬件事件 - GPTMRIS对应位置位 - 若GPTMIMR中对应中断使能未屏蔽则GPTMMIS对应位置位 - 若GPTMMIS位被置位且全局中断开启则向NVIC嵌套向量中断控制器发出中断请求 - CPU响应中断跳入中断服务程序ISR- 在ISR中通过向GPTMICR对应位写1来清除GPTMRIS和GPTMMIS中的标志位从而撤销中断请求。任何环节的误解都可能导致中断行为异常。2. 核心寄存器深度解析与位域功能要熟练驾驭GPTM中断必须像熟悉自己的手掌纹路一样熟悉这三个寄存器的每一个位。下面我们结合Tiva™ TM4C129X的实际情况进行逐位拆解并解释其在各种定时器模式下的行为差异。2.1 GPTMRIS硬件事件的忠实记录者GPTMRIS寄存器是中断流水线的源头。它是一个只读RO寄存器复位值为0x0000.0000。其每一位都直接映射到一个特定的硬件事件。关键特性在于无论GPTMIMR中断屏蔽寄存器中对应的中断是否被使能只要硬件事件发生GPTMRIS中的对应位就会被置1。这就像家里的烟雾报警器无论你是否把它的蜂鸣器线拔掉屏蔽传感器检测到烟雾硬件事件时其内部的检测状态灯GPTMRIS依然会亮起。根据输入资料GPTMRIS寄存器包含以下主要位域以Timer A和Timer B为例结构对称TATORIS (Bit 0) / TBTORIS (Bit 8):定时器超时原始中断状态。这是最常用的中断源。当定时器在单次One-Shot或周期Periodic模式下递减计数到0或递增计数到装载值GPTMTAILR/GPTMTBILR时此位被硬件置1。CAMRIS (Bit 1) / CBMRIS (Bit 9):捕获模式匹配原始中断状态。仅在输入边沿时间Input Edge-Time模式下有效。当捕获寄存器GPTMTAR/GPTMTBR的值与匹配寄存器GPTMTAMATCHR/GPTMTBMATCHR的值相等时此位置1。CAERIS (Bit 2) / CBERIS (Bit 10):捕获模式事件原始中断状态。仅在输入边沿时间Input Edge-Time模式下有效。当在配置的捕获引脚上发生有效的边沿事件上升沿或下降沿时此位置1。RTCRIS (Bit 3):实时时钟RTC事件原始中断状态。当GPTM被配置为RTC模式并发生RTC匹配事件时此位置1。TAMRIS (Bit 4) / TBMRIS (Bit 11):定时器匹配原始中断状态。在单次或周期模式下如果GPTMTAMR/TBMR寄存器中的中断使能位TAMIE/TBMIE被设置并且定时器计数值达到了匹配寄存器GPTMTAMATCHR/GPTMTBMATCHR的值此位置1。常用于产生PWM或特定时间点的中断。DMAARIS (Bit 5) / DMABRIS (Bit 13):DMA传输完成原始中断状态。当Timer A或Timer B关联的DMA传输完成时此位置1。这允许定时器事件直接触发DMA搬运数据而不占用CPU。保留位 (Bits 6-7, 12, 14-31): 必须小心处理。数据手册明确警告“软件不应依赖保留位的值。为了提供与未来产品的兼容性在读写修改操作中应保留保留位的值。”这意味着在编写代码清除中断标志时必须使用“读-修改-写”操作并且只修改目标位保留其他所有位包括保留位的原始值。直接对整个寄存器进行赋值是危险的操作。实操心得在调试时直接读取GPTMRIS的值是判断硬件是否真正产生了预期事件的“终极手段”。例如你配置了周期中断但迟迟不进中断服务程序第一步就应该检查GPTMRIS的TATORIS位是否被置1。如果它没置1说明问题出在定时器基础配置如时钟、装载值、模式或使能上如果它置1了但没进中断问题很可能出在中断屏蔽GPTMIMR或NVIC配置上。2.2 GPTMMIS通往CPU的中断网关GPTMMIS寄存器是经过筛选后的、实际能触发CPU中断的信号状态寄存器。它同样是只读的。其位的置位条件更为严格只有当GPTMRIS中某个位为1硬件事件发生且GPTMIMR中对应的中断使能位也为1中断未被屏蔽时GPTMMIS中的对应位才会被置1。GPTMMIS的位定义与GPTMRIS完全一一对应例如TATOMIS对应TATORISCAMMIS对应CAMRIS。它的值直接决定了GPTM模块是否会向微控制器的NVIC发出中断请求。因此在中断服务程序ISR中我们通常通过查询GPTMMIS或结合GPTMRIS来确定具体是哪个中断源触发了本次中断以便进行分支处理。一个至关重要的特性是GPTMMIS是一个“镜像”寄存器。向GPTMICR写入1清除某个中断标志时会同时清除GPTMRIS和GPTMMIS中的对应位。一旦GPTMMIS的位被清除即使GPTMRIS的位因新的硬件事件立即又被置1在极短时间内只要GPTMIMR使能GPTMMIS也会再次置位从而可能再次触发中断。这保证了不会丢失任何已使能的中断事件。2.3 GPTMICR状态清零的唯一下手处GPTMICR寄存器是软件干预中断状态的唯一通道。它是一个“写1清除”W1C类型的寄存器。这意味着你向某一位写入1可以清除GPTMRIS和GPTMMIS中对应的位写入0则没有任何效果。该寄存器复位值为0x0000.0000。这是中断服务程序ISR中必须执行的关键操作。通常在ISR开始处或处理完中断任务后你需要根据中断源向GPTMICR相应的位写入1来清除中断标志。如果不这样做GPTMMIS位将始终保持为1导致中断请求持续有效CPU会在退出ISR后立即再次进入同一个中断形成“中断风暴”系统将卡死在该中断中。清除操作非常简单但需要注意位对齐。例如要清除Timer A的超时中断你需要设置GPTMICR (1 0);即设置TATOCINT位。在实际编程中我们更常使用TivaWare驱动库提供的清晰接口如TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);这可以避免直接操作寄存器地址和位域的复杂性并确保对保留位的正确处理。严重警告数据手册的Note部分特别强调了一个易错点“GPTMRIS寄存器的状态不受使用GPTMCTL寄存器中的TnEN位禁用然后重新启用定时器的影响。如果应用程序要求在重新启用定时器后不应保留所有或某些状态位则应在重新启用定时器之前使用GPTMICR寄存器清除GPTMRIS寄存器中的相应位。如果不这样做GPTMRIS寄存器中设置的任何状态位以及在GPTMIMR寄存器中未屏蔽的位一旦定时器重新启用就会立即产生中断。” 这意味着如果你在程序运行中动态地关闭Disable一个定时器处理一些事情后再重新开启Enable之前积累的未处理中断标志在GPTMRIS中依然存在重新使能定时器的瞬间如果这些标志对应的中断在GPTMIMR中是使能的就会立刻触发中断。这常常导致一些非预期的、难以复现的中断行为。安全的做法是在重新使能定时器前先读取GPTMRIS然后向GPTMICR写入相应的值来清除所有可能悬而未决的标志位。3. 实战编程从寄存器配置到中断服务程序理解了原理我们通过一个完整的实例将GPTM中断的配置、启用和处理流程串联起来。我们以Tiva™ TM4C129X的Timer0A为例实现一个周期为1ms的定时中断并在中断服务程序中翻转一个LED灯。3.1 系统时钟与定时器基础配置首先我们需要启用外设的时钟。Tiva™微控制器采用外设时钟门控机制默认外设时钟是关闭的以节能。#include stdint.h #include stdbool.h #include “inc/hw_memmap.h” #include “inc/hw_types.h” #include “driverlib/sysctl.h” #include “driverlib/timer.h” #include “driverlib/interrupt.h” #include “driverlib/gpio.h” int main(void) { // 1. 配置系统时钟。假设使用主振荡器配置到120MHz。 SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_25MHZ); // 2. 启用Timer0和GPIOF假设LED在PF1的外设时钟 SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); // 等待外设就绪良好实践 while(!SysCtlPeripheralReady(SYSCTL_PERIPH_TIMER0)); while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF)); // 3. 配置PF1为输出用于驱动LED GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1);3.2 定时器初始化与中断配置接下来配置Timer0A为32位周期定时器并设置中断。// 4. 配置Timer0A为32位周期定时器 // 第一个参数定时器基地址。第二个参数配置选项。 // TIMER_CFG_PERIODIC 表示周期模式TIMER_CFG_A_ONE_SHOT等是其他模式。 TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC); // 5. 设置定时器装载值决定中断周期 // 系统时钟120MHz欲产生1ms中断则需计数 120,000,000 Hz * 0.001 s 120,000 次 // 周期模式下定时器从装载值递减到0触发中断然后重载。所以装载值 周期计数值 - 1 uint32_t ui32Period (SysCtlClockGet() / 1000) - 1; // 计算119999 TimerLoadSet(TIMER0_BASE, TIMER_A, ui32Period); // 6. 使能Timer0A的超时中断TATORIS对应的中断 // 此函数内部会操作GPTMIMR寄存器将对应的中断屏蔽位打开。 TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT); // 7. 在处理器级别NVIC使能Timer0A的中断 // 需要查数据手册或头文件确定Timer0A的中断向量号。Tiva™中TIMER0A的IRQn通常是19。 IntEnable(INT_TIMER0A); // 更通用的方法是使用IntMasterEnable()使能全局中断但通常我们精确使能所需中断。 // IntMasterEnable(); // 使能全局中断 // 8. 注册中断服务程序ISR // 将自定义函数Timer0A_ISR注册为Timer0A的中断处理器 TimerIntRegister(TIMER0_BASE, TIMER_A, Timer0A_ISR); // 9. 启动定时器 TimerEnable(TIMER0_BASE, TIMER_A);3.3 中断服务程序ISR的实现中断服务程序是中断处理的核心。它需要快速执行关键操作并清除中断标志。// Timer0A的中断服务程序 void Timer0A_ISR(void) { // 10. 在ISR入口首先清除中断标志位防止中断重入。 // 此函数内部会向GPTMICR寄存器的对应位写1清除GPTMRIS和GPTMMIS。 TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT); // 11. 执行中断任务翻转PF1引脚状态LED闪烁 uint32_t ui32CurrentState GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_1); GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, ui32CurrentState ^ GPIO_PIN_1); // 注意ISR应尽可能短小精悍避免复杂计算或阻塞调用。 // 如果需要处理复杂任务通常只在ISR中设置一个标志位在主循环中处理。 }3.4 主循环与低功耗考虑最后完成主函数。// 12. 主循环 while(1) { // 此处可以执行后台任务 // 如果ISR只设置了标志可以在这里检查并处理复杂逻辑 // 例如if(g_bTimerEvent) { ... g_bTimerEvent false; } } }这个例子展示了从零开始配置一个GPTM周期中断的完整流程。TivaWare库函数封装了底层寄存器操作让代码更易读和维护。但了解其背后操作的GPTMRIS、GPTMIMR、GPTMMIS和GPTMICR寄存器对于调试和实现更复杂的功能如PWM中断、捕获中断、DMA联动是不可或缺的。4. 高级应用场景与混合中断处理在实际项目中一个定时器模块往往需要服务于多个目的。GPTM的强大之处在于Timer A和Timer B可以独立或联合工作并产生多种中断。我们需要学会在一个中断服务程序中区分和处理多个中断源。4.1 单一定时器多中断源处理假设我们使用Timer0A同时用于周期超时中断和匹配中断例如用于产生非50%占空比的PWM并在匹配点进行某些操作。首先我们需要同时使能两种中断// 使能超时中断和匹配中断 TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT | TIMER_TIMA_MATCH);在中断服务程序中我们必须判断是哪个事件触发了中断并分别处理void Timer0A_Complex_ISR(void) { // 读取当前激活的中断状态GPTMMIS的映射 uint32_t ui32Status TimerIntStatus(TIMER0_BASE, true); // 检查并处理超时中断 if(ui32Status TIMER_TIMA_TIMEOUT) { TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT); // 处理超时任务例如系统心跳、任务调度 g_ulSystemTick; } // 检查并处理匹配中断 if(ui32Status TIMER_TIMA_MATCH) { TimerIntClear(TIMER0_BASE, TIMER_TIMA_MATCH); // 处理匹配任务例如更新PWM占空比、触发ADC采样等 // 可能涉及读取GPTMTAR和GPTMTAMATCHR进行一些计算 } // 理论上还应处理其他可能的中断源如捕获事件等 }TimerIntStatus(TIMER0_BASE, true)这个函数第二个参数为true时返回的是屏蔽后的中断状态即GPTMMIS寄存器的值。这直接告诉我们哪些已使能的中断正在请求服务。在ISR中根据这个状态字进行分支处理是标准做法。4.2 输入边沿时间模式下的中断应用输入边沿时间模式常用于测量脉冲宽度或频率。例如用Timer0A测量一个外部信号的上升沿到下降沿的时间高电平宽度。配置将定时器配置为输入边沿时间模式通常选择上升沿和下降沿都捕获如TIMER_CFG_A_CAP_TIME。中断使能使能捕获事件中断CAERIS和/或捕获匹配中断CAMRIS。捕获事件中断在每个边沿发生时触发用于记录时间戳捕获匹配中断可以用于设定一个超时防止信号丢失。ISR处理void Timer0A_Capture_ISR(void) { uint32_t ui32Status TimerIntStatus(TIMER0_BASE, true); static uint32_t ui32FirstEdgeTime 0; uint32_t ui32CurrentTime; if(ui32Status TIMER_CAPA_EVENT) { // 捕获事件中断 TimerIntClear(TIMER0_BASE, TIMER_CAPA_EVENT); ui32CurrentTime TimerValueGet(TIMER0_BASE, TIMER_A); // 读取GPTMTAR if(/* 判断是上升沿还是下降沿可通过检查引脚状态或配置区分 */) { // 假设是上升沿 ui32FirstEdgeTime ui32CurrentTime; } else { // 下降沿计算脉宽 uint32_t ui32PulseWidth ui32FirstEdgeTime - ui32CurrentTime; // 注意计数器方向 // 将计数值转换为时间微秒等 // ... } } // 处理其他中断... }这里的关键是读取GPTMTAR通过TimerValueGet来获取边沿发生的精确时刻。在边沿时间模式下GPTMTAR保存的是最后一次捕获事件发生时的定时器值。4.3 与DMA联动的中断处理GPTM的DMA完成中断DMAARIS/DMABRIS为高效数据搬运提供了可能。例如可以用定时器周期触发ADC采样并通过DMA将采样结果直接搬运到内存缓冲区当缓冲区半满或全满时触发DMA完成中断由CPU进行批处理。配置配置定时器为周期模式使能超时中断或匹配中断作为DMA触发源。配置DMA通道将源地址设为ADC结果寄存器目的地址设为内存数组设置传输数据量。中断使能使能定时器的DMA完成中断TIMER_DMA_TIMEOUT_A。ISR处理在DMA完成中断服务程序中通常不需要清除定时器本身的超时标志因为DMA传输是由硬件自动连续触发的但需要清除DMA完成中断标志并处理已经填满的数据缓冲区可能还需要切换DMA的目标缓冲区双缓冲技术。void Timer0A_DMA_ISR(void) { if(TimerIntStatus(TIMER0_BASE, true) TIMER_DMA_TIMEOUT_A) { TimerIntClear(TIMER0_BASE, TIMER_DMA_TIMEOUT_A); // 处理DMA传输完成后的数据例如标记缓冲区就绪、切换缓冲区等 g_bBufferReady true; } }这种模式将CPU从频繁的ADC数据搬运中解放出来极大地提高了系统效率特别适用于高速数据采集应用。5. 调试技巧与常见问题排查实录即使理解了所有原理在实际调试中GPTM中断仍然可能表现出各种“脾气”。下面是我在多年项目中总结的一些典型问题场景和排查思路整理成速查表希望能帮你快速定位问题。问题现象可能原因排查步骤与解决方法中断根本进不去1. 定时器未正确使能TnEN位。2. 中断在GPTMIMR寄存器中未使能。3. NVIC中对应中断向量未使能。4. 全局中断未开启PRIMASK等。5. 装载值GPTMTAILR设置过大或为0导致超时事件“遥遥无期”或立即连续发生。1.检查GPTMCTL寄存器确认TIMER_A/B的TnEN位已置1。使用TimerEnable()。2.检查GPTMIMR寄存器确认对应中断类型位已置1。使用TimerIntEnable()并检查参数。3.检查NVIC使用IntEnable(INT_TIMER0A)等函数并确认中断向量号正确。4.检查全局中断调用IntMasterEnable()。在调试器中可以查看PRIMASK寄存器。5.检查装载值与时钟计算预期中断周期对应的计数值是否正确。使用TimerLoadGet()读取确认。中断只触发一次1.单次模式配置成了单次One-Shot模式而非周期Periodic模式。2.中断标志未清除在ISR中忘记清除GPTMICR导致GPTMMIS保持为1CPU认为中断持续 pending无法响应新的边沿触发。3.在ISR中错误地禁用了定时器或中断。1.检查定时器配置模式TimerConfigure()的参数是否正确TIMER_CFG_PERIODIC。2.检查ISR确保第一或第二条语句就是TimerIntClear()且参数正确。3.审查ISR代码确保没有调用TimerDisable()或TimerIntDisable()。中断频率不正确1. 系统时钟SysClk配置错误导致定时器时钟源频率不对。2. 装载值计算错误。3. 分频器Prescaler配置有误。GPTMTAPR/TBPR寄存器被意外设置。4. 使用了32位模式但误操作了16位寄存器或反之。1.验证系统时钟使用SysCtlClockGet()获取实际频率与预期对比。2.重新计算装载值周期模式装载值 (时钟频率 / 期望中断频率) - 1。3.检查GPTMTAPR/TBPR如果不需分频确保其值为0。使用TimerPrescaleSet()检查。4.确认模式一致性32位模式下操作GPTMTAILR等寄存器16位独立模式下分别操作Timer A和Timer B的寄存器。进入中断后无法退出系统卡死1.中断标志未清除最常见。GPTMMIS位持续为1导致中断请求不断重入。2. ISR执行时间过长导致其他更高优先级中断被饿死或触发了看门狗。3. 在ISR中发生了另一个未被正确处理的中断导致嵌套或死锁。1.确认ISR中清除了正确的标志。使用TimerIntClear()并传入在TimerIntStatus()中读到的状态。2.优化ISR只做最必要的操作如设置标志、清除标志将耗时任务移到主循环。3.检查中断优先级避免在ISR中操作可能触发其他中断的外设。检查是否有未处理的中断源。动态启停定时器时产生意外中断未在重新使能定时器前清除悬而未决的中断标志。这是数据手册特别警告的陷阱。在调用TimerEnable()之前先调用TimerIntClear()清除该定时器所有可能的中断标志。例如TimerIntClear(TIMER0_BASE, TIMER_TIMB_TIMEOUTGPTMRIS有值但GPTMMIS为0不进中断中断在GPTMIMR中被屏蔽了。这是GPTMRIS和GPTMMIS的核心区别体现。检查并确保已通过TimerIntEnable()使能了目标中断类型。读取GPTMIMR寄存器确认对应位为1。在输入捕获模式下捕获中断不触发1. 定时器未配置为输入捕获模式。2. 捕获引脚复用功能未正确配置。3. 边沿触发方向配置错误。4. 捕获事件发生时定时器可能未运行。1.确认模式使用TimerConfigure()并指定TIMER_CFG_A_CAP_TIME等模式。2.检查GPIO配置使用GPIOPinTypeTimer()或GPIOPinConfigure()将引脚配置为定时器捕获功能。3.检查边沿配置使用TimerControlEvent()设置上升沿、下降沿或双边沿。4.确保定时器已启动调用TimerEnable()。调试时善用调试器的外设寄存器查看窗口是最高效的手段。直接观察GPTMRIS、GPTMIMR、GPTMMIS、GPTMICR以及GPTMCTL等寄存器的实时值可以让你清晰地看到中断信号的产生、屏蔽、上报和清除的全过程很多逻辑问题一目了然。同时在ISR入口设置断点观察是否触发以及观察TimerIntStatus()的返回值能快速定位问题根源。最后再分享一个关于中断清除的小技巧有些开发者喜欢在ISR一开始就清除所有可能的中断标志像这样TimerIntClear(TIMER0_BASE, 0xFFFFFFFF);。这种做法在简单应用中可能没问题但存在风险。如果在你清除标志后、退出ISR前同一个定时器又发生了另一个不同类型的中断事件虽然概率低但在高频率或复杂场景下可能发生这个新事件的中断标志会被设置但由于你清除了所有标志这个新事件可能会被丢失。更稳健的做法是只清除你检测到并处理了的那些中断标志即用TimerIntStatus()读取到的状态值作为TimerIntClear()的参数TimerIntClear(TIMER0_BASE, ui32Status);。这确保了只清除已响应的中断保留了可能同时发生的其他中断状态让它们能在下一轮得到处理。