STM32F407ZG是一款基于Arm Cortex-M4架构的高性能微控制器,运行主频高达168 MHz,内置丰富的外设资源和强大的定时器功能,非常适合需要精确时序控制的应用场景,比如电机驱动、LED调光和信号发生器。
本文将通过配置STM32F407ZG的定时器(Timer),实现一个简单的PWM信号生成,并应用于控制LED的亮度。希望通过这篇文章,帮助初学者快速掌握PWM的基本概念和STM32的实现方法。
准备工作硬件准备:
- STM32F407ZG开发板(如STM32F4 Discovery或Nucleo-F407ZG)。
- 一个LED及其限流电阻(也可以直接使用板载LED)。
软件工具:
- STM32CubeIDE或Keil MDK(本文基于STM32CubeIDE)。
- STM32CubeMX,用于生成初始化代码。
项目目标- 配置Timer 3生成PWM信号。
- 调节PWM占空比控制LED亮度。
- 通过USART调试,实时调整占空比。
硬件连接- 使用板载LED时,无需额外连接,板载LED连接在PC13上。
- 如果使用外接LED,将LED正极接PA6(Timer 3的Channel 1输出引脚),负极通过限流电阻接地。
代码实现以下是完整代码:
#include "main.h"
TIM_HandleTypeDef htim3; // 定时器3句柄
UART_HandleTypeDef huart2; // UART句柄
uint8_t rx_data[1]; // 接收数据缓冲区
volatile uint8_t duty_cycle = 50; // 初始占空比,50%
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM3_Init(void);
static void MX_USART2_UART_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM3_Init();
MX_USART2_UART_Init();
// 开始PWM输出
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
// 设置初始占空比
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, duty_cycle);
// 开启UART接收中断
HAL_UART_Receive_IT(&huart2, rx_data, 1);
while (1)
{
// 主循环空闲,可扩展其他逻辑
}
}
// UART中断回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART2)
{
if (rx_data[0] >= '0' && rx_data[0] <= '9') // 检查输入是否为数字
{
duty_cycle = (rx_data[0] - '0') * 10; // 转换占空比(0-100)
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, duty_cycle); // 更新占空比
}
// 重新开启接收中断
HAL_UART_Receive_IT(&huart2, rx_data, 1);
}
}
// 定时器3初始化
static void MX_TIM3_Init(void)
{
TIM_OC_InitTypeDef sConfigOC = {0};
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
htim3.Instance = TIM3;
htim3.Init.Prescaler = 84 - 1; // 1 MHz计数频率
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 100 - 1; // PWM频率为10 kHz
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 50; // 初始占空比50%
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
}
// USART2初始化
static void MX_USART2_UART_Init(void)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = 9600;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
}
// GPIO初始化
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
// 错误处理函数
void Error_Handler(void)
{
while (1)
{
// 错误状态指示
}
}
代码说明- PWM信号生成:
- 使用定时器3的通道1生成PWM信号,频率为10 kHz。
- 初始占空比为50%,通过UART输入调整占空比。
- UART通信:
- 接收用户输入的数字(0-9),实时调整PWM信号的占空比。
- 可扩展性:
- 可以添加更多UART命令实现频率调节或切换其他功能。
项目验证- 将代码烧录到STM32F407ZG开发板。
- 使用串口助手(如PuTTY)连接USART2,波特率设置为9600。
- 在串口中输入0-9,观察LED亮度随占空比变化。
总结通过本项目,您可以初步掌握STM32的PWM生成与应用。STM32F407ZG的高性能和灵活性使其能够满足多种嵌入式需求。如果进一步扩展,可以尝试多通道PWM生成或结合ADC实现闭环控制。
|