在嵌入式系统中,PWM(脉宽调制)信号常用于控制电机速度、调节LED亮度等场景。本文将以STM32G431微控制器为例,详细讲解如何配置TIM1定时器生成PWM信号,并通过调整占空比实现精确控制。
STM32G431简介STM32G431是ST公司推出的一款功能强大的32位微控制器,基于Cortex-M4内核,主频高达170 MHz。它内置多个高级定时器(如TIM1),支持高分辨率的PWM输出,非常适合电机控制、工业自动化和其他实时应用。
PWM信号生成原理PWM信号通过固定频率的方波控制信号强度,其占空比(即高电平持续时间与整个周期的比值)决定了输出的平均功率。例如,50%占空比表示输出信号的高低电平时间相等,而25%占空比表示高电平时间仅为整个周期的四分之一。
开发环境准备- STM32CubeIDE(用于编写代码和调试)。
- STM32G431开发板。
- 一个PWM信号测试设备(如LED或示波器)。
硬件连接将一个LED连接到开发板的PWM引脚(例如PA8),并在电路中串联一个限流电阻(如220欧姆)。
软件实现以下代码实现了使用TIM1定时器生成PWM信号,并通过调整占空比控制LED的亮度。
- #include "stm32g4xx_hal.h"
- // 定时器句柄
- TIM_HandleTypeDef htim1;
- // 初始化定时器
- void TIM1_Init(void) {
- __HAL_RCC_TIM1_CLK_ENABLE();
- htim1.Instance = TIM1;
- htim1.Init.Prescaler = 170 - 1; // 定时器预分频值
- htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
- htim1.Init.Period = 1000 - 1; // PWM周期1000个计数
- htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
- htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
- HAL_TIM_PWM_Init(&htim1);
- // 配置PWM输出通道
- TIM_OC_InitTypeDef sConfigOC;
- sConfigOC.OCMode = TIM_OCMODE_PWM1;
- sConfigOC.Pulse = 500; // 初始占空比为50%
- sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
- sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
- HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);
- // 启动PWM
- HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
- }
- // 初始化GPIO
- void GPIO_Init(void) {
- __HAL_RCC_GPIOA_CLK_ENABLE();
- GPIO_InitTypeDef GPIO_InitStruct = {0};
- GPIO_InitStruct.Pin = GPIO_PIN_8; // TIM1_CH1引脚
- GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
- GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
- }
- // 修改占空比
- void Set_PWM_DutyCycle(uint16_t dutyCycle) {
- if (dutyCycle <= 1000) { // 确保占空比值合法
- __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, dutyCycle);
- }
- }
- int main(void) {
- HAL_Init();
- SystemClock_Config();
- GPIO_Init();
- TIM1_Init();
- while (1) {
- for (uint16_t duty = 0; duty <= 1000; duty += 10) {
- Set_PWM_DutyCycle(duty); // 增加占空比
- HAL_Delay(50);
- }
- for (uint16_t duty = 1000; duty > 0; duty -= 10) {
- Set_PWM_DutyCycle(duty); // 减小占空比
- HAL_Delay(50);
- }
- }
- }
代码解析- TIM1_Init函数:初始化TIM1定时器并配置PWM模式。
- Set_PWM_DutyCycle函数:通过修改TIM1的比较寄存器(CCR1),动态调整PWM占空比。
- 主循环:实现占空比在0%到100%之间的循环渐变,从而让LED的亮度逐渐变化。
测试与优化- 使用示波器测试PA8引脚的PWM输出信号,观察占空比是否随代码变化。
- 如果需要更高的分辨率,可以调整Prescaler和Period参数,使PWM周期更精确。
小结通过STM32G431和其高级定时器TIM1,我们可以轻松生成高精度的PWM信号,并灵活调整占空比。这种方法广泛适用于工业控制、电机驱动和信号调制等场景。
|