2. LED闪烁
任务说明
本案例以LED闪烁为载体,完成定时器的首次实践。目标不是“让LED亮灭”本身,而是通过LED的闪烁周期,直观验证定时器的定时计算、初始化流程与中断服务函数的正确性。你需要完成:配置定时器产生1ms中断,在中断中累加计数,每500ms翻转一次LED状态,最终实现LED以1Hz频率闪烁(亮500ms,灭500ms)。
硬件连接与原理
以STM32F103系列为例,LED接在PC13(板上常见位置),低电平点亮。定时器选用TIM2,其时钟源为APB1定时器时钟(通常为72MHz)。定时器初值计算公式为:
定时周期 = (ARR + 1) × (PSC + 1) / 定时器时钟频率
若需要1ms中断,72MHz时钟下可取PSC=71(分频后1MHz),ARR=999(计数1000次),则周期为1000×1µs = 1ms。
代码实现
#include "stm32f1xx_hal.h"
/* 中断计数变量 */
volatile uint16_t tick_count = 0;
volatile uint8_t led_state = 0;
/* TIM2初始化:1ms中断 */
void TIM2_Init(void)
{
TIM_HandleTypeDef htim2;
htim2.Instance = TIM2;
htim2.Init.Prescaler = 71; /* 72MHz/72 = 1MHz */
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 999; /* 1MHz/1000 = 1kHz → 1ms */
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
HAL_TIM_Base_Init(&htim2);
HAL_NVIC_SetPriority(TIM2_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(TIM2_IRQn);
HAL_TIM_Base_Start_IT(&htim2); /* 使能更新中断并启动定时器 */
}
/* TIM2中断服务函数 */
void TIM2_IRQHandler(void)
{
HAL_TIM_IRQHandler(&htim2); /* 调用HAL库公共处理,内部会清更新标志 */
}
/* 定时器更新回调(HAL库在更新中断中自动调用) */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM2) {
tick_count++;
if (tick_count >= 500) { /* 500ms */
tick_count = 0;
led_state = !led_state;
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13,
led_state ? GPIO_PIN_RESET : GPIO_PIN_SET);
}
}
}
/* 简单主函数示意 */
int main(void)
{
HAL_Init();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_TIM2_CLK_ENABLE();
GPIO_InitTypeDef gpio;
gpio.Pin = GPIO_PIN_13;
gpio.Mode = GPIO_MODE_OUTPUT_PP;
gpio.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &gpio);
TIM2_Init();
while (1) {
/* 主循环无需额外处理,LED翻转由中断驱动 */
}
}
关键点说明
- 中断服务函数中必须调用
HAL_TIM_IRQHandler(),由它负责清除更新中断标志并触发回调,否则会反复进入中断。 - 回调函数
HAL_TIM_PeriodElapsedCallback是弱函数,你在用户代码中重写即可,无需修改HAL库。 - LED翻转逻辑:
led_state为1时输出低电平点亮LED,为0时输出高电平熄灭,实现500ms亮、500ms灭。
验证方法
将代码编译后下载至开发板,连接PC13引脚至LED(若为板上LED则直接观察)。上电后观察LED是否以约1Hz频率闪烁(每周期约1秒)。若闪烁频率明显偏差,优先检查以下两点:
- 确认
SystemCoreClock是否为72000000(即72MHz),若芯片实际运行在8MHz内部时钟,则需调整PSC与ARR数值。 - 用示波器或逻辑分析仪测量PC13引脚波形,高电平持续时间应为500ms±10ms,低电平持续时间同理。若波形周期正确但占空比异常,检查翻转逻辑。
判定标准:LED以稳定周期闪烁,肉眼观察无明显快慢变化;用示波器测得翻转周期为1s±20ms,即认为定时器配置正确,案例通过。
常见问题排查
- LED不闪烁:检查TIM2时钟是否使能(
__HAL_RCC_TIM2_CLK_ENABLE()),以及NVIC中断是否开启。 - 闪烁频率异常快:确认PSC与ARR是否按72MHz计算;若芯片时钟不是72MHz,需按实际时钟重新计算。
- 编译报错:确认已包含
stm32f1xx_hal.h,且工程中已添加HAL库的定时器模块源文件。