寄存器实现
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 */
}