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

[复制链接]
972|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秒中断:
  1. #include "main.h"

  2. TIM_HandleTypeDef htim3;

  3. void SystemClock_Config(void);
  4. static void MX_GPIO_Init(void);
  5. static void MX_TIM3_Init(void);

  6. int main(void) {
  7.     HAL_Init();
  8.     SystemClock_Config();
  9.     MX_GPIO_Init();
  10.     MX_TIM3_Init();

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

  13.     while (1) {
  14.         // 主循环
  15.     }
  16. }

  17. // 定时器3初始化
  18. void MX_TIM3_Init(void) {
  19.     htim3.Instance = TIM3;
  20.     htim3.Init.Prescaler = 8000 - 1; // 1 MHz / 8000 = 125 Hz
  21.     htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  22.     htim3.Init.Period = 125 - 1;    // 125 Hz / 125 = 1 Hz
  23.     htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  24.     htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  25.     if (HAL_TIM_Base_Init(&htim3) != HAL_OK) {
  26.         Error_Handler();
  27.     }
  28. }

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

  3.     __HAL_RCC_GPIOB_CLK_ENABLE();

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

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

  4.     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  5.     RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  6.     RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  7.     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  8.     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
  9.         Error_Handler();
  10.     }

  11.     RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
  12.                                   | RCC_CLOCKTYPE_PCLK1;
  13.     RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  14.     RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  15.     RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

  16.     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) {
  17.         Error_Handler();
  18.     }
  19. }
结果验证将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输出方波那部分解释得挺清楚,挺棒的!
童雨竹 发表于 2024-12-9 07:49 | 显示全部楼层
最近也在用STM32G071,这个定时器例子对我很有帮助!
万图 发表于 2024-12-9 07:49 | 显示全部楼层
代码注释详细,真是新手福音!
Wordsworth 发表于 2024-12-9 07:49 | 显示全部楼层
请问如果换成外部晶振,该怎么改时钟配置呢?
Bblythe 发表于 2024-12-9 07:49 | 显示全部楼层
这个定时器的精度表现怎么样啊?有测试数据吗?
Uriah 发表于 2024-12-9 07:50 | 显示全部楼层
STM32CubeIDE确实方便,直接生成初始化代码,效率提升不少。
Clyde011 发表于 2024-12-9 07:50 | 显示全部楼层
感觉ST的HAL库有点重,有没有裸机实现的版本推荐?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

163

主题

6099

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部