在嵌入式系统中,PWM(脉宽调制)广泛应用于电机控制、LED调光等场景。本文将基于ST公司的STM32F407微控制器,通过定时器实现PWM输出功能,深入探讨实现过程与代码细节。
一、硬件和软件准备- 硬件:
- STM32F407开发板
- LED模块或负载设备
- 示波器(用于检测PWM波形)
- 软件:
二、PWM输出的原理PWM信号是一种数字信号,通过调节高电平占空比来模拟连续变化的模拟量。STM32F407内部集成了多组高级定时器(如TIM1、TIM8),可以通过硬件直接生成稳定的PWM信号。
三、实现步骤- 配置定时器:通过STM32CubeMX初始化定时器,设置为PWM模式,并指定输出引脚。
- 编写代码:设置占空比,控制输出信号的强弱。
- 验证结果:使用LED灯或示波器验证PWM波形。
四、代码实现以下代码展示如何使用STM32F407生成一组50Hz、占空比可调的PWM信号。
#include "stm32f4xx_hal.h"
TIM_HandleTypeDef htim3;
/* 定时器初始化 */
void MX_TIM3_Init(void)
{
TIM_OC_InitTypeDef sConfigOC = {0};
htim3.Instance = TIM3;
htim3.Init.Prescaler = 84 - 1; // 预分频器,将84MHz分为1MHz
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 20000 - 1; // 1MHz计数到20000对应50Hz
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 1500; // 初始占空比为7.5% (1500/20000)
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
}
/* 主函数 */
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_TIM3_Init();
/* 开启PWM输出 */
if (HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
while (1)
{
for (int duty = 500; duty <= 2500; duty += 100) // 调整占空比
{
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, duty);
HAL_Delay(500); // 延时500ms
}
}
}
/* 系统时钟配置 */
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
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;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
Error_Handler();
}
}
/* 错误处理函数 */
void Error_Handler(void)
{
while (1)
{
// 错误状态循环处理
}
}
五、实验结果通过示波器,我们可以观察到50Hz的PWM信号,并且通过代码动态调整占空比,负载(如LED)亮度随之变化。
六、总结STM32F407强大的定时器资源,使得生成精准的PWM信号变得非常方便。在实际项目中,我们可以扩展该功能,用于电机速度控制或信号调制。
|