名词解释:PWM
本例是一个PWM输出demo。
-
GPIO管脚设置:
将TIM2的Channel3设置为PWM generation GH3,它对应的管脚是PA2,当Channel3设置为PWM generation GH3后,PA2就自动被设置为TIM2_CH3。
-
PWM载波频率设置:
PWM载波频率:
本例的APB1定时器的时钟频率=72MHz。Prescaler=71,Counter Period=999,就可以得到1KHz的载波频率。
-
中断配置:
-
生成代码:
配置完成后生成代码。 记得选这个:
-
新建tim_app.h 和 tim_app.c 文件:
-
在tim_app.h内添加代码:
#ifndef __TIM_APP_H
#define __TIM_APP_H
#include "stm32f1xx_hal.h" // 根据芯片系列调整
void TIM2_PWM_Init(void);
void TIM2_PWM_Start(void);
void TIM2_PWM_Update_Duty(uint32_t duty); // duty: 0~100
#endif
在tim_app.c内添加代码:
#include "tim_app.h"
#include "main.h"
extern TIM_HandleTypeDef htim2;
// 初始化封装(可选)
void TIM2_PWM_Init(void)
{
// CubeMX 已生成 MX_TIM2_Init()
}
// 启动 PWM
void TIM2_PWM_Start(void)
{
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3);
}
// 设置占空比(0~100)
void TIM2_PWM_Update_Duty(uint32_t duty)
{
if (duty > 100) duty = 100;
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, duty * 10); // ARR=999 → duty*10
}
-
在main.c内添加代码:
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
static uint8_t direction = 1; // 1: 增加, 0: 减少
static uint32_t duty = 0; //初始占空比=0%
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
TIM2_PWM_Start();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
TIM2_PWM_Update_Duty(duty);
HAL_Delay(20); // 每 20ms 调整一次,2 秒完成 0→100→0
if (direction)
{
duty++;
if (duty >= 100)
direction = 0;
}
else
{
duty--;
if (duty == 0)
direction = 1;
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
这里是在main.c的主循环里周期刷新占空比,当然也可以再开一个定时器中断,在定时器中断响应里周期调整占空比。