1. 系统定时器(SYSTIM)在嵌入式系统中的核心地位
在嵌入式开发,尤其是涉及无线通信、实时控制或低功耗管理的项目中,精准的时间控制不是“锦上添花”,而是“雪中送炭”。无论是Wi-Fi信标间隔的维持、蓝牙连接事件的同步,还是传感器数据的周期性采样,其底层都依赖于一个可靠且高精度的硬件定时器。CC35xx系列无线MCU内置的系统定时器(SYSTIM)模块,正是为满足这类严苛的时序需求而设计的核心外设。它不仅仅是一个简单的计数器,更是一个集成了高分辨率计时、双通道独立事件管理以及灵活中断触发机制的精密时间引擎。
与常见的通用定时器(GPT)或看门狗定时器(WDT)不同,SYSTIM的设计目标非常明确:为系统CPU以及Wi-Fi和蓝牙低功耗(BLE)核心提供一个统一、同步且高精度的时间基准。它的基础分辨率达到了250纳秒,虽然绝对计时范围相对有限(约1.2小时),但这恰恰体现了其设计哲学——在关键的活跃工作时段内,提供无与伦比的计时精度。想象一下,在协调Wi-Fi的TX/RX时序和BLE的广告/扫描窗口时,几微秒的偏差都可能导致数据包碰撞或连接失败,此时SYSTIM的250ns精度就显得至关重要。
SYSTIM与实时时钟(RTC)模块紧密协作。RTC像是一个走时缓慢但持久耐用的挂钟,负责在设备休眠(SLEEP)和活跃(ACTIVE)状态下维持一个长跨度的时间基准(可达数十年)。而SYSTIM则像一块高精度的秒表,在设备进入ACTIVE状态后,立即从RTC同步时间,并以更高的分辨率“滴答”运行。这种分工使得系统既能实现超低功耗的长时间待机(依靠RTC),又能在需要高性能处理时获得精确的微秒乃至纳秒级时间控制(依靠SYSTIM)。
对于嵌入式软件工程师、固件开发者和系统架构师而言,深入理解SYSTIM的工作机制、寄存器配置以及最佳实践,意味着能够更高效地开发出响应迅速、时序准确且功耗优化的产品。本文将基于TI CC35xx的官方技术手册,结合实际的嵌入式开发经验,为你深入剖析SYSTIM的方方面面,从模块概述、功能描述到每一个关键寄存器的实战配置,并分享在调试过程中容易遇到的“坑”和解决技巧。
2. SYSTIM架构与核心功能深度解析
2.1 整体架构与工作模式
SYSTIM模块的核心是一个34位的向上计数器,其时钟源来自于系统时钟(SOC CLK)。它提供两种时间读取方式,对应不同的分辨率:
- TIME250N寄存器:读取计数器低32位,提供250纳秒的分辨率。这是SYSTIM的最高精度模式。
- TIME1U寄存器:读取计数器高32位(实际上是bit[33:2]),提供1微秒的分辨率。这种设计方便了不同精度需求的场景。
模块包含两个独立通道:通道0和通道1。这是SYSTIM灵活性的关键。通道0完全开放给用户应用程序使用,并且可以配置为1μs或250ns两种分辨率。通道1则通常预留给TI的底层无线协议栈软件(例如Wi-Fi 6和BLE的时序调度),固定为1μs分辨率,用户一般无需直接配置,但了解其存在有助于理解系统资源分配。
每个通道都可以独立工作在两种基本模式:
- 比较模式:当SYSTIM的计数器值达到用户预设的比较值时,硬件会自动触发一个事件或中断。这用于实现精确定时、生成PWM波形或调度周期性任务。
- 捕获模式:当指定的外部事件(通过事件管理器路由进来)发生时,硬件会瞬间将当前的SYSTIM计数器值“抓取”并保存到对应通道的捕获寄存器中。这用于精确测量外部脉冲的宽度、频率或事件发生的时间戳。
2.2 与RTC的同步机制详解
SYSTIM的时间并非“无源之水”。在设备从SLEEP或SHUTDOWN状态唤醒进入ACTIVE状态时,SYSTIM的初始值是从RTC加载的。更重要的是,在ACTIVE状态下,两者会持续同步。这个同步过程对保证整个系统时间基的准确性至关重要。
具体是如何同步的呢?RTC运行在32.768kHz的低频时钟(LFCLK)上,它会产生一个叫LFTICK的信号。SYSTIM模块内部有一个同步逻辑,会接收这个LFTICK信号以及RTC的TIME比特流。SYSTIM利用这些信息来校准自己的高速时钟计数,消除由于时钟源频率微小偏差带来的累积误差。你可以通过STA寄存器的SYNCUP位来观察同步状态。上电或复位后,该位为1,表示正在进行首次同步。首次同步完成后,该位清零。你也可以通过向STA寄存器写入任何值(实际是触发一个写操作)来手动请求一次重新同步。
注意:理解SYSTIM与RTC的关系,是避免时间漂移问题的关键。在设计长时间运行的精确延时或定时任务时,不能假设SYSTIM的时钟是绝对完美的。虽然同步机制在很大程度上保证了准确性,但在极端温度变化或时钟源不稳的情况下,了解这一机制有助于你定位一些“诡异”的时序漂移问题。
2.3 事件与中断管理逻辑
SYSTIM的事件和中断系统是其能够响应外部世界的“神经末梢”。其设计遵循了典型的中断控制器模式,清晰且易于管理。
每个通道(0和1)都有自己独立的事件输出。此外,还有一个组合事件输出,它包含了两个通道的事件以及一个定时器溢出事件。这个溢出事件在34位计数器回滚时触发,并会持续置位约4秒,为软件处理溢出情况提供了充足的时间窗口。
中断的管理通过一组寄存器进行,层次分明:
- RIS:原始中断状态寄存器。任何通道事件或溢出事件发生,对应的位就会置1,无论该中断是否被屏蔽。它反映了最底层的硬件状态。
- IMASK/IBM:中断屏蔽寄存器。你可以通过
IMSET和IMCLR寄存器来设置或清除这里的位。如果某个事件对应的屏蔽位为0,即使RIS置位,也不会产生CPU中断。 - MIS:已屏蔽的中断状态寄存器。这是
RIS & IMASK的结果。只有MIS寄存器中为1的位,才会最终触发到CPU的中断线。在中断服务程序(ISR)中,通常应该查询MIS而非RIS。 - ISET/ICLR:中断设置与清除寄存器。
ISET允许软件模拟一个事件来触发中断,这在诊断和自测试中非常有用。ICLR用于清除RIS中的标志位。手册中特别指出,在捕获模式下读取捕获值,或在比较模式下写入新的比较值,也会自动清除对应通道的RIS标志,这个机制可以有效避免软件在清除标志和硬件自动清除之间产生竞争条件。
实操心得:在编写中断服务程序时,一个稳健的做法是:首先读取
MIS值来判断是哪个中断源触发,处理完成后,先读取必要的状态或数据(如在捕获模式下读取捕获寄存器),然后再向ICLR寄存器写入相应的位来清除RIS标志。这个顺序可以利用硬件自动清除机制,有时可以简化代码逻辑,避免重复清除。
3. 通道配置与工作模式实战指南
3.1 比较模式配置与“立即触发”特性
将通道配置为比较模式是SYSTIM最常用的功能之一。操作非常直接:向SYSTIM.CHnCC寄存器(n为0或1)写入任何一个非零的比较值,该通道便会自动进入比较模式并开始工作。当SYSTIM的计数器值(TIME)达到或超过你设定的比较值时,硬件就会触发一个比较事件。
这里有一个非常重要的细节,称为“立即触发”或“过去事件触发”。如果软件写入的比较值CMP满足条件:0 <= (TIME - CMP) < 2^22,那么比较事件会立即触发。
- 对于通道0(可配置为250ns分辨率):这个时间窗口大约是
2^22 * 250ns ≈ 1.048576秒。意味着如果你设置了一个比当前时间晚不到1.05秒,或者甚至是过去(但不超过1.05秒)的时间点,事件会立刻产生。 - 对于通道1(固定1μs分辨率):时间窗口是
2^22 * 1μs ≈ 4.194304秒。
这个特性的设计非常巧妙。它确保了即使软件因为调度延迟等原因,设置的定时点稍微“过期”了,系统也能立刻得到通知,而不是傻傻地等待一个永远不会到来的未来时间点。这在实现超时机制时特别有用。
配置示例:使用通道0实现一个100微秒后触发的单次定时假设SYSTIM已使能并运行,我们想用通道0在100微秒后触发一个事件。
- 计算比较值:首先读取当前的
TIME1U值(1μs分辨率)。假设读到的值是current_time。 - 设置比较值:
target_time = current_time + 100。因为TIME1U单位是1μs,所以加100就是100μs。 - 写入寄存器:将
target_time写入SYSTIM.CH0CC寄存器。写入操作会自动将通道0武装为比较模式。 - 等待事件:你可以通过轮询
SYSTIM.OUT寄存器的OUT0位,或者使能通道0中断并等待中断发生,来检测定时是否完成。
// 伪代码示例 uint32_t current_time = HWREG(SYSTIM_BASE + SYSTIM_O_TIME1U); // 读取当前时间(1us) uint32_t target_time = current_time + 100; // 100微秒后 HWREG(SYSTIM_BASE + SYSTIM_O_CH0CC) = target_time; // 写入比较值,通道自动武装 // 方式一:轮询方式 while (!(HWREG(SYSTIM_BASE + SYSTIM_O_OUT) & 0x01)) { // 等待OUT0位变为1 } // 方式二:中断方式(需提前配置好中断控制器和IMASK) // 在中断服务程序中检查并处理事件3.2 捕获模式配置与触发条件
捕获模式用于测量外部事件的精确发生时刻。配置步骤如下:
- 配置输入事件路由:这不是SYSTIM本身的寄存器,而是需要通过事件管理器来配置。你需要设置
SOC_AON.TMEVTCTL寄存器中的SYSTIM0或SYSTIM1位域,将某个外部信号(如GPIO边沿、另一个定时器输出等)路由到SYSTIM通道的输入。 - 设置捕获边沿:通过
SYSTIM.CHnCFG寄存器的INP位域(bit[2:1])选择捕获条件:00:上升沿捕获01:下降沿捕获10:双边沿(上升和下降)捕获
- 武装捕获通道:将
SYSTIM.CHnCFG寄存器的MODE位(bit 0)设置为1。此时通道进入“待捕获”状态。 - 等待与读取:当配置的输入事件边沿到来时,硬件会立即将当前的
SYSTIM.TIME值锁存到SYSTIM.CHnCC寄存器中,并产生一个捕获事件(置位RIS)。此时,MODE位会被硬件自动清零,通道解除武装(除非使能了重武装)。软件可以通过中断或轮询RIS/OUT寄存器来获知捕获完成,然后读取CHnCC寄存器得到时间戳。
重武装功能:CHnCFG寄存器中的REARM位(bit 3)控制此功能。若REARM=1,则在一次捕获发生后,通道会保持在捕获模式,等待下一个事件,实现连续捕获。若REARM=0,则为单次捕获模式,捕获一次后自动退出。
3.3 灵活的武装与解除武装机制
除了通过写CHnCC(比较模式)和设置MODE位(捕获模式)来武装通道外,SYSTIM还提供了更灵活的ARMSET和ARMCLR寄存器。
ARMSET寄存器:向某通道对应的位写1,可以将其武装。其行为有智能判断:- 如果通道当前未武装(
ARMSTA[x]==0),则无效果。 - 如果通道已处于捕获模式,则无效果。
- 否则,将通道设置为比较模式,并使用该通道
CHnCC寄存器中现有的值作为比较值。这在你需要预先加载一个比较值,但不想立即启动定时器时非常有用。你可以先写入CHnCCSR(别名寄存器,写入不影响通道状态),然后在合适的时机通过ARMSET启动定时。
- 如果通道当前未武装(
ARMCLR寄存器:向某通道对应的位写1,可以立即解除该通道的武装,使其进入未武装状态,且不会触发事件(除非解除武装操作与比较/捕获事件发生在同一周期,这是一种极端的边界情况)。
CHnCCSR寄存器的妙用:这个寄存器是CHnCC的“别名”。读它等同于读CHnCC,但写它只会更新比较值,而不会改变通道的当前状态(武装/未武装、模式)。这在你需要动态更新一个正在运行的比较定时器,或者预先加载一个值以备后用时会非常方便,避免了直接写CHnCC可能导致的意外触发或状态改变。
4. 关键寄存器详解与配置流程
4.1 控制与状态寄存器组
这一组寄存器负责SYSTIM的全局控制和状态查询。
SYSTIM_CTRL(Offset 0x8):MEM_SYSTIM_ENCLK(Bit 0):这是SYSTIM模块的时钟门控使能位。必须将此位置1,SYSTIM的计数器才能开始运行,否则所有寄存器访问可能无效或模块不工作。通常在系统初始化早期设置。
CLKCFG(Offset 0x1000):EN(Bit 0):系统定时器时钟使能位。功能与MEM_SYSTIM_ENCLK类似,是另一个层级的控制。根据经验,两者通常都需要使能。
STA(Status Register, Offset 0x140):VAL(Bit 0):系统定时器运行状态位。0表示定时器未运行,1表示正在运行。在使能时钟后,可以查询此位确认定时器已启动。SYNCUP(Bit 4):同步状态位。上电复位后为1,表示正在与RTC进行初始同步。同步完成后自动清零。向该寄存器写任何值可手动触发一次重新同步。
初始化流程示例:
void SYSTIM_Init(void) { // 1. 使能SYSTIM模块时钟请求(通常在电源与时钟管理模块中配置) // 2. 使能SYSTIM时钟 HWREG(SYSTIM_BASE + SYSTIM_O_CLKCFG) |= 0x01; // 设置CLKCFG.EN = 1 // 3. 可选:等待SYSTIM与RTC同步完成(如果对初始时间绝对精度要求高) while (HWREG(SYSTIM_BASE + SYSTIM_O_STA) & 0x10) { // 等待SYNCUP位清零 } // 此时,SYSTIM的TIME寄存器已经开始递增,可以开始使用 }4.2 通道配置寄存器详解
每个通道都有自己的配置寄存器CHnCFG,结构如下(以通道0的CH0CFG为例):
| 位域 | 名称 | 类型 | 复位值 | 描述 |
|---|---|---|---|---|
| 4 | RES | R/W | 0 | 分辨率选择(仅通道0有效)。0:通道使用定时器的1μs分辨率。1:通道使用定时器的250ns分辨率。通道1固定为1μs。 |
| 3 | REARM | R/W | 0 | 重武装使能。0:禁用,捕获模式为单次触发。1:使能,捕获模式为连续触发。 |
| 2:1 | INP | R/W | 00 | 输入捕获边沿选择。00:上升沿捕获。01:下降沿捕获。10:双边沿捕获。11:保留。 |
| 0 | MODE | R/W | 0 | 通道模式选择。0:通道禁用(未武装)。1:通道使能并进入捕获模式。注意:写CHnCC寄存器会自动进入比较模式,不受此位控制。 |
配置示例:设置通道0为双边沿捕获、连续模式、250ns分辨率
// 假设要配置通道0 uint32_t cfg_value = 0; cfg_value |= (1 << 4); // RES=1, 选择250ns分辨率 cfg_value |= (1 << 3); // REARM=1, 使能连续捕获 cfg_value |= (2 << 1); // INP=2, 双边沿捕获 cfg_value |= (1 << 0); // MODE=1, 使能捕获模式(武装通道) HWREG(SYSTIM_BASE + SYSTIM_O_CH0CFG) = cfg_value; // 注意:此时还需要通过事件管理器将外部信号路由到SYSTIM0输入4.3 时间读取与比较值寄存器
TIME250N(Offset 0x100):读取获得系统定时器计数值的低32位,单位为250ns。这是获取最高精度当前时间的寄存器。TIME1U(Offset 0x104):读取获得系统定时器计数值的高32位(bit[33:2]),单位为1μs。适用于对精度要求稍低,但需要更宽数值范围的场景。CHnCC(Offset 0x120, 0x124):通道比较/捕获寄存器。在比较模式下,写入目标时间值。在捕获模式下,捕获事件发生后,从这里读取时间戳。CHnCCSR(Offset 0x14C, 0x150):通道比较/捕获影子寄存器。功能上与CHnCC相同,但写入操作不会改变通道状态,仅更新比较值。用于安全地更新一个已武装的比较定时器。
读取当前时间的注意事项:由于TIME250N和TIME1U是两个独立的32位寄存器,而计数器是34位的,直接读取可能会在高低位之间发生进位导致读数错误。标准的做法是连续读取两次TIME1U,如果两次读取值相同,则认为读取有效;如果不同,则需要重新读取。对于需要34位完整值的情况,需要将TIME1U左移2位后与TIME250N的高2位组合。
uint64_t SYSTIM_GetTime64(void) { uint32_t time1u_high, time1u_low; uint32_t time250n; do { time1u_high = HWREG(SYSTIM_BASE + SYSTIM_O_TIME1U); time250n = HWREG(SYSTIM_BASE + SYSTIM_O_TIME250N); time1u_low = HWREG(SYSTIM_BASE + SYSTIM_O_TIME1U); } while (time1u_high != time1u_low); // 确保读取期间高位没有溢出 // 组合成64位时间(单位:250ns) // TIME1U 是 bit[33:2],所以需要左移2位 // TIME250N 是 bit[31:0] uint64_t full_time = ((uint64_t)time1u_high << 2) | ((time250n >> 30) & 0x03); // 注意:这里获取的只是34位中的高32位和低32位组合后的近似64位值, // 实际上TIME250N的高2位(bit[31:30])与TIME1U的低2位(bit[1:0])是重叠的, // 上述代码是一种拼接方式。更精确的做法需参考芯片勘误或用户指南。 return full_time; }4.4 中断管理寄存器组
这组寄存器用于精细控制中断的产生和响应,前文已概述其功能,下表汇总其作用:
| 寄存器 | 偏移地址 | 主要功能 |
|---|---|---|
IBM/IMASK | 0x44 | 中断屏蔽寄存器。位0/1/6分别对应EVT0/EVT1/OVFL事件。0=屏蔽,1=允许。 |
RIS | 0x48 | 原始中断状态。事件发生即置1,不受屏蔽影响。 |
MIS | 0x4C | 已屏蔽的中断状态。RIS & IMASK的结果,真正触发CPU中断的来源。 |
ISET | 0x50 | 中断设置寄存器。写1可软件模拟事件,用于测试。 |
ICLR | 0x54 | 中断清除寄存器。写1清除RIS中对应的标志位。 |
IMSET | 0x58 | 中断屏蔽设置寄存器。写1将IMASK对应位置1(允许中断)。 |
IMCLR | 0x5C | 中断屏蔽清除寄存器。写1将IMASK对应位置0(屏蔽中断)。 |
典型的中断服务程序(ISR)流程:
- 进入ISR,读取
MIS寄存器值mis_status。 - 根据
mis_status判断中断源(EVT0, EVT1, OVFL)。 - 如果是通道事件(EVT0/EVT1):
- 若为比较模式:处理定时任务。
- 若为捕获模式:立即读取
CHnCC寄存器获取时间戳(此操作可能自动清除RIS)。
- 如果是溢出事件(OVFL):处理34位计数器回滚,可能需要软件维护一个扩展的高位计数器。
- 向
ICLR寄存器写入mis_status值,清除已处理的中断标志。 - 中断返回。
5. 实战应用场景与常见问题排查
5.1 应用场景分析
- 高精度延时与定时:这是SYSTIM最基本的功能。利用比较模式,可以实现微秒甚至亚微秒级别的精准延时。例如,在驱动特定传感器时,需要满足严格的时序要求,如启动后等待100.5μs再读取数据。使用通道0的250ns模式,可以轻松实现。
- 脉冲宽度测量:利用捕获模式的双边沿触发,可以精确测量一个脉冲的高电平和低电平时间。首先配置为双边沿捕获,并使能重武装(
REARM=1)。第一次捕获到上升沿时记录时间T1,第二次捕获到下降沿时记录时间T2,脉冲宽度即为(T2 - T1)。此方法精度远高于软件轮询GPIO。 - 事件时间戳:在复杂的实时系统中,记录某个外部事件(如按键按下、数据包到达)发生的绝对时间至关重要。将该事件通过事件管理器路由到SYSTIM捕获通道,即可在事件发生时自动打上高精度的时间戳,便于后续分析和调试。
- 周期性任务调度:在比较事件的中断服务程序中,重新设置下一个比较点(
CHnCC += period),即可实现一个高精度的周期性定时器。注意处理计数器溢出的情况。 - 与无线协议栈协同:通道1通常被TI的无线协议栈占用,用于调度Wi-Fi和BLE的射频活动。用户程序应避免冲突使用。理解这一点有助于在调试无线功能时,知道系统底层有一个高精度定时器在忙碌。
5.2 常见问题与调试技巧
问题1:配置了SYSTIM,但定时器似乎没有运行,读TIME寄存器值不变。
- 排查步骤:
- 检查时钟:确认
SYSTIM_CTRL.MEM_SYSTIM_ENCLK和CLKCFG.EN是否都已置1。这是最常见的原因。 - 检查电源状态:SYSTIM仅在设备ACTIVE状态下工作。确保设备未进入SLEEP或SHUTDOWN。
- 查询状态:读取
STA.VAL位,确认是否为1(运行中)。 - 检查同步:如果
STA.SYNCUP一直为1,可能是与RTC同步有问题,检查RTC模块是否正常初始化。
- 检查时钟:确认
问题2:比较事件没有触发,或者触发时间不准确。
- 排查步骤:
- 检查比较值:确认写入
CHnCC的值是相对于TIME1U或TIME250N的绝对时间,而不是一个间隔值。常见的错误是将“延时100μs”理解为CHnCC = 100,正确的做法是CHnCC = current_TIME1U + 100。 - 检查分辨率:对于通道0,确认
CH0CFG.RES位设置是否符合预期。如果你按1μs计算却配置了250ns模式,实际定时时间会是预期的1/4。 - 检查中断/事件使能:如果使用中断,检查
IMASK寄存器对应位是否已置1(允许中断),以及CPU的中断控制器是否已正确配置和使能。如果使用轮询,检查OUT寄存器或RIS寄存器。 - 注意“立即触发”窗口:如果你设置的比较值落在“过去事件触发”的窗口内(通道0约1秒,通道1约4秒),事件会立即触发。这可能是你感觉“不准确”或“立刻触发”的原因。
- 检查比较值:确认写入
问题3:捕获功能不工作,读不到捕获值。
- 排查步骤:
- 检查事件路由:这是最关键的一步。SYSTIM的捕获输入依赖于事件管理器。确保
SOC_AON.TMEVTCTL寄存器中对应的SYSTIM0或SYSTIM1位域已正确配置,将所需的外部事件信号路由进来。 - 检查捕获边沿:确认
CHnCFG.INP位设置与输入信号的边沿一致。 - 检查通道模式:确认已通过设置
CHnCFG.MODE=1或使用ARMSET寄存器武装了通道为捕获模式。 - 检查重武装设置:如果是单次捕获(
REARM=0),一次捕获后通道会自动解除武装。如果需要连续捕获,需设置REARM=1。 - 验证信号:使用逻辑分析仪或示波器,确认预期的边沿事件确实到达了MCU的相应引脚。
- 检查事件路由:这是最关键的一步。SYSTIM的捕获输入依赖于事件管理器。确保
问题4:在中断服务程序中,中断标志似乎无法彻底清除,导致重复进入中断。
- 排查步骤:
- 遵循正确的清除顺序:如前所述,在捕获模式下,读取捕获寄存器(
CHnCC)的操作可能会自动清除RIS标志。如果你先清了ICLR,再读CHnCC,可能没问题。但如果你先读了CHnCC,标志已被清,再写ICLR可能就是多余操作。最安全的方法是:在ISR开始时,读取MIS和RIS备份,然后进行业务处理(包括读捕获值),最后根据备份的RIS值写ICLR。 - 检查中断嵌套与优先级:确保没有更高优先级的中断长时间阻塞,导致当前ISR尚未清除标志,同一中断源又产生了新的事件。
- 检查软件触发:是否意外地写入了
ISET寄存器,导致软件模拟了事件。
- 遵循正确的清除顺序:如前所述,在捕获模式下,读取捕获寄存器(
问题5:长时间运行后,定时出现累积误差。
- 排查思路:SYSTIM的时钟源可能存在微小漂移。虽然它与RTC同步,但同步频率和精度有限。对于需要极长期、极高精度定时的应用(如每小时误差小于1秒),可能需要结合软件校准算法,或者使用更稳定的外部时钟源。同时,确保设备不要频繁在ACTIVE和SLEEP间切换,因为每次唤醒的同步过程可能引入微小误差。
调试技巧:充分利用
OUT寄存器(Offset 0x108)。它的OUT0和OUT1位直接反映了通道0和通道1的事件输出电平。在调试时,可以轮询或通过GPIO映射这个事件输出来用示波器观察,非常直观地判断定时器是否按预期触发,这比单步调试中断服务程序更高效。