STM32使用定时器、PWM波

一、定时器

  • 在 STM32 中,定时器(Timer) 是一种硬件外设,常用于生成精确的时间延迟、测量时间间隔、PWM(脉宽调制)输出、捕获输入信号的时间、生成定时中断等。
  • STM32 的定时器类型通常包括基础定时器(如 TIM6 和 TIM7)、通用定时器(如 TIM2到TIM5)、高级定时器(如TIM1和TIM8)等。
  • 输入捕获
    定时器可以捕获外部信号的变化并记录其发生时间,常用于测量信号的频率或周期,如脉冲计数、测速等。
  • RCC(Reset and Clock Control,复位与时钟控制)是 STM32 微控制器中的一个重要模块,它负责管理和控制系统的时钟和复位功能。
  1. 选择时钟源:定时器的时钟源可以来自APB总线时钟或外部时钟。
  2. 设置预分频器(Prescaler):预分频器用于降低计数器的计数频率。通过设定预分频器值,可以让定时器的时钟频率为系统时钟的1/N,其中N为预分频值+1。
  3. 设定自动重装载寄存器(ARR):ARR决定了计数器从0计数到ARR的周期。定时器到达ARR值时会触发更新事件,可以通过中断响应或自动重置计数器。
  4. 据此2,3,可以算出多少时间产生溢出事件T = (Prescaler+1)* (Period +1)/TIMClk
设APB1 时钟(定时器 TIM5 的时钟)频率为 64 MHz,现在我们来看看为什么选择了这两个值:
Prescaler = 64000 - 1(STM32 的定时器会从 0 开始,故减1)
这个设置的意思是将 64 MHz 的时钟频率预分频 64000 次。
预分频后的定时器时钟频率为:
定时器时钟频率=64MHz/64000=1kHz
也就是说,现在定时器每秒计数 1000 次,每次计数的时间间隔为 1 毫秒。


Counter Period = 1000 - 1(定时器会从 0 计数到这个值)
计数周期设置为 1000,也就是说,定时器会从 0 计数到 999(总共 1000 个计数),然后产生一次溢出事件。
由于定时器时钟频率现在为 1 kHz,每次计数的时间间隔是 1 毫秒,因此计数 1000 次的总时间为:
1000×1ms=1秒
这意味着,定时器每经过 1 秒会产生一次溢出中断。
  1. 使用方法(TIM5)
    1). 使用TIM5的内部时钟源。(选择通道的话,就是要有确定的GPIO配置)
    2). 并设置Prescaler 为64000-1和Counter Period为1000-1
    3). 在NIVC Interrupt Table中允许TIM5 global Interrupt 中断使能
    4).RCC的High-Speed Clock的模式选择Crystal/Ceramic pesaonator,可以提供比内部振荡器更精确、稳定的时钟信号。
    5. 并时钟配置如下图
    ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/86a4002aa9b0450780d32932c973872f.png
    6. 配置LED的管脚
    7. 在main函数中启动定时器HAL_TIM_Base_Start_IT(&htim5);
    8. 然后在HAL_TIM_PeriodElapsedCallback处理你想要做的事情。
  2. 代码示例
控制灯一闪一闪的
#include "main.h"  // 包含主头文件,包含STM32 HAL库的声明

TIM_HandleTypeDef htim5;  // 声明TIM5句柄

void SystemClock_Config(void);  // 声明系统时钟配置函数
static void MX_TIM5_Init(void);  // 声明TIM5初始化函数
static void MX_GPIO_Init(void);  // 声明GPIO初始化函数

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
   
	HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_6|GPIO_PIN_7);  // 定时器中断回调,切换GPIOC引脚6和7的电平
}

int main(void)
{
   
  HAL_Init();  // 初始化HAL库
  SystemClock_Config();  // 配置系统时钟
  MX_TIM5_Init();  // 初始化TIM5定时器
  MX_GPIO_Init();  // 初始化GPIO引脚
  HAL_TIM_Base_Start_IT(&htim5);  // 启动TIM5定时器并使能中断

  while (1)  // 无限循环
  {
   
  }
}

void SystemClock_Config(void)
{
   
  RCC_OscInitTypeDef RCC_OscInitStruct = {
   0};  // RCC时钟结构体,用于配置振荡器
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {
   0};  // RCC时钟结构体,用于配置总线时钟

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;  // 配置使用HSE外部高频振荡器
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;  // 打开HSE振荡器
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;  // HSE预分频设置为1
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;  // 启用内部高频振荡器HSI
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;  // 启用PLL(锁相环)模块
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;  // 设置PLL时钟源为HSE
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL8;  // PLL倍频系数设置为8
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)  // 配置时钟并检查是否成功
  {
   
    Error_Handler();  // 如果配置失败,进入错误处理
  }

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;  // 配置HCLK、SYSCLK、PCLK1和PCLK2
  RCC_ClkInitStruct
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值