ARM7 LPC21xx/22xx定时器与PWM模块:从寄存器到电机驱动的实战指南

ARM7 LPC21xx/22xx定时器与PWM模块:从寄存器到电机驱动的实战指南 1. 定时器与PWM模块的核心价值与设计哲学在嵌入式开发领域尤其是基于ARM7架构的LPC21xx/22xx这类经典微控制器定时器和PWM脉宽调制模块的掌握程度往往是区分“能跑代码”和“精通底层”工程师的一道分水岭。很多新手拿到芯片手册看到满屏的寄存器位描述常常感到无从下手。实际上这些寄存器并非随意堆砌其背后是一套精密的硬件状态机设计逻辑。理解这套逻辑你就能像指挥交响乐团一样让定时器精准地为你工作无论是产生一个毫秒级的中断还是驱动一个精密的伺服电机。LPC21xx/22xx的定时器Timer 0/1和PWM模块其本质是一个可编程的“时间引擎”。它的核心是一个由系统时钟PCLK驱动的32位计数器。通过预分频器Prescaler我们可以灵活地调节这个“引擎”的转速以适应从微秒到数秒的不同定时需求。而匹配Match和捕获Capture功能则是这个引擎上的两套“触发器”和“记录仪”。匹配功能允许我们在计数器到达特定值时触发动作如产生中断、复位计数器或改变引脚电平这是实现定时、PWM输出的基础。捕获功能则允许我们在外部引脚发生特定跳变时“抓拍”下当前计数器的值常用于测量脉冲宽度或频率。PWM模块更是定时器功能的集大成者。它在标准定时器的基础上增加了多路、灵活的波形生成逻辑。最厉害的是它支持单边沿和双边沿控制模式。单边沿模式简单直接所有PWM通道的上升沿对齐通过控制下降沿位置来调节占空比常见于LED调光、简单的直流电机调速。而双边沿模式则允许独立控制脉冲的上升沿和下降沿位置可以生成中心对齐、相位可调的复杂波形这是实现三相电机无刷驱动、精密电源转换如逆变器的关键。理解这些模块你就能在资源有限的单片机上实现许多看似需要FPGA才能完成的复杂时序控制任务。2. 核心寄存器深度解析与配置逻辑要驾驭LPC21xx/22xx的定时器与PWM必须吃透几个核心寄存器。它们就像控制面板上的旋钮和按钮每一个位的设置都直接决定了硬件的行为。这里我们抛开手册的平铺直叙从功能逻辑的角度重新梳理。2.1 定时器的“大脑”控制与状态寄存器定时器控制寄存器TCR是整个定时器的开关和复位键。它只有两个有效控制位位0Counter Enable这是总开关。置1预分频计数器PC和定时器计数器TC开始累加清0计数器冻结。一个关键细节在修改很多其他寄存器如匹配寄存器MR、外部匹配控制EMR之前最好先关闭计数器TCR[0]0配置完成后再开启以避免在配置过程中产生不可预期的匹配事件和输出 glitch。位1Counter Reset这是同步复位键。置1后在下一个PCLK上升沿TC和PC会被同步清零。特别注意这是一个“瞬时”操作位。手册要求在发出复位命令写1后应尽快将其清零写0。通常的编程模式是TCR (11); TCR 0;先复位再清复位位并保持停止状态或者TCR (11) | (10); TCR (10);复位并立即启动。中断寄存器IR是中断状态的“指示灯”和“清除按钮”。它有8个位对应4个匹配中断MR0-MR3和4个捕获中断CR0-CR3。当硬件因匹配或捕获事件产生中断时对应的位会自动置1。这里有一个非常重要的硬件特性清除中断标志不是靠写0而是靠写1也就是说在中断服务程序ISR里你需要执行类似T0IR (10);的操作来清除MR0中断标志。如果错误地写0中断标志将永远无法清除导致一次触发后持续进入中断系统卡死。这是新手常踩的一个坑。2.2 定时器的“心脏”计数器与分频器预分频寄存器PR和预分频计数器PC共同决定了定时器的基本时间分辨率。它们的工作原理是PC在每个PCLK周期加1当PC的值等于PR的值时在下个PCLK周期TC加1同时PC被清零。因此TC计数一次的周期 (PR 1) 个 PCLK 周期。计算公式定时时间 (PR 1) * (MR匹配值 1) / PCLK频率例如PCLK 60MHz需要产生1ms的定时中断。若设置PR59999则PC每计数60000个PCLK周期TC才加1此时TC的计数频率为 60MHz / 60000 1kHz。若再设置MR00则TC从0加到0即每次加1就匹配匹配频率就是1kHz周期为1ms。若设置MR0999则TC需要从0加到1000才匹配定时周期就是 1000 * 1ms 1秒。关键经验PR和MR都是32位寄存器理论定时范围极大。但在计算时要注意溢出问题。当PR设置为0xFFFFFFFF最大值时分频系数巨大TC几乎不计数可用于实现超长定时。但更常见的做法是使用较小的PR值获得较高的TC计数频率然后利用MR实现较长的定时周期这样定时精度更高因为MR可以随时更改而更改PR可能会影响正在进行的计数周期。2.3 定时器的“触发器”匹配与捕获系统匹配控制寄存器MCR为每个匹配通道MR0-MR3定义了“当匹配发生时要做什么”。每个通道占用3个位中断位MRnI置1匹配时产生中断。复位位MRnR置1匹配时复位TC。这是实现周期性定时的关键。通常MR0会设置此位让TC在匹配时归零从而形成一个固定的定时周期。其他MRx如果也设置了复位会覆盖MR0的复位吗不会任何一个匹配事件发生只要其复位位使能TC都会被复位。停止位MRnS置1匹配时停止计数器TCR[0]清零。这用于实现单次定时。比如启动一个测量定时时间到后自动停止计数器然后去读取TC的值。外部匹配寄存器EMR是连接内部匹配事件与外部引脚MATn.0-3的桥梁。它的低4位EM0-EM3反映了对应MAT引脚的电平状态。高位的控制位EMC0-EMC3每通道2位决定了匹配发生时引脚的动作00无动作。引脚电平不受匹配事件影响需软件手动控制。01匹配时强制对应引脚输出低电平。10匹配时强制对应引脚输出高电平。11匹配时翻转对应引脚电平。这是生成可变占空比方波或PWM的基础。一个高级技巧通过配置多个MR和对应的EMR可以在一个定时器周期内让一个引脚产生多次电平跳变实现复杂波形。例如MR0设置翻转并复位TC定义周期MR1和MR2也设置翻转就可以在一个周期内生成一个带死区时间的脉冲。捕获控制寄存器CCR和捕获寄存器CR用于测量外部信号。CCR为每个捕获通道CAPn.0-3配置在上升沿、下降沿或双边沿触发捕获以及是否产生中断。触发时当前TC的值会被锁存到对应的CR中。这里有一个硬件细节捕获是同步于PCLK的。外部信号需要被PCLK采样两次以检测边沿因此输入信号的最高频率不能超过PCLK的一半高/低电平的持续时间也不能短于1个PCLK周期。在测量高频信号时需要特别注意。2.4 PWM模块的“增强套件”PWM模块在定时器基础上增加了PWMMR4-6三个匹配寄存器以及最关键的PWM控制寄存器PWMPCR和锁存使能寄存器PWMLER。PWMPCR主要控制两项功能PWMSELn选择PWM通道n是单边沿模式0还是双边沿模式1。这决定了该通道的波形生成逻辑。PWMENAn使能PWM通道n的输出。只有使能后对应的PWMx引脚才会受匹配事件控制。PWMLER是实现PWM输出无毛刺的关键。当你更新匹配寄存器PWMMR0-6的值时新值并不会立即生效而是先写入一个影子寄存器。只有在下次MR0匹配即一个PWM周期结束时并且对应的PWMLER位被置位影子寄存器的值才会被加载到工作的匹配寄存器中。这个机制保证了在一个PWM周期内占空比参数是稳定的不会出现半周期新旧值混合导致的脉冲撕裂现象。正确的更新流程是1. 更新PWMMRx值2. 置位PWMLER中对应的位3. 等待下一次MR0匹配事件后新参数生效。3. 从零构建定时与PWM应用的实操指南理解了寄存器我们来看如何将它们组合起来完成实际任务。我们以最常见的两个场景为例利用Timer0实现一个1ms的周期性中断以及利用PWM模块生成一个频率1kHz、占空比可调的单边沿PWM信号。3.1 实战配置Timer0产生1ms定时中断假设系统PCLK频率为60MHz。我们的目标是让Timer0每1ms产生一次中断。步骤1计算预分频值PR和匹配值MR0首先确定时间基准。我们希望中断周期为1ms即0.001秒。 一个直观的想法是让TC直接计数到某个值。但TC的计数频率是PCLK/(PR1)。如果我们设PR0则TC每个PCLK周期加1计数到60000需要1ms。但MR0是32位这当然可以。不过更常见的做法是利用预分频获得一个中间频率让MR0的值更“规整”。 我们让TC的计数频率为1MHz这样每个TC计数就是1us。那么PR PCLK / 期望的TC频率 - 1 60,000,000 / 1,000,000 - 1 59然后1ms 1000us所以MR0应设置为999因为TC从0开始计数。验证定时周期 (PR1)/PCLK * (MR01) 60/60MHz * 1000 0.001秒。正确。步骤2初始化寄存器序列以下是基于直接寄存器操作的C代码示例。在实际项目中你可能会使用厂商提供的库函数但理解底层操作至关重要。// 假设 PCLK 60MHz #define PCLK 60000000UL void Timer0_Init_1ms(void) { // 1. 关闭定时器并确保处于已知状态 T0TCR 0x00; // 停止计数器 T0TCR 0x02; // 先复位计数器 T0TCR 0x00; // 清除复位保持停止 // 2. 设置预分频器得到1MHz的TC计数频率 T0PR 59; // PR (PCLK / 1MHz) - 1 59 // 3. 设置匹配寄存器0的值决定中断周期 T0MR0 999; // 匹配值 周期(us) - 1 1000 - 1 // 4. 配置匹配控制寄存器MR0匹配时产生中断并复位TC T0MCR (1 0) | (1 1); // 位0: MR0I (中断使能), 位1: MR0R (复位使能) // 5. 清除所有可能挂起的中断标志写1清零 T0IR 0xFF; // 6. 启动定时器 T0TCR 0x01; // 位0: Counter Enable }步骤3编写中断服务程序ISR在启动文件或中断向量表中将Timer0的中断服务程序指向一个C函数。void TIMER0_IRQHandler(void) __irq { uint32_t ir_status; // 读取中断寄存器判断中断源 ir_status T0IR; if (ir_status (1 0)) { // MR0中断 // 此处执行每1ms需要完成的任务 // 例如翻转一个LED灯用于指示 // LED_PIN ^ 1; // 清除中断标志非常重要 T0IR (1 0); } // 可以检查其他中断源如MR1, CR0等 // ... }关键注意事项中断标志清除顺序务必在ISR内处理完关键任务后尽早清除中断标志。避免因ISR执行时间过长错过下一次中断标志的识别。匹配值与实际周期记住定时周期是(MRx 1) * (PR 1) / PCLK。如果你设置MR00那么TC从0到0的“匹配”发生在它从0变为1的瞬间吗不匹配发生在TC等于MR0的时刻。如果TC初始为0MR0也为0则在使能定时器的第一个计数周期就会发生匹配。这通常不是我们想要的。一般将MR0设为大于0的值。复位的影响当MR0R使能时TC在匹配后瞬间复位为0。这意味着TC永远无法计数到MR01。你读取TC的值范围永远是0 ~ MR0。3.2 实战配置PWM1输出1kHz50%占空比方波我们使用PWM模块的通道1PWM1工作在单边沿模式。PWM周期由MR0决定占空比由MR1决定。假设PCLK仍为60MHz目标PWM频率1kHz占空比50%。步骤1计算寄存器值PWM周期 T 1 / 频率 1 / 1000Hz 0.001秒 1ms。 我们需要选择一个合适的预分频值PWMPR让PWMTC的计数周期便于计算。同样我们让PWMTC的计数频率为1MHz1us。PWMPR PCLK / 1MHz - 1 59在一个PWM周期内PWMTC需要从0计数到周期 / PWMTC周期 - 1 0.001s / 0.000001s - 1 999。 所以PWMMR0 999。这个值决定了PWM频率。 对于50%占空比高电平时间应为0.5ms即500us。所以PWMMR1 500 - 1 499。在单边沿模式下PWM1输出在MR0匹配时周期开始变高在MR1匹配时变低。步骤2初始化PWM寄存器序列void PWM1_Init_1kHz_50Duty(void) { // 1. 关闭PWM定时器并复位 PWMTCR 0x00; // 停止 PWMTCR (1 1); // 复位 PWMTCR 0x00; // 清除复位 // 2. 设置预分频得到1MHz的PWMTC时钟 PWMPR 59; // 3. 设置匹配寄存器MR0定义周期MR1定义占空比 PWMMR0 999; // 周期值1000个TC计数 - 1ms PWMMR1 499; // 匹配值500个TC计数 - 0.5ms (50%占空比) // 4. 配置匹配控制MR0匹配时复位PWMTC以形成固定周期 PWMMCR (1 1); // MR0R 1复位TC。不需要MR0中断。 // 5. 配置PWM控制寄存器(PWMPCR) // 使能PWM1输出并设置为单边沿模式PWMSEL1默认为0 // PWMPCR的位定义需查手册假设PWMENA1是第9位。 PWMPCR (1 9); // 使能PWM1输出 // 6. 配置锁存使能寄存器使MR0和MR1的新值生效 PWMLER (1 0) | (1 1); // 使能MR0和MR1的锁存 // 7. 启动PWM定时器同时启动计数器 PWMTCR (1 0); // 计数器使能 // 如果需要PWM输出立即生效还需使能PWM模式 PWMTCR | (1 3); // 位3是PWM使能位(PWM Enable) }步骤3动态调整占空比在运行中改变占空比需要使用锁存机制避免毛刺。void PWM1_SetDutyCycle(uint32_t duty_cycle) { // duty_cycle: 高电平计数值范围 1 ~ (PWMMR0) if (duty_cycle 0) { // 占空比0%即常低。可以通过设置匹配值超出范围实现或直接控制引脚。 // 更规范的做法是设置MR1 MR0这样匹配事件不会发生输出保持低电平单边沿模式MR0置高MR1置低但MR1事件不触发。 PWMMR1 PWMMR0 1; } else if (duty_cycle (PWMMR0 1)) { // 占空比100%即常高。设置MR1 0则MR1匹配发生在周期开始立即拉低不对。 // 在单边沿模式输出在MR0变高MR1变低。要让输出常高应禁止MR1的匹配动作。 // 简单方法设置MR1 0并在外部匹配控制中不执行任何动作但PWM模块逻辑固定。 // 正确做法设置MR1 0并配置MR1匹配时“无动作”。但PWM输出逻辑是硬件连接的。 // 更简单设置MR1为一个大于MR0的值使其永不匹配。输出将在MR0变高后永不拉低。 PWMMR1 PWMMR0 1; } else { // 正常占空比 PWMMR1 duty_cycle - 1; } // 关键步骤使能MR1的锁存新值将在下一个PWM周期开始时生效 PWMLER (1 1); // 只锁存MR1 // 注意PWMLER是“一次性”的。写入后硬件在下次MR0匹配时会自动清除对应的位。 }PWM配置的核心要点单边沿 vs 双边沿单边沿模式PWMSELn0下所有通道的上升沿对齐在周期开始MR0匹配。双边沿模式PWMSELn1下每个通道需要两个匹配寄存器来控制上升沿和下降沿可以生成中心对称或任意位置的脉冲适用于电机驱动等需要死区控制和相位调整的场景。死区时间在驱动H桥等电路时为了防止上下管直通需要在互补的PWM信号之间插入死区时间两者都为低电平的短暂时间。这可以通过软件配置两个匹配寄存器来实现一个通道的下降沿提前另一个通道的上升沿延后。影子寄存器与同步更新PWMLER机制是生产级应用稳定的保证。永远不要在直接写入PWMMRx后立即期望波形改变必须通过PWMLER同步到周期边界。4. 高级应用与常见问题深度排查掌握了基本配置后我们来看一些更复杂的应用场景和那些让人头疼的调试问题。4.1 应用一输入捕获测量脉冲宽度假设我们需要用Timer1的CAP0.0引脚测量一个正脉冲的宽度。void Timer1_Capture_Init(void) { // 1. 停止并复位定时器 T1TCR 0x02; T1TCR 0x00; // 2. 设置预分频获得合适的计时分辨率例如1us T1PR (PCLK / 1000000) - 1; // 1MHz TC // 3. 配置捕获控制寄存器(CCR) // 在CAP0.0的上升沿和下降沿都捕获并产生中断 T1CCR (1 0) | (1 1) | (1 2); // 位0 (CAP0RE): 上升沿捕获使能 // 位1 (CAP0FE): 下降沿捕获使能 // 位2 (CAP0I): 捕获中断使能 // 4. 清除中断标志 T1IR 0xFF; // 5. 启动定时器 T1TCR 0x01; } void TIMER1_IRQHandler(void) __irq { uint32_t ir_status T1IR; static uint32_t rise_time 0; uint32_t pulse_width; if (ir_status (1 4)) { // CR0中断即CAP0.0捕获中断 if (/* 判断是上升沿还是下降沿可通过检查引脚状态或另设标志 */) { // 假设是上升沿 rise_time T1CR0; // 读取捕获寄存器0的值 } else { // 下降沿 pulse_width T1CR0 - rise_time; // 计算脉宽单位是TC计数周期 // 将pulse_width转换为时间微秒time_us pulse_width * (T1PR1) / PCLK // 处理脉宽数据... } T1IR (1 4); // 清除CR0中断标志 } // ... 处理其他中断 }捕获模式的陷阱信号抖动机械开关等信号会有抖动可能触发多次边沿捕获。需要在硬件RC滤波或软件去抖算法上处理。计数器溢出如果脉冲宽度超过定时器从0到0xFFFFFFFF的计数时间计算脉宽时需要考虑溢出。一个实用的方法是开启定时器溢出中断虽然Timer没有直接的溢出中断但可以设置一个MR在接近最大值时中断或者在捕获中断中检查T1CR0与rise_time的大小关系如果后者大说明发生了溢出。中断响应时间从边沿触发到进入ISR读取CR0存在延迟。对于极窄的脉冲可能捕获不到或精度下降。对于高频信号测量更适合使用脉冲计数模式计数器模式而非输入捕获。4.2 应用二双边沿PWM生成互补带死区信号驱动一个三相逆变器或H桥通常需要三对互补的PWM信号且每对信号之间需要插入死区时间。我们以PWM2和PWM4配置为一对互补信号为例假设PWM2高有效PWM4低有效。void PWM_Complementary_With_DeadTime(void) { // 目标PWM频率10kHz死区时间2us。 // 假设PCLK60MHzPWMPR59 (TC频率1MHz, 1us分辨率)。 PWMPR 59; uint32_t period_ticks 100; // 周期 100us 1/10kHz uint32_t deadtime_ticks 2; // 死区 2us uint32_t duty_ticks 30; // 高电平时间 30us (占空比30%) // 配置MR0决定周期 PWMMR0 period_ticks - 1; // 99 // 配置PWM2 (高有效侧) 和 PWM4 (低有效侧) 为双边沿模式 // 需要查手册确定PWMSEL2和PWMSEL4在PWMPCR中的位置 // 假设PWMSEL2是位2, PWMSEL4是位4, PWMENA2是位10, PWMENA4是位12 PWMPCR (1 2) | (1 4) | (1 10) | (1 12); // 双边沿 输出使能 // 设置匹配寄存器以实现带死区的互补输出 // PWM2: 上升沿由MR1控制下降沿由MR2控制。 // PWM4: 上升沿由MR3控制下降沿由MR4控制。 // 逻辑我们希望PWM2高电平时PWM4为低。 // 死区期间两者都为低。 // 设定: // MR1 死区时间开始 (PWM2上升沿) // MR2 死区时间开始 有效高电平时间 (PWM2下降沿) // MR3 有效高电平时间结束 (PWM4上升沿) - 实际上PWM4是低有效所以其“上升沿”对应PWM2高电平结束 // MR4 周期结束 - 死区时间 (PWM4下降沿) - 实际上PWM4的“下降沿”对应下一个周期PWM2上升沿之前 // 更直观的方法定义高电平有效时间段的开始和结束。 uint32_t high_start deadtime_ticks; uint32_t high_end deadtime_ticks duty_ticks; PWMMR1 high_start - 1; // PWM2 上升沿 PWMMR2 high_end - 1; // PWM2 下降沿 PWMMR3 high_end - 1; // PWM4 上升沿 (低有效侧的开始变低需要理清逻辑) PWMMR4 period_ticks - deadtime_ticks - 1; // PWM4 下降沿 // 注意双边沿模式下PWM输出逻辑由PWMSELn选择匹配寄存器对。 // 根据手册表221PWM2双边沿模式Set by MR1, Reset by MR2. // PWM4双边沿模式Set by MR3, Reset by MR4. // “Set”意味着输出变高“Reset”意味着输出变低。 // 因此对于高有效的PWM2我们需要在high_start置高high_end置低。 // 对于低有效的互补信号逻辑应相反。通常我们会用一个反相器硬件实现或者软件上生成两路独立信号。 // 更常见的做法是生成两路独立PWM一路高有效一路低有效通过调整匹配值错开死区时间。 // 配置匹配控制MR0匹配时复位TC PWMMCR (1 1); // MR0R // 锁存所有更新的匹配寄存器 PWMLER (10)|(11)|(12)|(13)|(14); // 启动PWM定时器和输出 PWMTCR (1 0) | (1 3); // 计数器使能 PWM模式使能 }这个例子比较复杂实际中需要结合硬件电路是否使用硬件反相仔细推敲Set/Reset的逻辑关系。最好的方法是先用示波器观察单个通道的波形再组合成互补对。4.3 常见问题排查清单当你配置的定时器或PWM不工作时可以按照以下清单逐项检查时钟问题确认PCLK是否使能在LPC21xx/22xx中外设模块的时钟默认可能是关闭的。你需要查看系统控制模块的PCONP外设功率控制寄存器寄存器确保对应定时器/PWM模块的时钟位被使能。例如Timer0的时钟使能位是PCONP[1]。确认PCLK频率计算预分频和匹配值依赖准确的PCLK。检查主时钟配置、PLL设置和APB分频器(VPBDIV)的设置。引脚功能问题引脚是否配置为定时器/PWM功能LPC21xx/22xx的引脚是多功能复用的。你需要配置PINSELx寄存器将对应引脚选择为MATx.x或CAPx.x或PWMx功能。这是最容易被忽略的一步引脚方向作为输出MAT, PWM时对应的IODIR位应设置为输出。中断问题中断是否使能除了配置定时器的MCR中的中断位还需要在NVIC嵌套向量中断控制器中使能对应的中断如Timer0_IRQn。中断标志是否清除在ISR中必须清除中断标志IR寄存器写1清零否则会连续触发中断。中断优先级如果系统中有其他高优先级中断长时间阻塞可能导致定时器中断无法及时响应。PWM无输出问题PWMTCR的PWM使能位PWMTCR[3]PWM Enable必须置1PWM输出逻辑才工作。仅使能计数器(PWMTCR[0])是不够的。PWMPCR的输出使能位PWMPCR中的PWMENA1~6必须置1对应的PWM引脚才有输出。锁存寄存器PWMLER更新了PWMMRx后是否设置了对应的PWMLER位新值必须等到下一个PWM周期开始MR0匹配才会生效。匹配值超出范围在单边沿模式下如果MRx的值大于等于MR0则该通道输出恒高因为下降沿匹配永远不会发生。如果MRx0则输出恒低因为周期开始就匹配拉低。检查你的占空比计算。计数器不计数TCR配置TCR[0]Counter Enable是否置1复位位卡住是否错误地将TCR[1]Counter Reset一直置为1这会强制计数器保持复位状态。在调试器中查看连接调试器实时查看TC寄存器的值是否在增加。这是最直接的诊断方法。输出波形异常毛刺、相位不对寄存器访问同步在计数器运行时修改PR、MR等寄存器可能导致不可预知的行为。尽量在计数器停止时修改关键寄存器或利用影子寄存器PWM的PWMLER机制。匹配/捕获事件与时钟同步所有匹配、捕获、复位操作都与PCLK同步会有最多一个时钟周期的延迟。在计算精确时序时要考虑这一点。双边沿PWM逻辑混淆再次仔细阅读手册表221确认你选择的MRx对是否正确控制了对应PWM通道的Set和Reset。画一个时序图来辅助理解。调试嵌入式外设示波器和逻辑分析仪是你的最佳伙伴。首先用示波器看引脚是否有任何信号然后用逻辑分析仪抓取长时间的时序关系对照你配置的寄存器值一步步分析硬件是否按预期工作。从最简单的功能比如让一个MAT引脚定时翻转开始测试逐步增加复杂度这样能快速定位问题所在。