4. 定时器定时翻转LED

任务说明

本案例基于中微CMS32系列车规MCU,使用定时器(以TIM0为例)产生周期性中断,在中断服务函数中翻转LED引脚电平,实现精确的定时翻转效果。通过本案例,掌握定时器初始化、中断配置及中断服务函数的编写方法。

硬件连接

LED阳极通过限流电阻(约330Ω)连接至PB0引脚,阴极接地。当PB0输出高电平时LED点亮,输出低电平时熄灭。

代码实现


#include "CMS32L051.h"

/* 定时器中断周期:100ms(系统时钟24MHz,预分频24000,计数100) */
#define TIMER_PRESCALER  24000
#define TIMER_PERIOD     100

volatile uint32_t led_toggle_count = 0;

/* TIM0中断服务函数 */
void TIM0_IRQHandler(void)
{
    if (TIM0->INTF & TIM_INTF_C0IF) {
        TIM0->INTF &= ~TIM_INTF_C0IF;    /* 清除中断标志 */
        led_toggle_count++;
        if (led_toggle_count >= 5) {      /* 每5次中断翻转一次,即500ms翻转 */
            led_toggle_count = 0;
            GPIO->PBOD ^= (1 << 0);      /* 翻转PB0 */
        }
    }
}

void TIM0_Init(void)
{
    /* 使能TIM0时钟 */
    SYS->CLKEN |= SYS_CLKEN_TIM0;
    
    /* 复位TIM0 */
    SYS->RSTEN |= SYS_RSTEN_TIM0;
    SYS->RSTEN &= ~SYS_RSTEN_TIM0;
    
    /* 配置TIM0为定时器模式,向上计数 */
    TIM0->CR0 = 0x0000;                  /* 停止计数,边沿计数模式 */
    TIM0->CR1 = 0x0000;                  /* 定时器模式,向上计数 */
    
    /* 设置预分频值 */
    TIM0->PR = TIMER_PRESCALER - 1;
    
    /* 设置比较值 */
    TIM0->C0 = TIMER_PERIOD - 1;
    
    /* 使能比较匹配中断 */
    TIM0->INTE |= TIM_INTE_C0IE;
    
    /* 配置NVIC */
    NVIC_EnableIRQ(TIM0_IRQn);
    NVIC_SetPriority(TIM0_IRQn, 2);
}

void GPIO_Init(void)
{
    /* 使能GPIO时钟 */
    SYS->CLKEN |= SYS_CLKEN_GPIO;
    
    /* 配置PB0为推挽输出 */
    GPIO->PB0CR = 0x01;                  /* 输出模式 */
    GPIO->PBOD &= ~(1 << 0);            /* 初始输出低电平 */
}

int main(void)
{
    GPIO_Init();
    TIM0_Init();
    
    /* 启动TIM0 */
    TIM0->CR0 |= 0x0001;                 /* 启动计数 */
    
    while (1) {
        /* 主循环空操作,LED翻转由中断完成 */
        __NOP();
    }
}

定时器工作原理

TIM0配置为定时器模式,系统时钟24MHz经预分频器24000分频后得到1kHz计数时钟。计数器从0向上计数至比较值100时产生中断请求,即每100ms触发一次中断。中断服务函数中每累计5次中断(500ms)翻转一次PB0引脚电平,实现LED以1Hz频率闪烁。

SVG时序图

TIM0定时中断翻转LED时序图 0ms 100ms 200ms 300ms 400ms 500ms 计数器 中断标志 LED(PB0) 高电平(亮) 低电平(灭) ↑ 中断触发 ↑ 中断触发 ↑ 中断触发 ↑ 中断触发 ↑ 中断触发 ← 第5次中断翻转 →

编译与烧录

使用中微官方CMS32L051芯片支持包创建工程,将上述代码保存为main.c并加入工程。编译配置选择芯片型号CMS32L051,优化级别建议O0便于调试。编译成功后通过CMS-ICE仿真器连接目标板,使用官方烧录工具下载hex文件至芯片。

验证方法

将程序烧录至开发板后,观察PB0引脚连接的LED状态。预期现象:LED以约1Hz频率(每500ms翻转一次)持续闪烁。使用示波器测量PB0引脚波形,可观察到周期约为1s的方波信号,高电平持续500ms,低电平持续500ms。若LED不闪烁或闪烁频率异常,检查晶振频率配置、预分频值及比较值是否与系统时钟匹配。