随着嵌入式开发的不断深入,STM32系列微控制器凭借其强大的性能和丰富的外设资源,成为了工程师们的首选。在这篇文章中,我们将以STM32G431为例,讲解如何实现PWM(脉宽调制)输出功能,从代码实现到实际应用,让你快速掌握这一常用功能。
什么是PWM?PWM(Pulse Width Modulation)是一种通过改变脉冲宽度来调节输出信号的技术,广泛应用于电机控制、LED调光、音频信号生成等领域。通过STM32G431的高级定时器,我们可以轻松生成精确的PWM信号。
工程准备在开始之前,你需要准备以下材料:
- STM32G431开发板(例如Nucleo-G431RB)
- ST-LINK调试器
- Keil、STM32CubeIDE或其他开发工具
- STM32CubeMX初始化代码生成工具
我们将以TIM1定时器的通道1为例,生成50Hz的PWM信号,并且占空比可以调节。
PWM实现步骤- 配置硬件资源使用STM32CubeMX配置TIM1为PWM模式,并将输出引脚设置为PA8(TIM1_CH1)。
- 初始化代码生成利用STM32CubeMX生成初始化代码,并在生成的工程中补充PWM控制代码。
- 编写主程序在主程序中初始化PWM并设置占空比。
代码实现以下是实现50Hz PWM信号的完整代码,支持动态调整占空比:
#include "main.h"
// 定义PWM占空比
uint32_t dutyCycle = 50; // 默认50%
// PWM初始化函数
void PWM_Init(void) {
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); // 启动PWM
}
// 调节占空比函数
void Set_PWM_DutyCycle(uint32_t duty) {
if (duty <= 100) {
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, (htim1.Init.Period + 1) * duty / 100);
}
}
int main(void) {
HAL_Init(); // 初始化HAL库
SystemClock_Config(); // 配置系统时钟
MX_GPIO_Init(); // 初始化GPIO
MX_TIM1_Init(); // 初始化TIM1
PWM_Init(); // 启动PWM
while (1) {
// 动态调节占空比
for (dutyCycle = 0; dutyCycle <= 100; dutyCycle += 10) {
Set_PWM_DutyCycle(dutyCycle);
HAL_Delay(500); // 每500ms调整一次
}
for (dutyCycle = 100; dutyCycle >= 0; dutyCycle -= 10) {
Set_PWM_DutyCycle(dutyCycle);
HAL_Delay(500);
}
}
}
// TIM1初始化函数(由STM32CubeMX生成)
void MX_TIM1_Init(void) {
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
htim1.Instance = TIM1;
htim1.Init.Prescaler = 1700 - 1; // 时钟预分频
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 1000 - 1; // 设置周期,生成50Hz信号
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim1) != HAL_OK) {
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) {
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim1) != HAL_OK) {
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) {
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0; // 初始占空比为0
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) {
Error_Handler();
}
HAL_TIM_MspPostInit(&htim1);
}
代码解析- PWM初始化通过HAL_TIM_PWM_Start函数启动定时器的PWM功能。
- 占空比调节使用__HAL_TIM_SET_COMPARE动态设置比较值,从而调整PWM信号的占空比。
- 延时循环使用HAL_Delay模拟占空比逐步变化的效果,可以用于调光或调速应用。
注意事项- 确保使用的引脚支持定时器功能,具体引脚信息可参考STM32G431的引脚分配表。
- PWM信号的频率由定时器的Prescaler和Period共同决定,确保正确设置以满足应用需求。
- 如果需要更高的分辨率或更低的频率,可以适当调整定时器参数。
总结通过本文的示例代码,STM32G431可以轻松实现PWM输出,并可根据实际需求动态调整占空比。这种实现方式不仅适用于简单的LED调光,还可以拓展到复杂的电机控制或音频信号生成中。希望这篇文章能够帮助你快速掌握STM32 PWM功能的使用。
|