[STM32F1] 使用STM32F103实现PWM输出控制:详解与实践

[复制链接]
4870|9
 楼主| Clyde011 发表于 2025-1-13 07:43 | 显示全部楼层 |阅读模式
1. 项目背景PWM(Pulse Width Modulation,脉宽调制)是一种通过调节信号的宽度(占空比)来实现控制的技术,在嵌入式系统中得到了广泛应用。无论是在电机控制、LED亮度调节,还是在音频信号生成中,PWM都扮演着重要角色。
STM32F103是一款基于ARM Cortex-M3核心的微控制器,具有丰富的外设和强大的计算能力,能够轻松实现PWM信号的生成。今天,我们将介绍如何在STM32F103上使用PWM输出控制一个LED的亮度。
2. 开发环境搭建要完成本项目,我们需要准备以下工具和设备:
  • 开发板:STM32F103C8T6开发板(俗称蓝色小开发板)。
  • 开发工具
    • STM32CubeMX:用于外设配置和代码生成。
    • STM32CubeIDE:编写和编译代码。
  • 硬件
    • LED灯和适当的电阻(建议220Ω)。
    • 杜邦线(用于连接开发板和LED)。
3. 配置PWM外设我们将在STM32F103上使用定时器(Timer)来生成PWM信号。定时器通过不同的占空比来控制PWM输出,从而调节LED的亮度。
步骤:
  • 打开STM32CubeMX并选择STM32F103C8T6芯片。
  • 进入Peripherals菜单,选择TIM3(作为PWM输出)。
  • 配置TIM3为PWM模式,设置预分频器和自动重装载寄存器(ARR)来确定PWM的周期。
  • 配置PA6为TIM3的输出引脚。
  • 生成代码,选择STM32CubeIDE作为开发环境。
4. 代码实现生成代码后,我们可以在STM32CubeIDE中编写应用程序代码。以下是一个完整的代码示例,用于控制LED的亮度。
  1. #include "main.h"

  2. // 定义PWM占空比
  3. uint32_t pwmDutyCycle = 0;

  4. // 初始化定时器
  5. void Timer_Init(void)
  6. {
  7.     // TIM3定时器配置
  8.     TIM_HandleTypeDef htim3;
  9.     TIM_OC_InitTypeDef sConfigOC;

  10.     htim3.Instance = TIM3;
  11.     htim3.Init.Prescaler = 72 - 1;  // 1 MHz的定时器时钟
  12.     htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  13.     htim3.Init.Period = 1000 - 1;   // PWM周期为1ms
  14.     htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  15.     htim3.Init.RepetitionCounter = 0;

  16.     if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
  17.     {
  18.         Error_Handler();
  19.     }

  20.     // 配置PWM通道1(PA6)
  21.     sConfigOC.OCMode = TIM_OCMODE_PWM1;
  22.     sConfigOC.Pulse = pwmDutyCycle;  // 初始化占空比为0
  23.     sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  24.     sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

  25.     if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  26.     {
  27.         Error_Handler();
  28.     }

  29.     // 启动PWM
  30.     if (HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1) != HAL_OK)
  31.     {
  32.         Error_Handler();
  33.     }
  34. }

  35. // 调节PWM占空比
  36. void Set_PWM_DutyCycle(uint32_t dutyCycle)
  37. {
  38.     if (dutyCycle <= 1000)
  39.     {
  40.         pwmDutyCycle = dutyCycle;
  41.         __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, pwmDutyCycle);
  42.     }
  43. }

  44. // 主程序
  45. int main(void)
  46. {
  47.     // HAL库初始化
  48.     HAL_Init();

  49.     // 系统时钟配置
  50.     SystemClock_Config();

  51.     // 初始化GPIO、定时器
  52.     Timer_Init();

  53.     // 循环调节PWM占空比来改变LED亮度
  54.     while (1)
  55.     {
  56.         for (uint32_t i = 0; i <= 1000; i += 10)
  57.         {
  58.             Set_PWM_DutyCycle(i);
  59.             HAL_Delay(50);  // 延迟50ms
  60.         }

  61.         for (uint32_t i = 1000; i > 0; i -= 10)
  62.         {
  63.             Set_PWM_DutyCycle(i);
  64.             HAL_Delay(50);  // 延迟50ms
  65.         }
  66.     }
  67. }
5. 代码解释
  • Timer_Init:配置定时器TIM3以生成PWM信号。通过设置预分频器和ARR寄存器,我们决定PWM信号的周期为1ms。
  • Set_PWM_DutyCycle:根据传入的占空比调整TIM3的比较寄存器,进而改变PWM的占空比。
  • 主程序:在主循环中,我们通过改变占空比使LED逐渐亮起和变暗,从而实现LED的亮度渐变效果。
6. 调试与测试
  • 将代码编译并烧录到STM32F103开发板中。
  • 将PA6引脚连接到LED的正极,并连接适当的限流电阻(如220Ω)。
  • 通过调试,我们可以看到LED的亮度逐渐从暗到亮,再从亮到暗,形成渐亮渐暗的效果。
7. 常见问题与解决方案
  • 问题:LED无法正常亮起或亮度不变。解决方案:检查定时器和PWM配置,确保PA6引脚已正确配置为定时器的输出引脚。
  • 问题:LED亮度变化不平滑。解决方案:检查PWM周期和占空比设置,确保周期足够长,且占空比调节的步进足够小,以实现平滑过渡。
  • 问题:LED闪烁不稳定。解决方案:检查定时器的初始化配置,确保定时器时钟和PWM频率设置正确。

8. 总结在STM32F103微控制器上使用PWM进行LED亮度控制是一个简单而常见的应用。通过配置定时器生成PWM信号并调节占空比,我们可以灵活地控制LED的亮度。此技术不仅在LED调光中有应用,还可以扩展到电机控制、音频调节等多个领域。

公羊子丹 发表于 2025-1-13 07:43 | 显示全部楼层
这篇帖子太实用了!终于能用STM32控制LED亮度了!从来没做过PWM,感觉好像学会了一个新技能。
周半梅 发表于 2025-1-13 07:44 | 显示全部楼层
楼主讲解得很清晰,特别是代码里的注释,刚开始接触嵌入式的我很受用。
帛灿灿 发表于 2025-1-13 07:44 | 显示全部楼层
直接用这个代码控制LED的亮度,效果挺好的。就是调试时需要多注意定时器的参数。
童雨竹 发表于 2025-1-13 07:44 | 显示全部楼层
这个PWM的应用不止可以调节LED亮度吧?我试了一下,控制舵机也可以。
万图 发表于 2025-1-13 07:44 | 显示全部楼层
看了这篇帖子,我学会了如何在STM32上用定时器做PWM输出,真是大开眼界!
Wordsworth 发表于 2025-1-13 07:45 | 显示全部楼层
刚开始用STM32做PWM,感觉这个教程帮我节省了不少时间,感谢楼主!
Bblythe 发表于 2025-1-13 07:45 | 显示全部楼层
学习到了!STM32F103的PWM调节真是好用,LED亮度调节得特别顺畅。
Pulitzer 发表于 2025-1-13 07:45 | 显示全部楼层
控制LED亮度的效果非常好,PWM输出的精度也高,调节很细腻,支持楼主!
Uriah 发表于 2025-1-13 07:46 | 显示全部楼层
这个教程对我来说很有帮助。之前做PWM输出时总是遇到问题,看看这篇教程后解决了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

171

主题

6048

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部