STM32通用定时器(HAL库)定时中断、PWM呼吸灯

定时器和延时函数的区别

通用定时器结构

时钟信号:

触发控制器选择时钟信号:

  • 内部时钟驱动:
  • 从模式:用其他定时器的触发信号作为时钟信号(ITR0、ITR1)
  • 时基单元:

    基本定时器已经讲过,下面节选字stm32cubemx的教程基础篇

    捕获/比较通道

    定时器的捕获/比较通道可以用于多种应用,包括测量信号的频率、脉宽调制(PWM)信号的生成和控制等。

    输入捕获:用于捕获外部信号的事件时间,可用于测量频率和脉宽。

    输出比较:用于生成特定的PWM信号或控制外部设备(如伺服电机)。

    捕获:

    通过检测边沿信号,在边沿信号跳转时,将定时器的TIMx_CNT的值放到TIMx_CCR(捕获/比较寄存器)里。

    输入捕获模式

    当外部信号沿(上升沿或下降沿)到达时,当前计数器的值会被捕获并存储在相应的CCR寄存器中。这可以用来计算信号的频率、脉宽等信息。可以用来测量脉冲宽度或者测量频率。

    t1-t2 时间就是我们需要测量的高电平时间,假如定时器工作在向上计数模式,测量方法是:首先设置定时器通道 x 为上升沿捕获,这样在 t1 时刻,就会捕获到当前的 CNT 值,然后立即清零 CNT,并设置通道 x 为下降沿捕获,这样到 t2 时刻,又会发生捕获事件,得到此时的 CNT 值,记为 CCRx2。根据定时器的计数频率,我们就可以算出 t1-t2 的时间,从而得到高电平脉宽。在 t1-t2 时间内可能会出现 N 次定时器溢出,因此我们还需要对定时器溢出进行处理,防止因高电平时间过长发生溢出导致测量数据不准。CNT计数的次数等于:N*ARR+CCRx2,有了这个计数次数,再乘以 CNT 的计数周期,即可得到 t2-t1 的时间长度,即高电平持续时间。

    PWM输入模式

    在PWM模式下,TIMx_CCR寄存器的值决定了输出信号的高电平持续时间,即占空比。

    设定比较值后,当计数器的值达到该比较值时,触发相应的事件,比如切换输出引脚状态。

    比较

    计数器的值和与装载的值进行比较。

  • 强置输出模式
  • 输出比较模式
  • PWM模式
  • 单脉冲模式
  • 在PWM模式下,TIMx_CCR寄存器的值决定了输出信号的高电平持续时间,即占空比。改变 CCRx 的值,就可以改变 PWM 输出的占空比,改变 ARR 的值,就可以改变 PWM 输出的频率。

    设定比较值后,当计数器的值达到该比较值时,触发相应的事件,比如切换输出引脚状态。

    相关HAL函数

  • PWM
  • 初始化

    HAL_TIM_PWM_Init(TIM_HandleTypeDef *htim);

    HAL_StatusTypeDef HAL_TIM_PWM_Init(TIM_HandleTypeDef *htim)
    {
      /* 检查定时器句柄是否分配 */
      if (htim == NULL)
      {
        return HAL_ERROR;
      }
    
      /* 检查参数的有效性 */
      assert_param(IS_TIM_INSTANCE(htim->Instance));
      assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode));
      assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision));
      assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload));
    
      if (htim->State == HAL_TIM_STATE_RESET)
      {
        /* 分配锁资源并进行初始化 */
        htim->Lock = HAL_UNLOCKED;
    
    #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
        /* 将中断回调重置为传统的弱回调函数 */
        TIM_ResetCallback(htim);
    
        if (htim->PWM_MspInitCallback == NULL)
        {
          htim->PWM_MspInitCallback = HAL_TIM_PWM_MspInit;
        }
        /* 初始化底层硬件:GPIO、时钟、NVIC */
        htim->PWM_MspInitCallback(htim);
    #else
        /* 初始化底层硬件:GPIO、时钟、NVIC 及 DMA */
        HAL_TIM_PWM_MspInit(htim);
    #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
      }
    
      /* 设置定时器状态 */
      htim->State = HAL_TIM_STATE_BUSY;
    
      /* 初始化PWM的基本时间 */
      TIM_Base_SetConfig(htim->Instance, &htim->Init);
    
      /* 初始化DMA突发操作状态 */
      htim->DMABurstState = HAL_DMA_BURST_STATE_READY;
    
      /* 初始化定时器通道状态 */
      TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY);
      TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY);
    
      /* 初始化定时器状态 */
      htim->State = HAL_TIM_STATE_READY;
    
      return HAL_OK;
    }
    

    HAL_TIM_PWM_DeInit(TIM_HandleTypeDef *htim);

    反初始化定时器PWM功能,将定时器的设置重置为其默认状态,并释放相关资源。

    HAL_TIM_PWM_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OC_InitTypeDef *sConfig, uint32_t Channel);

    sConfig为指向 PWM 配置结构体的指针,该结构体中包含了 PWM 模式下的输出比较初始化参数。这些参数通常包括:

    Pulse: 定义在一个计数周期内的脉冲宽度(即占空比)。

    OCMode: 定义输出比较模式(如 PWM 模式 1 或 2)。

    Polarity: 定义输出的极性(如高或低有效)。

    FastMode: 加速模式的启用/禁用。

    OCFastMode: 是否启用快速模式。

    操作函数

    HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel);

    启动PWM输出。

    HAL_StatusTypeDef HAL_TIM_PWM_Stop(TIM_HandleTypeDef *htim, uint32_t Channel);

    停止PWM输出。

    HAL_StatusTypeDef HAL_TIM_PWM_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel);

    启动PWM输出并使能中断。

    HAL_StatusTypeDef HAL_TIM_PWM_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel);

    停止PWM输出并禁用中断。

    HAL_TIM_PWM_SetCompare(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t CompareValue);

    设置PWM通道的比较值(占空比),以动态调整PWM输出。

    HAL_TIM_OCxPreloadConfig(TIM_HandleTypeDef *htim, uint32_t Channel, FunctionalState NewState);

    用于配置输出比较通道的预装载功能,这个功能可以增强PWM信号的稳定性和一致性。OCx 代表输出比较通道(如 OC1、OC2 等),其中 x 是通道的编号。

    HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)

    当 PWM 脉冲完成时调用的回调函数,允许用户执行自定义操作。

  • 输入捕获

  • HAL_TIM_IC_Init(&htim);

    初始化定时器的输入捕获功能。

    HAL_TIM_IC_ConfigChannel(TIM_HandleTypeDef *htim, TIM_IC_InitTypeDef *sConfig, uint32_t Channel)

    TIM_IC_InitTypeDef sConfigIC;
    sConfigIC.ICPolarity = TIM_ICPOLARITY_RISING; // 设置捕获极性
    sConfigIC.ICSelection = TIM_IC_SELECTION_DIRECTTI; // 直接连接
    sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; // 不分频
    sConfigIC.ICFilter = 0; // 无滤波
    HAL_TIM_IC_ConfigChannel(&htim, &sConfigIC, TIM_CHANNEL_1);
    

    HAL_TIM_IC_ConfigChannel(&htim, &sConfigIC, TIM_CHANNEL_1);

    HAL_TIM_IC_Start(TIM_HandleTypeDef *htim, uint32_t Channel);

    启动指定的输入捕获通道。

    HAL_TIM_IC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel);

    停止指定的输入捕获通道。

    HAL_TIM_IC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel);

    HAL_TIM_IC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel);

    启动\停止输入捕获通道并使能中断。

    HAL_TIM_IC_GetState(TIM_HandleTypeDef *htim);

    获取输入捕获通道的状态。

    HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)

    输入捕获事件发生时调用的回调函数,用户可以在这里处理捕获数据。

  • PWM输入

  • PWI模式(输入捕获的特例)是专为捕获PWM信号设计的输入捕获模式。在该模式下,定时器的两个输入捕获通道(通常为CH1和CH2)协同工作,通过捕获PWM信号的两个不同特征(通常是上升沿和下降沿)来实现对信号频率和占空比的测量。

    CH1通常用于捕获PWM信号的上升沿,以此来测量信号的周期。

    CH2则用于捕获PWM信号的下降沿,用于计算占空比。

    HAL库的定时器中断结构

    HAL_TIM_IRQHandler()框架,根据不同的中断标志位和中断事件调用不同的中断回调函数。

    定时器同步

    参考下文介绍

    多个定时器同步输出的主从配置示例 – STM32团队 ST意法半导体中文论坛 (stmicroelectronics.cn)

    生成PWM波和定时中断

    PWM原理

    基础设置

    配置Timer的时钟信号

    将TIM2配置基本定时功能,

    设置NVIC

    配置PWM输出

    设置参数

    设置PWM通道的GPIO配置

    代码

    定时器的函数结构

    main.c

    HAL_Delay()改变了PWM 占空比调节的速度

    main.c

    /* USER CODE BEGIN Header */
    /**
      ******************************************************************************
      * @file           : main.c
      * @brief          : Main program body
      ******************************************************************************
      * @attention
      *
      * <h2><center>&copy; Copyright (c) 2024 STMicroelectronics.
      * All rights reserved.</center></h2>
      *
      * This software component is licensed by ST under BSD 3-Clause license,
      * the "License"; You may not use this file except in compliance with the
      * License. You may obtain a copy of the License at:
      *                        opensource.org/licenses/BSD-3-Clause
      *
      ******************************************************************************
      */
    /* USER CODE END Header */
    /* Includes ------------------------------------------------------------------*/
    #include "main.h"
    #include "tim.h"
    #include "gpio.h"
    
    /* Private includes ----------------------------------------------------------*/
    /* USER CODE BEGIN Includes */
    
    /* USER CODE END Includes */
    
    /* Private typedef -----------------------------------------------------------*/
    /* USER CODE BEGIN PTD */
    
    /* USER CODE END PTD */
    
    /* Private define ------------------------------------------------------------*/
    /* USER CODE BEGIN PD */
    /* USER CODE END PD */
    
    /* Private macro -------------------------------------------------------------*/
    /* USER CODE BEGIN PM */
    
    /* USER CODE END PM */
    
    /* Private variables ---------------------------------------------------------*/
    
    /* USER CODE BEGIN PV */
    
    /* USER CODE END PV */
    
    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    /* USER CODE BEGIN PFP */
    
    /* USER CODE END PFP */
    
    /* Private user code ---------------------------------------------------------*/
    /* USER CODE BEGIN 0 */
    
    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){//定时器中断回调函数
    	if(htim==(&htim2))//判断产生中断的定时器
    	{
    		HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);//LED状态反转
    	}
    }
    
    
    /* USER CODE END 0 */
    
    /**
      * @brief  The application entry point.
      * @retval int
      */
    int main(void)
    {
      /* USER CODE BEGIN 1 */
    
      /* USER CODE END 1 */
    
      /* 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_TIM2_Init();
      MX_TIM3_Init();
      /* USER CODE BEGIN 2 */
      HAL_TIM_Base_Start_IT(&htim2);
      HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4);
     
      uint16_t a=0;//定义占空比变量并给出初始值
      
      
      /* USER CODE END 2 */
    
      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
        /* USER CODE END WHILE */
    	 while(a < 500){ 
    	  a++;
    	  __HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_4,a);//设置占空比函数(参数3是PWM比值,范围0~ARR计数周期) 
    		 HAL_Delay(10);
    	 }
    	 while(a)
    	 {
    		 a--;
    		 __HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_4,a);
    		 HAL_Delay(10);
    	 
    	 }
        /* 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_NONE;
      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_HSI;
      RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
      RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
      RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    
      if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
      {
        Error_Handler();
      }
    }
    
    /* USER CODE BEGIN 4 */
    
    /* USER CODE END 4 */
    
    /**
      * @brief  This function is executed in case of error occurrence.
      * @retval None
      */
    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
    /**
      * @brief  Reports the name of the source file and the source line number
      *         where the assert_param error has occurred.
      * @param  file: pointer to the source file name
      * @param  line: assert_param error line source number
      * @retval None
      */
    void assert_failed(uint8_t *file, uint32_t line)
    {
      /* USER CODE BEGIN 6 */
      /* User can add his own implementation to report the file name and line number,
         ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
      /* USER CODE END 6 */
    }
    #endif /* USE_FULL_ASSERT */
    
    /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

    tim.c

    /**
      ******************************************************************************
      * @file    tim.c
      * @brief   This file provides code for the configuration
      *          of the TIM instances.
      ******************************************************************************
      * @attention
      *
      * <h2><center>&copy; Copyright (c) 2024 STMicroelectronics.
      * All rights reserved.</center></h2>
      *
      * This software component is licensed by ST under BSD 3-Clause license,
      * the "License"; You may not use this file except in compliance with the
      * License. You may obtain a copy of the License at:
      *                        opensource.org/licenses/BSD-3-Clause
      *
      ******************************************************************************
      */
    
    /* Includes ------------------------------------------------------------------*/
    #include "tim.h"
    
    /* USER CODE BEGIN 0 */
    
    /* USER CODE END 0 */
    
    TIM_HandleTypeDef htim2;
    TIM_HandleTypeDef htim3;
    
    /* TIM2 init function */
    void MX_TIM2_Init(void)
    {
      TIM_ClockConfigTypeDef sClockSourceConfig = {0};
      TIM_MasterConfigTypeDef sMasterConfig = {0};
    
      htim2.Instance = TIM2;
      htim2.Init.Prescaler = 9999;
      htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
      htim2.Init.Period = 7199;
      htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
      htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
      if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
      {
        Error_Handler();
      }
      sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
      if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
      {
        Error_Handler();
      }
      sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
      sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
      if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
      {
        Error_Handler();
      }
    
    }
    /* TIM3 init function */
    void MX_TIM3_Init(void)
    {
      TIM_ClockConfigTypeDef sClockSourceConfig = {0};
      TIM_MasterConfigTypeDef sMasterConfig = {0};
      TIM_OC_InitTypeDef sConfigOC = {0};
    
      htim3.Instance = TIM3;
      htim3.Init.Prescaler = 71;
      htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
      htim3.Init.Period = 499;
      htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
      htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
      if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
      {
        Error_Handler();
      }
      sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
      if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
      {
        Error_Handler();
      }
      if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
      {
        Error_Handler();
      }
      sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
      sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
      if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
      {
        Error_Handler();
      }
      sConfigOC.OCMode = TIM_OCMODE_PWM1;
      sConfigOC.Pulse = 0;
      sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
      sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
      if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
      {
        Error_Handler();
      }
      HAL_TIM_MspPostInit(&htim3);
    
    }
    
    void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
    {
    
      if(tim_baseHandle->Instance==TIM2)
      {
      /* USER CODE BEGIN TIM2_MspInit 0 */
    
      /* USER CODE END TIM2_MspInit 0 */
        /* TIM2 clock enable */
        __HAL_RCC_TIM2_CLK_ENABLE();
    
        /* TIM2 interrupt Init */
        HAL_NVIC_SetPriority(TIM2_IRQn, 2, 0);
        HAL_NVIC_EnableIRQ(TIM2_IRQn);
      /* USER CODE BEGIN TIM2_MspInit 1 */
    
      /* USER CODE END TIM2_MspInit 1 */
      }
      else if(tim_baseHandle->Instance==TIM3)
      {
      /* USER CODE BEGIN TIM3_MspInit 0 */
    
      /* USER CODE END TIM3_MspInit 0 */
        /* TIM3 clock enable */
        __HAL_RCC_TIM3_CLK_ENABLE();
    
        /* TIM3 interrupt Init */
        HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0);
        HAL_NVIC_EnableIRQ(TIM3_IRQn);
      /* USER CODE BEGIN TIM3_MspInit 1 */
    
      /* USER CODE END TIM3_MspInit 1 */
      }
    }
    void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
    {
    
      GPIO_InitTypeDef GPIO_InitStruct = {0};
      if(timHandle->Instance==TIM3)
      {
      /* USER CODE BEGIN TIM3_MspPostInit 0 */
    
      /* USER CODE END TIM3_MspPostInit 0 */
    
        __HAL_RCC_GPIOB_CLK_ENABLE();
        /**TIM3 GPIO Configuration
        PB1     ------> TIM3_CH4
        */
        GPIO_InitStruct.Pin = LED4_Pin;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_PULLUP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
        HAL_GPIO_Init(LED4_GPIO_Port, &GPIO_InitStruct);
    
      /* USER CODE BEGIN TIM3_MspPostInit 1 */
    
      /* USER CODE END TIM3_MspPostInit 1 */
      }
    
    }
    
    void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
    {
    
      if(tim_baseHandle->Instance==TIM2)
      {
      /* USER CODE BEGIN TIM2_MspDeInit 0 */
    
      /* USER CODE END TIM2_MspDeInit 0 */
        /* Peripheral clock disable */
        __HAL_RCC_TIM2_CLK_DISABLE();
    
        /* TIM2 interrupt Deinit */
        HAL_NVIC_DisableIRQ(TIM2_IRQn);
      /* USER CODE BEGIN TIM2_MspDeInit 1 */
    
      /* USER CODE END TIM2_MspDeInit 1 */
      }
      else if(tim_baseHandle->Instance==TIM3)
      {
      /* USER CODE BEGIN TIM3_MspDeInit 0 */
    
      /* USER CODE END TIM3_MspDeInit 0 */
        /* Peripheral clock disable */
        __HAL_RCC_TIM3_CLK_DISABLE();
    
        /* TIM3 interrupt Deinit */
        HAL_NVIC_DisableIRQ(TIM3_IRQn);
      /* USER CODE BEGIN TIM3_MspDeInit 1 */
    
      /* USER CODE END TIM3_MspDeInit 1 */
      }
    }
    
    /* USER CODE BEGIN 1 */
    
    /* USER CODE END 1 */
    
    /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

    也可以在回调函数里写:

    这个函数实现了按脉宽递增或递减方向修改CCR 的值,因为开启了CCR 预装载功能,所以新设置的CCR的值在下一个UEV事件时才生效。

    可以观察到LED1由明到暗,再由暗到明的循环往复变化效果。

    作者:zhi_beiyou

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32通用定时器(HAL库)定时中断、PWM呼吸灯

    发表回复