STM32的hal库与标准库定时器区别

HAL库

#include "stm32f4xx_hal.h"

TIM_HandleTypeDef htim2;

void SystemClock_Config(void); // 系统时钟初始化

void Timer_Init(void) {
    __HAL_RCC_TIM2_CLK_ENABLE(); // 启用 TIM2 时钟

    htim2.Instance = TIM2; // 使用 TIM2
    htim2.Init.Prescaler = 8399; // 预分频器:时钟频率 84MHz / (8399 + 1) = 10kHz
    htim2.Init.CounterMode = TIM_COUNTERMODE_UP; // 向上计数模式
    htim2.Init.Period = 10000 - 1; // 自动重装值:10kHz / 10000 = 1 秒
    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; // 时钟不分频
    HAL_TIM_Base_Init(&htim2); // 初始化定时器

    HAL_TIM_Base_Start_IT(&htim2); // 启动定时器并使能中断
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
    if (htim->Instance == TIM2) {
        // 1 秒定时器中断回调
        HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); // 翻转 LED(示例)
    }
}

int main(void) {
    HAL_Init(); // 初始化 HAL
    SystemClock_Config(); // 配置系统时钟
    Timer_Init(); // 初始化定时器

    __HAL_RCC_GPIOA_CLK_ENABLE(); // 使能 GPIOA 时钟
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = GPIO_PIN_5;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 配置 LED 引脚

    while (1) {
        // 主循环
    }
}

标准库

#include "stm32f4xx.h"

void Timer_Init(void) {
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 启用 TIM2 时钟

    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_TimeBaseStructure.TIM_Prescaler = 8399; // 预分频器:84MHz / (8399 + 1) = 10kHz
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数
    TIM_TimeBaseStructure.TIM_Period = 10000 - 1; // 自动重装值:10kHz / 10000 = 1 秒
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 时钟不分频
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // 初始化定时器

    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); // 使能更新中断
    TIM_Cmd(TIM2, ENABLE); // 启动定时器

    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; // 配置 TIM2 中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

void TIM2_IRQHandler(void) {
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 清除中断标志
        GPIO_ToggleBits(GPIOA, GPIO_Pin_5); // 翻转 LED(示例)
    }
}

int main(void) {
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // 使能 GPIOA 时钟
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置 LED 引脚

    Timer_Init(); // 初始化定时器

    while (1) {
        // 主循环
    }
}

1. 开启定时器时钟

HAL 库SPL
__HAL_RCC_TIM2_CLK_ENABLE();RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
作用:
  • 都是开启定时器的时钟,分别针对 TIM2 定时器。
  • HAL 库使用更简洁的宏,而 SPL 明确了寄存器命名(RCC_APB1PeriphClockCmd)。

 

2. 定时器初始化结构体定义

HAL 库SPL
TIM_HandleTypeDef htim2;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
作用:
  • HAL 库使用更高层的 TIM_HandleTypeDef,不仅包含配置参数,还包含状态信息(如定时器实例)。
  • SPL 使用 TIM_TimeBaseInitTypeDef,更接近寄存器的直接配置。

 

3. 设置预分频器和重装值

HAL 库SPL
htim2.Init.Prescaler = 8399;TIM_TimeBaseStructure.TIM_Prescaler = 8399;
htim2.Init.Period = 10000 - 1;TIM_TimeBaseStructure.TIM_Period = 10000 - 1;
作用:
  • 都是设置定时器的预分频器和自动重装值,以实现定时 1 秒。

 

4. 定时器模式配置

HAL 库SPL
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
作用:
  • 设置定时器为 向上计数模式,两者代码非常类似。
  • HAL 和 SPL 的枚举值命名也接近。

 

5. 初始化定时器

HAL 库SPL
HAL_TIM_Base_Init(&htim2);TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
作用:
  • 都是将前面设置的参数应用到定时器。
  • HAL 库隐藏了更多底层逻辑,使用单一函数完成初始化;SPL 更显式,需要手动指定定时器实例。

 

6. 启动定时器

HAL 库SPL
HAL_TIM_Base_Start_IT(&htim2);TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM2, ENABLE);
作用:
  • HAL 库:启动定时器并使能中断,通过单一函数实现。
  • SPL:需要分别使能中断(TIM_ITConfig)和启动计数(TIM_Cmd)。

 

7. 配置中断优先级

HAL 库SPL
HAL 自动管理中断优先级。手动配置中断优先级:
```c
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
```
作用:
  • HAL 简化了中断优先级的配置,默认设置即可运行。
  • SPL 必须手动调用 NVIC_Init 设置优先级和启用中断。

 

8. 总结对照表

功能HAL 库SPL
时钟初始化__HAL_RCC_TIMx_CLK_ENABLE()RCC_APB1PeriphClockCmd()
定时器初始化HAL_TIM_Base_Init()TIM_TimeBaseInit()
启动定时器HAL_TIM_Base_Start_IT()TIM_ITConfig()TIM_Cmd()
中断优先级设置自动管理手动调用 NVIC_Init()
中断处理使用回调函数 HAL_TIM_PeriodElapsedCallback手动编写中断函数并清除标志位
开发效率简单快速,适合新手灵活性高,需要更多硬件知识
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值