Nuru_Banmian
Nuru_Banmian
Published on 2025-06-18 / 53 Visits
0
0

基本定时器_PMW应用_呼吸灯_寄存器&HAL库实现

寄存器实现

tim5.h

#ifndef __TIM5_H
#define __TIM5_H
#include "stm32f10x.h"void TIM5_Init(void);

// 将定时器的开关包装成函数
void TIM5_Start(void);
void TIM5_Stop(void);

// 设置占空比的函数
void TIM5_SetDutyCycle(uint8_t dutyCycle);

#endif

tim5.c

#include "tim5.h"
void TIM5_Init(void)

{
  // 1. 开启时钟
  RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
  RCC->APB1ENR |= RCC_APB1ENR_TIM5EN;

  // 2. GPIO工作模式,PA1:复用推挽输出 CNF-10,MODE-11
  GPIOA->CRL |= GPIO_CRL_MODE1;
  GPIOA->CRL |= GPIO_CRL_CNF1_1;
  GPIOA->CRL &= ~GPIO_CRL_CNF1_0;

  // 3. 定时器配置
  // 3.1 预分频值 7199,得到10000Hz
  TIM5->PSC = 7199;
  
  // 3.2 重装载值,99,每隔 10ms 溢出一次
  TIM5->ARR = 99;

    // 3.3 计数方向
  TIM5->CR1 &= ~TIM_CR1_DIR;
  
  // 3.4 设置通道2的CCR值
  TIM5->CCR2 = 50;
  
  // 3.5 配置通道2为输出模式
  TIM5->CCMR1 &= ~TIM_CCMR1_CC2S;
  
  // 3.6 配置通道2为PWM1模式,OC2M-110
  TIM5->CCMR1 |= TIM_CCMR1_OC2M_2;
  TIM5->CCMR1 |= TIM_CCMR1_OC2M_1;
  TIM5->CCMR1 &= ~TIM_CCMR1_OC2M_0;
  
  // 3.7 使能输出通道
  TIM5->CCER |= TIM_CCER_CC2E;
}// 将定时器的开关包装成函数
  
void TIM5_Start(void)
{
    TIM5->CR1 |= TIM_CR1_CEN;
}
  
void TIM5_Stop(void)
{
  TIM5->CR1 &= ~TIM_CR1_CEN;
}
  
  // 设置占空比的函数
void TIM5_SetDutyCycle(uint8_t dutyCycle)
{
  TIM5->CCR2 = dutyCycle;
}

main.c

#include "usart.h"
#include "tim5.h"
#include "delay.h"

int main(void)
{
  // 初始化
  USART_Init();
  TIM5_Init();
  
  printf("Hello, world!\n");
  
  // 开启定时器
  TIM5_Start();
  
  // 定义占空比和变化方向
  uint8_t dutyCycle = 0;
  uint8_t dir = 0;
  
  while (1)
  {
  	// 判断当前占空比变化方向,决定新的占空比
  	if (dir == 0)
  	{
  		// 占空比增大
  		dutyCycle += 1;
  		if (dutyCycle >= 99)
  		{
  			dir = 1; // 如果增到最大亮度,就开始减小占空比
  		}
  	}
  	else
  	{
  		// 占空比减小
  		dutyCycle -= 1;
  		if (dutyCycle <= 1)
  		{
  			dir = 0; // 如果减到最小亮度,就开始增大占空比
  		}
  	}
  
  	// 设置占空比
  	TIM5_SetDutyCycle(dutyCycle);
  
  	// 延迟20ms
  	Delay_ms(20);
  }
}

HAL库实现

tim.h

/* USER CODE BEGIN Prototypes */
void TIM5_SetDutyCycle(uint8_t dutyCycle);
/* USER CODE END Prototypes */

tim.c

void TIM5_SetDutyCycle(uint8_t dutyCycle)
{
  __HAL_TIM_SetCompare(&htim5, TIM_CHANNEL_2, dutyCycle);
}

main.c

/* USER CODE BEGIN 2 */
// 开启TIM5
HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_2);

// 定义变量,保存当前的占空比
uint8_t dutyCycle = 1;

// 定义步长
int8_t step = -1;
/* USER CODE END 2 */

/* USER CODE BEGIN WHILE */
while (1)
{
  if (dutyCycle <= 1 || dutyCycle >= 99)
  {
  // 只要超出了占空比取值范围,就直接取步长的相反数(反向)
  step = -step;
  }

  dutyCycle += step;
  TIM5_SetDutyCycle(dutyCycle);

  HAL_Delay(20);
  /* USER CODE END WHILE */
}


Comment