这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【功率监测与控制系统DIY活动过程贴】LED的定时器中断控制LED闪烁

共2条 1/1 1 跳转至

【功率监测与控制系统DIY活动过程贴】LED的定时器中断控制LED闪烁

助工
2025-05-10 16:39:49     打赏

【功率监测与控制系统DIY活动过程贴】LED的定时器中断控制

本文介绍了基于 NUCLEO-F411RE 开发板并使用 SMT32CubeMX 软件快速生成工程,实现了通过定时器精确定时 300 毫秒的 GPIO 电平翻转以及 LED 闪烁项目。

LED闪烁

介绍了使用定时器实现 300ms 翻转板载 LED 的开发流程。

原理

介绍了实现 LED 闪烁和 GPIO 电平翻转所需的定时器和中断的基本原理。

interrupt.jpg

该项目的设计思路为通过定时器精确定时 300 毫秒,当到达计时时刻,进入中断并执行 LED 对应的 GPIO 电平翻转指令,进而实现精确闪灯。

定时器

定时器的基本功能是定时,设定目标时间,系统会在设定的时刻执行相应的任务。

定时器的使用涉及到三个重要概念

分频:例如分针对于秒针的分频为60;

计数:例如秒针转动 10 格的时长为 10 秒,对于定时器的计数,频率越高增长速度越快;

重载:时针在表盘最多记12小时,如果继续增加,则回到0;当定时器中的计数值达到重载值时,计数值就会被清零。

NVIC

STM32 专门用于处理中断的控制器为嵌套向量中断控制器 (Nested Vectored Interrupt Controller, NVIC);

NVIC 支持 中断优先级 和 中断嵌套 功能,

中断优先级即给不同的中断划分不同的响应等级,如果多个中断同时产生,则STM32优先处理高优先级的中断;

中断嵌套即允许在处理中断时,如果有更高优先级的中断产生,则挂起当前中断,先去处理产生的高优先级中断,处理完后再恢复到原来的中断继续处理。

方案

打开 STM32CubeMX 软件,新建ST板卡工程;

时钟配置

默认系统时钟频率为 84MHz

clock_default.jpg

定时器配置

pinout_config.jpg

时钟分频计算方法

T = (psc+1)(arr+1)/Tclk = (50399+1)(499+1)/84MHz = 300ms

其中

PSC 为定时器预分频系数 prescaler 取值范围 [0, 65535]

arr 为自动重装载值 Counter Period (AutoReload Register) 取值范围 [0, 65535]

Tclk 为系统时钟频率 System Clock,这里为 84MHz

进入 NVIC Settings 标签,使能定时器中断

配置完成后,进入 Project Manager 标签栏,进行项目命名、保存路径设置、编译器选择等操作;

点击 Generate Code 按钮,使用 STM32CubeIDE 或 Keil 打开目标工程;

编译工程,0 error, 0 warning .

代码

在进入主函数前,需调用定时器回调函数,并在其中加入中断执行代码,即 LED 闪烁 (GPIO 电平翻转)

/**
  * @brief          Timer period Callback
  * @param[in]      htim - pointer
  * @retval         none
  */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim == &htim3)
    {
      //300ms trigger
      HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
    }
}

进入主函数,需要使能定时器中断服务

// ----- HAL_TIM_Base_Start(&htim3) ---------
HAL_TIM_Base_Start_IT(&htim3);

完整 main.c 代码

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/**
  * @brief          Timer period Callback
  * @param[in]      htim - pointer
  * @retval         none
  */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim == &htim3)
    {
      //300ms trigger
      HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
    }
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM3_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start_IT(&htim3); // -- HAL_TIM_Base_Start(&htim3);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 16;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks*/
  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_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT

void assert_failed(uint8_t *file, uint32_t line)
{
}
#endif /* USE_FULL_ASSERT */

★ 注意用户自定义代码需写入 /* USER CODE BEGIN x */ 和 /* USER CODE END x */ 之间,确保CubeMX再次生成工程,代码不会被覆盖。

保存代码,重新编译工程,调试或运行程序,将固件上传至 NUCLEO-F411RE 开发板,程序运行,板载 LED 按照定时器周期准确闪烁。

参考:stm32cubemx 定时器定时器闪烁LED .

效果

板载 LED 按照 300 毫秒的周期准确闪烁

blink_Timer.gif

总结

该项目结合 SMT32CubeMX 软件快速生成工程,实现了通过定时器精确定时 300 毫秒的 GPIO 电平翻转以及 LED 闪烁项目,为定时器相关的应用设计提供了参考。





关键词: 活动     定时器     中断     LED     STM32    

专家
2025-05-10 20:13:35     打赏
2楼

感谢分享


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]