首页 物联网

STM32 智能垃圾桶进阶:PWM 舵机控制 SG90 实战

分类:物联网
字数: (1682)
阅读: (5144)
内容摘要:STM32 智能垃圾桶进阶:PWM 舵机控制 SG90 实战,

STM32 智能垃圾桶项目中,我们需要控制垃圾桶盖的自动开合,而舵机(SG90)是一个常用的选择。本文将深入探讨如何使用 STM32 的 PWM 功能来精确控制 SG90 舵机,并分享一些实战经验。

问题场景:垃圾桶盖的精确控制

我们需要实现:

  1. 当检测到垃圾桶前方有人靠近时,垃圾桶盖自动打开。
  2. 在一定时间后,垃圾桶盖自动关闭。
  3. 能够通过程序精确控制垃圾桶盖的开合角度。

这需要我们精确控制舵机的转动角度,而 PWM 正是实现这一目标的关键。

STM32 智能垃圾桶进阶:PWM 舵机控制 SG90 实战

PWM 原理回顾

PWM(Pulse Width Modulation,脉冲宽度调制)是一种通过改变脉冲的占空比来调节信号有效值的技术。在 STM32 中,我们可以通过配置定时器(Timer)来生成 PWM 信号。PWM 的几个关键参数包括:

  • 频率(Frequency):PWM 信号的周期,决定了舵机控制的刷新率。一般来说,舵机的工作频率在 50Hz 左右。
  • 占空比(Duty Cycle):高电平时间在一个周期中所占的比例,决定了舵机的转动角度。对于 SG90 舵机,通常使用 0.5ms-2.5ms 的高电平脉宽来控制 0-180 度的转动。
  • 分辨率(Resolution):占空比变化的最小单位,分辨率越高,舵机控制精度越高。

STM32 的定时器资源非常丰富,例如 TIM1、TIM2 等,我们可以选择合适的定时器来生成 PWM 信号。在使用定时器时,我们需要配置以下参数:

STM32 智能垃圾桶进阶:PWM 舵机控制 SG90 实战
  • 时钟源(Clock Source):选择定时器的时钟源,通常选择内部时钟。
  • 预分频器(Prescaler):对时钟进行分频,降低定时器的计数频率。
  • 自动重载值(Auto-Reload Value,ARR):定时器计数到 ARR 值时,会重新开始计数。
  • 比较值(Compare Value,CCR):当定时器的计数值与 CCR 值相等时,输出 PWM 信号发生翻转。

SG90 舵机控制原理

SG90 舵机的工作原理是:通过控制输入 PWM 信号的高电平脉宽来控制舵机的转动角度。一般来说,SG90 的控制信号周期为 20ms(50Hz),高电平脉宽与转动角度的关系如下:

  • 0.5ms:0 度
  • 1.5ms:90 度
  • 2.5ms:180 度

因此,我们需要根据所需的转动角度,计算出对应的 PWM 占空比,然后配置 STM32 的定时器,生成相应的 PWM 信号。

STM32 智能垃圾桶进阶:PWM 舵机控制 SG90 实战

代码实现:STM32 控制 SG90

以下是一个使用 STM32CubeIDE 生成的工程控制 SG90 舵机的示例代码:

// 初始化 TIM1 的 PWM 输出
void PWM_Init(void) {
  TIM_HandleTypeDef htim1;
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};

  htim1.Instance = TIM1;
  htim1.Init.Prescaler = 71; // 72MHz / 72 = 1MHz
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP; 
  htim1.Init.Period = 19999;  // 1MHz / 20000 = 50Hz (20ms)
  htim1.Init.ClockDivision = 0; 
  htim1.Init.RepetitionCounter = 0;
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  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 = 1500; // 初始角度,对应 1.5ms
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; 
  sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH; 
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; 
  sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; 
  sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET; 
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) {
    Error_Handler();
  }

  HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); // 启动 PWM
}

// 设置舵机角度
void SetServoAngle(float angle) {
  // 计算对应的 PWM 脉宽
  float pulse_width = 0.5 + (angle / 180.0) * 2.0; // 0.5ms - 2.5ms
  uint32_t pulse = (uint32_t)(pulse_width * 1000); // us

  // 设置 CCR 值
  TIM1->CCR1 = pulse;  // 假设使用 TIM1_CH1
}

代码解释:

STM32 智能垃圾桶进阶:PWM 舵机控制 SG90 实战
  1. PWM_Init() 函数用于初始化 TIM1,配置 PWM 频率为 50Hz,并设置初始角度对应的脉宽(1.5ms)。
  2. SetServoAngle() 函数用于设置舵机的转动角度,根据给定的角度计算出对应的 PWM 脉宽,然后设置 TIM1 的 CCR1 寄存器,改变 PWM 的占空比。

实战避坑经验总结

  1. 电源问题:SG90 舵机需要独立的 5V 电源供电,不能直接从 STM32 的 3.3V 引脚取电,否则可能导致舵机工作不稳定甚至无法工作。
  2. GND 共地:务必将 STM32 和舵机的 GND 引脚连接在一起,否则可能导致信号传输异常。
  3. 抖动问题:如果舵机出现抖动,可以尝试调整 PWM 频率和分辨率,或者增加滤波电路。
  4. 角度校准:由于 SG90 舵机的实际角度与 PWM 脉宽之间可能存在偏差,需要进行角度校准,以确保舵机能够精确转动到目标角度。
  5. 注意舵机寿命:频繁地快速转动舵机可能会缩短其寿命,尽量避免不必要的转动。
  6. CubeMX 配置要点:在使用 STM32CubeMX 配置时钟树时,需要确保 TIMx 的时钟频率是正确的,这直接影响 PWM 的频率和精度。可以使用调试器查看时钟频率,或者使用 HAL 库提供的时钟查询函数。

扩展:配合红外传感器实现智能控制

可以将代码与红外传感器或其他传感器结合,实现更智能的垃圾桶控制。例如,使用红外传感器检测到有人靠近时,自动调用 SetServoAngle() 函数打开垃圾桶盖,并在一段时间后自动关闭。

通过本文,我们详细了解了如何使用 STM32 的 PWM 功能来控制 SG90 舵机,并分享了一些实战经验。希望这些内容能够帮助你更好地完成你的 STM32 智能垃圾桶项目

STM32 智能垃圾桶进阶:PWM 舵机控制 SG90 实战

转载请注明出处: 键盘上的咸鱼

本文的链接地址: http://m.acea2.store/blog/112488.SHTML

本文最后 发布于2026-04-05 09:44:12,已经过了22天没有更新,若内容或图片 失效,请留言反馈

()
您可能对以下文章感兴趣
评论
  • 键盘侠本侠 5 天前
    电源问题确实是个坑,之前直接从开发板取电,舵机抖得厉害,后来接了独立电源就好了。
  • 向日葵的微笑 12 小时前
    请问博主,如果我想用OLED屏幕显示当前舵机的角度,应该怎么实现呢?
  • 山西刀削面 5 天前
    角度校准很重要,不同批次的SG90舵机可能存在差异,不校准的话角度误差很大。
  • 咖啡不加糖 1 天前
    电源问题确实是个坑,之前直接从开发板取电,舵机抖得厉害,后来接了独立电源就好了。