打印
[STM32G0]

STM32G071:探索基于低功耗MCU的定时器中断应用

[复制链接]
175|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Pulitzer|  楼主 | 2024-12-9 07:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
随着物联网的普及,对MCU低功耗性能和高集成度的需求愈发显著。ST推出的STM32G071系列凭借其Cortex-M0+内核、低功耗特性以及丰富的外设,成为许多低成本嵌入式应用的首选。本篇文章将以STM32G071为例,介绍如何配置定时器以实现中断功能,并通过代码演示其应用场景。
应用场景定时器中断功能广泛应用于定时任务、事件驱动和PWM信号生成等场景。在本文中,我们以1秒周期触发中断为例,通过GPIO输出方波信号,演示STM32G071的定时器中断功能。

步骤与代码实现硬件环境
  • MCU型号:STM32G071RB
  • 开发板:NUCLEO-G071RB
  • IDE:STM32CubeIDE
  • 调试接口:ST-LINK

步骤 1:时钟配置在STM32CubeMX中启用HSI作为主时钟,确保定时器的时钟源正常工作。

步骤 2:定时器初始化配置TIM3为基本定时器,设置预分频器和重装载值以实现1秒中断:
#include "main.h"

TIM_HandleTypeDef htim3;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM3_Init(void);

int main(void) {
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_TIM3_Init();

    // 启动定时器中断
    HAL_TIM_Base_Start_IT(&htim3);

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

// 定时器3初始化
void MX_TIM3_Init(void) {
    htim3.Instance = TIM3;
    htim3.Init.Prescaler = 8000 - 1; // 1 MHz / 8000 = 125 Hz
    htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim3.Init.Period = 125 - 1;    // 125 Hz / 125 = 1 Hz
    htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
    if (HAL_TIM_Base_Init(&htim3) != HAL_OK) {
        Error_Handler();
    }
}

// 中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
    if (htim->Instance == TIM3) {
        // 翻转GPIO引脚
        HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
    }
}
步骤 3:GPIO配置通过STM32CubeMX启用GPIOB引脚,配置PB0为推挽输出,初始化后用于输出方波信号。
void MX_GPIO_Init(void) {
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __HAL_RCC_GPIOB_CLK_ENABLE();

    GPIO_InitStruct.Pin = GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
步骤 4:中断服务函数在定时器中断触发时,翻转GPIO输出状态,实现定时方波信号输出。

步骤 5:主时钟配置通过STM32CubeMX自动生成SystemClock_Config函数,确保时钟配置正确。
void SystemClock_Config(void) {
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
        Error_Handler();
    }

    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
                                  | RCC_CLOCKTYPE_PCLK1;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) {
        Error_Handler();
    }
}
结果验证将GPIOB引脚连接至示波器或LED,当程序运行后,PB0引脚将以1 Hz的频率翻转,实现稳定的方波信号输出。

总结本文通过一个简单的定时器中断示例,展示了STM32G071的基本配置方法及其在定时任务中的应用。STM32G071的低功耗特性使其适合用于电池供电的场景,而其高性价比和丰富外设让它成为物联网设备开发的理想选择。

使用特权

评论回复
沙发
公羊子丹| | 2024-12-9 07:48 | 只看该作者
哇,STM32G071还有这种**,学到了!

使用特权

评论回复
板凳
周半梅| | 2024-12-9 07:48 | 只看该作者
有没有可能用这个思路实现多通道PWM啊?

使用特权

评论回复
地板
帛灿灿| | 2024-12-9 07:48 | 只看该作者
GPIO输出方波那部分解释得挺清楚,挺棒的!

使用特权

评论回复
5
童雨竹| | 2024-12-9 07:49 | 只看该作者
最近也在用STM32G071,这个定时器例子对我很有帮助!

使用特权

评论回复
6
万图| | 2024-12-9 07:49 | 只看该作者
代码注释详细,真是新手福音!

使用特权

评论回复
7
Wordsworth| | 2024-12-9 07:49 | 只看该作者
请问如果换成外部晶振,该怎么改时钟配置呢?

使用特权

评论回复
8
Bblythe| | 2024-12-9 07:49 | 只看该作者
这个定时器的精度表现怎么样啊?有测试数据吗?

使用特权

评论回复
9
Uriah| | 2024-12-9 07:50 | 只看该作者
STM32CubeIDE确实方便,直接生成初始化代码,效率提升不少。

使用特权

评论回复
10
Clyde011| | 2024-12-9 07:50 | 只看该作者
感觉ST的HAL库有点重,有没有裸机实现的版本推荐?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

34

主题

3655

帖子

0

粉丝