stm32定时器控制led闪烁hal
时间: 2025-01-06 10:32:34 浏览: 6
### STM32 HAL 库定时器控制 LED 闪烁
为了实现STM32微控制器上LED的秒级闪烁,可以利用内置的定时器模块配合硬件抽象层(HAL)库完成。具体来说,通过配置TIMx定时器中断来触发状态切换,从而达到周期性的点亮和熄灭连接到指定GPIO端口上的发光二极管的效果。
下面给出一段基于STM32F103C8T6型号单片机并采用HAL库编写的简单实例代码:
```c
#include "main.h"
// 定义全局变量用于存储定时器句柄
TIM_HandleTypeDef htim2;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM2_Init(void);
int main(void){
// 初始化系统时钟
SystemClock_Config();
// GPIO初始化函数调用
MX_GPIO_Init();
// TIM2定时器初始化函数调用
MX_TIM2_Init();
// 开启TIM2更新事件中断
HAL_TIM_Base_Start_IT(&htim2);
while (1){
// 主循环体保持空闲等待中断发生改变LED状态
}
}
/**
* @brief 配置系统的时钟源及其分频系数等参数.
*/
void SystemClock_Config(void){
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK){
Error_Handler();
}
}
/**
* @brief 对应引脚初始化为推挽输出模式.
*/
static void MX_GPIO_Init(void){
__HAL_RCC_GPIOD_CLK_ENABLE();
/* Configure PD2 as output push-pull mode with speed set to low */
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOD,&GPIO_InitStruct);
}
/**
* @brief 设置TIM2工作方式及时基装载值.
*/
static void MX_TIM2_Init(void){
__HAL_RCC_TIM2_CLK_ENABLE()
htim2.Instance = TIM2;
htim2.Init.Prescaler = 7999;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 999;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK){
Error_Handler();
}
}
/**
* @brief 当计数溢出时会自动进入此回调处理程序翻转PD2的状态.
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
static uint8_t state=0;
if(htim->Instance==TIM2){
HAL_GPIO_TogglePin(GPIOD,GPIO_PIN_2);
state=!state;
}
}
```
上述代码实现了每秒钟一次的LED亮暗交替变化过程[^2]。这里选择了通用型定时器TIM2来进行操作,并将其预分频寄存器设定为7999加上ARR重载寄存器中的数值999共同决定了实际产生的延时时长接近一秒(假设APB1总线频率为8MHz)。每当定时器向上计数到达最大限界后就会产生一个更新事件进而激活相应的ISR服务例程,在那里完成了对目标IO电平高低转换的任务。
阅读全文