STM32——HAL库开发笔记22(定时器3—呼吸灯实验)(参考来源:b站铁头山羊)

本文利用前几节所学知识来实现一个呼吸灯实验:两颗led灯交替呼吸。

一、STM32CubeMX配置

step1:配置调试接口

step2:配置定时器

定时器1位于APB2总线上,如上图所示。

step3:配置时基单元

按照下图配置

时钟来源配置为内部RCC

预分频器PSC设置为7

自动重装寄存器ARR设置为999

计数方向CNT设置为上计数

重复计数器RCR设置为0

为了防止寄存器跑飞,我们使能ARR寄存器的预加载

设置完成后定时器CNT的值就会从0增加到999,而且发送一次溢出,周期为1ms

step4:输出PWM

使用定时器1的通道1向外输出PWM

Channel1参数说明:

先回顾一下上一节的八种输出比较的模式

最后是No Outout : 两种输出都禁止

CHx :只使能正常输出

CHxN :只使能互补输出

CHx CHxN :两种输出都使能

我们选择两种输出都使能

step5:连接电路图

step6:设置CH1的PWM参数

step7:生成代码

step8:

step9:

step10:

二、编程接口

复制代码
HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim ,uint32_t Channel)

作用 :启动PWM的正常输出

HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim ,uint32_t Channel)


作用 :启动PWM的互补输出

参数说明:htim  填写定时器句柄
 
         Channel :填写通道编号                 TIM_CHANNEL_1 - 通道1
                                               TIM_CHANNEL_2 - 通道2
                                               TIM_CHANNEL_3 - 通道3
                                               TIM_CHANNEL_4 - 通道4

__HAL_TIM_GET_PRESCALER(__HANDLE__)                //读PSC

__HAL_TIM_SET_PRESCALER(__HANDLE__ , __VAL__)                //写PSC

___________________________________________________________________________________________

__HAL_TIM_GET_COUBTER(__HANDLE__)                //读CNT

__HAL_TIM_SET_COUNTER(__HANDLE__ , __VAL__)                //写CNT

___________________________________________________________________________________________

__HAL_TIM_GET_AUTORELOAD(__HANDLE__)                //读ARR

__HAL_TIM_SET_AUTORELOAD(__HANDLE__ , __VAL__)                //写ARR

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

__HAL_TIM_GET_COMPARE(__HANDLE__)                //读CCR

__HAL_TIM_SET_COMPARE(__HANDLE__ , __VAL__)                //写CCR

三、编程思路

公式:占空比 = 0.5sin(2Πt + 0.5)

复制代码
先启动 通道1的正常输出
再启动通道1 的互补输出

在while循环里面根据公式修改PWM的占空比        PWM的周期 = ARR+1

占空比 = 高电压所占时间 / 总时间 = CCR / ARR+1

在while循环里面 :

先获取当前时间

计算占空比

获取ARR寄存器的值

计算CCR寄存器的值

将结果写入CCR

四、代码

复制代码
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2025 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "tim.h"
#include "gpio.h"
#include "math.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 */

/* 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_TIM1_Init();
  /* USER CODE BEGIN 2 */
	
HAL_TIM_PWM_Start(&htim1 , TIM_CHANNEL_1);  //启动正常输出

HAL_TIMEx_PWMN_Start(&htim1 , TIM_CHANNEL_1);  //启动互补输出

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		
		float t = HAL_GetTick()* 0.01 ;// 获取当前时间
		
		float duty = 0.5 * sin(2 * 3.14 * t) + 0.5 ; // 计算占空比
		
		uint16_t arr = __HAL_TIM_GET_AUTORELOAD(&htim1);  //获取ARR寄存器的值
		
		uint16_t ccr =duty * (arr + 1);        //计算CCR寄存器的值
		
		__HAL_TIM_SET_COMPARE(&htim1 , TIM_CHANNEL_1 , ccr);   //将计算结果写入CCR
		
    /* 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};

  /** 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 */

最后将代码下载编译即可看到两颗LED灯交替闪烁。

相关推荐
新子y1 天前
【小白笔记】最大交换 (Maximum Swap)问题
笔记·python
你要飞1 天前
Hexo + Butterfly 博客添加 Live2D 看板娘指南
笔记
Vae_Mars1 天前
单片机中的TVS管
单片机·嵌入式硬件
hazy1k1 天前
51单片机基础-直流电机控制
stm32·单片机·嵌入式硬件·51单片机
ajsbxi1 天前
【Java 基础】核心知识点梳理
java·开发语言·笔记
呱呱巨基1 天前
vim编辑器
linux·笔记·学习·编辑器·vim
新子y1 天前
【小白笔记】普通二叉树(General Binary Tree)和二叉搜索树的最近公共祖先(LCA)
开发语言·笔记·python
聪明的笨猪猪1 天前
Java JVM “调优” 面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
爱学习的uu1 天前
CURSOR最新使用指南及使用思路
人工智能·笔记·python·软件工程
YuCaiH1 天前
Linux文件处理
linux·笔记·嵌入式