当前位置: 首页 > news >正文

STM32 智能垃圾桶项目笔记(四):PWM 回顾与舵机(SG90)控制实现 - 实践

STM32 智能垃圾桶项目笔记(四):PWM 回顾与舵机(SG90)控制实现 - 实践

本系列笔记是笔者学习 B 站 up 主 “技术探索者” STM32 系列视频所作的记录,不理解的地方推荐观看视频~

目录

一、前言

大家好,我是 Hello_Embed。上一篇我们完成了蓝牙模块(JDY-31)的通信验证,实现了 “手机指令控制 LED”。本次笔记将聚焦智能垃圾桶的 “执行核心”—— 舵机 SG90,通过 PWM 信号控制舵机转动,为后续 “自动开盖” 功能铺垫。

舵机控制的核心是 特定频率的 PWM 信号,因此先快速回顾 PWM 的核心概念(具体细节可参考笔者之前的 “STM32HAL 快速入门” 系列笔记),再逐步讲解舵机的原理、配置与代码实现。

二、PWM 快速回顾与舵机(SG90)控制

2.1 PWM 核心概念快速回顾

PWM(脉宽调制)本质是 “高低电平周期性交替的矩形波”,核心参数为频率占空比,是控制舵机、电机、LED 亮度的基础。

2.1.1 核心参数定义
  • 占空比:高电平持续时间占整个周期的比例,公式为 占空比 = 高电平时间(t2) / 周期(t)× 100%

    例:5V 设备接入占空比 50% 的 PWM 信号,实际等效工作电压约为 5V × 50% = 2.5V,可通过调节占空比控制设备功率(如电机调速)。

  • PWM 频率:单位时间内周期的数量,公式为 PWM 频率 = 时钟频率 / 预分频值 / (ARR + 1)(ARR 为自动重载值)。

2.1.2 PWM 输出原理

定时器计数器(CNT)从 0 向上累加,与捕获比较寄存器(CCR)实时比较:

例:若 ARR=1000、CCR=800,则高电平占比 800/1000=80%(高电平有效)。

2.1.3 PWM 控制 LED 示例

以定时器 3 为例,配置预分频值 71、ARR=1000(频率 1kHz),代码启动 PWM 并设置占空比:

// 启动定时器3 通道1 PWM 输出
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
// 设置 CCR1=500,占空比 50%(1000 周期内高电平 500)
TIM3->CCR1 = 500;

逻辑分析仪抓取的 50% 占空比波形如下:
请添加图片描述

若将 CCR1 改为 200,占空比则变为 20%。

2.2 舵机(SG90)工作原理与控制逻辑

2.2.1 舵机特性与原理

SG90 是 180° 模拟舵机,核心由 “信号调制芯片、电机、减速齿轮、电位器” 组成,工作原理如下:

  1. 接收 PWM 控制信号后,内部基准电路生成 20ms 周期、1.5ms 高电平的基准信号;
  2. 控制信号的高电平时间与基准信号比较,产生电压差;
  3. 电压差驱动电机正转 / 反转,通过减速齿轮带动电位器旋转;
  4. 当电位器电压与控制信号电压一致时,电压差为 0,电机停止,舵机稳定在目标角度。

舵机使用说明图如下:
请添加图片描述

2.2.2 舵机控制核心:PWM 时基脉冲

SG90 需 20ms 周期(频率 50Hz) 的 PWM 信号,高电平时间决定转动角度,180° 舵机的 “高电平时间 - 角度” 对应关系如下:

高电平时间对应角度占空比(20ms 周期)
0.5ms2.5%
1.0ms45°5%
1.5ms90°7.5%
2.0ms135°10%
2.5ms180°12.5%

关键结论:只要生成 50Hz PWM 信号,并调节高电平时间在 0.5ms~2.5ms 之间,即可控制舵机转动到对应角度。

2.3 CubeMX 配置(定时器 2 生成 50Hz PWM)

由于定时器 1 无法配置通道 1 为 PWM 输出,选择 定时器 2 通道 1(PA0 引脚) 生成 50Hz PWM 信号,配置步骤如下:

2.3.1 参数计算(50Hz 频率)

已知系统时钟 72MHz,目标 PWM 频率 50Hz,根据频率公式推导参数:

  • 频率 = 72MHz / (预分频值 + 1) / (ARR + 1) = 50Hz
  • 选择预分频值 = 720 - 1(720 分频后,时钟频率 = 72MHz / 720 = 100kHz);
  • 则 ARR + 1 = 100kHz / 50Hz = 2000 → ARR = 2000 - 1 = 1999。
2.3.2 定时器 2 配置
  1. 进入 Timers → TIM2,模式选择 Internal Clock
  2. 参数配置:
    • Prescaler(预分频值):719(720 分频);
    • Counter Period(ARR):1999(2000 周期);
    • PWM 模式:通道 1 设为 PWM Generation CH1
    • 极性:默认 High(高电平有效,不影响舵机控制);
  3. 引脚:TIM2 通道 1 对应 PA0,无需手动修改;
  4. 配置截图如下:
    请添加图片描述
2.3.3 生成工程

确认基础配置(HCLK=72MHz、Debug=Serial Wire)不变,点击 Generate Code 生成工程,编译确保无错误。

2.4 舵机驱动代码实现(driver_SG90)

新建 driver_SG90.cdriver_SG90.h 驱动文件,封装 “舵机初始化” 和 “角度设置” 函数,核心是将 “角度” 线性映射为 “CCR 值”。

2.4.1 驱动头文件(driver_SG90.h)

定义角度对应的 CCR 值宏(0° 对应 50、180° 对应 250,推导:2000 周期内 0.5ms 占 50 个计数单位,2.5ms 占 250 个计数单位):

#ifndef __DRIVER_SG90_H
#define __DRIVER_SG90_H
#include "tim.h"  // 包含定时器句柄定义
/* 舵机角度-CCR 值映射宏(2000 周期,50Hz) */
#define SG90_0_DEGREE       50    // 0° 对应 CCR 值(0.5ms 高电平)
#define SG90_90_DEGREE      150   // 90° 对应 CCR 值(1.5ms 高电平)
#define SG90_180_DEGREE     250   // 180° 对应 CCR 值(2.5ms 高电平)
/* 函数声明 */
void SG90_Init(void);            // 舵机初始化(启动 PWM + 复位到 90°)
void SG90_SetAngle(uint8_t angle); // 设置舵机角度(0-180°)
#endif
2.4.2 驱动源文件(driver_SG90.c)

实现初始化和角度设置函数,包含角度范围限制和线性映射逻辑:

#include "driver_SG90.h"
// 声明定时器2 句柄(CubeMX 自动生成在 tim.c 中)
extern TIM_HandleTypeDef htim2;
/**
* @brief  舵机 SG90 初始化函数
* @param  无
* @retval 无
* @note   启动定时器2 通道1 PWM,初始化舵机到中间位置(90°)
*/
void SG90_Init(void)
{
// 启动 TIM2 通道1 PWM 输出(舵机信号线接 PA0)
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
// 初始化角度为 90°(避免舵机上电后无规律转动)
SG90_SetAngle(90);
}
/**
* @brief  设置舵机 SG90 目标角度
* @param  angle:目标角度(范围 0-180°,超过 180° 自动限制为 180°)
* @retval 无
* @note   线性映射:角度 → CCR 值(0°→50,180°→250)
*/
void SG90_SetAngle(uint8_t angle)
{
uint16_t ccr_value = 0;  // 存储计算后的 CCR 值
// 限制角度范围(避免超出舵机物理极限)
if (angle > 180)
{
angle = 180;
}
// 线性映射公式:ccr = 最小CCR + (最大CCR-最小CCR) × 角度/180
ccr_value = SG90_0_DEGREE + (uint16_t)((SG90_180_DEGREE - SG90_0_DEGREE) * angle / 180);
// 设置 TIM2 通道1 的 CCR 值(更新 PWM 高电平时间)
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, ccr_value);
}

2.5 主函数测试与预期现象

main.c 中调用舵机驱动函数,实现 “每秒转动 45°” 的测试逻辑:

#include "driver_SG90.h"
// 全局变量:舵机当前角度、计时变量
uint8_t sg90_current_angle = 0;
uint32_t sg90_tick = 0;
int main(void)
{
SG90_Init();
while (1)
{
// 500ms 定时(避免转动过快导致舵机卡顿)
if (HAL_GetTick() - sg90_tick > 500)
{
sg90_tick = HAL_GetTick();  // 更新计时基准
// 设置舵机到当前角度
SG90_SetAngle(sg90_current_angle);
// 角度累加 45°,超过 180° 重置为 0°
sg90_current_angle += 45;
if (sg90_current_angle >= 180)
{
sg90_current_angle = 0;
}
}
}
}

三、下一篇预告:语音合成模块(SYN6288)

完成舵机控制后,下一篇将聚焦智能垃圾桶的 “语音提示” 功能 —— 基于语音合成模块 SYN6288 实现 “开盖提示”“关盖提示” 等语音输出。内容包括:

  1. SYN6288 模块特性与接线(串口通信);
  2. CubeMX 串口配置(与模块匹配的波特率);
  3. 语音合成代码实现(发送文本指令,模块转换为语音);
  4. 功能整合:舵机开盖时触发 “欢迎使用” 语音,关盖时触发 “谢谢使用” 语音。

四、总结

本次笔记围绕 “PWM 控制舵机” 展开,核心收获包括:

  1. 回顾 PWM 频率与占空比的计算逻辑,理解 “特定频率 PWM 信号” 对舵机控制的重要性;
  2. 掌握 SG90 舵机的控制原理(20ms 周期 PWM + 高电平时间 - 角度映射);
  3. 封装通用舵机驱动函数,实现 “角度 - CCR 值” 线性映射,为后续 “自动开盖” 功能提供可复用代码。

至此,智能垃圾桶的 “感知(超声波)- 通信(蓝牙)- 执行(舵机)” 三大核心模块已全部覆盖,下一篇将通过语音模块丰富项目交互体验。请关注 Hello_Embed,后续笔记持续更新!

http://www.hskmm.com/?act=detail&tid=22954

相关文章:

  • 机器学习 深度学习发展简史(简化版)
  • 2025无锡黄金上门回收公司权威推荐榜:专业估价与诚信服务口碑之选
  • 详细介绍:告别“下次注意”,用这套结构化事故复盘方案就对了
  • 关于树状数组的一些东西
  • lazyVIM整体介绍、常用功能和插件
  • 【SpringAI】第四弹:深入解析 Rag 检索增强工作流程、最佳实践和调优 - 详解
  • 2025 年浮动密封厂家 TOP 企业品牌推荐排行榜,矿用,工程机械,矿山机械,煤矿井下,煤矿机械浮动密封推荐这十家公司!
  • P2141 [NOIP 2014 普及组] 珠心算测验
  • CF1081F Tricky Interactor
  • 2025.10 做题笔记
  • 2025年浮动油封厂家TOP企业品牌推荐排行榜,深度剖析技术创新与产品性能矿用,工程机械,矿山机械,煤矿井下,煤矿机械油封推荐这十家公司!
  • P1554 [USACO06DEC] 梦中的统计 Dream Counting B
  • 2025 年防火涂料厂家 TOP 企业品牌推荐红榜,膨胀型钢结构,非膨胀型钢结构,厚型钢结构,薄型钢结构,钢结构喷涂防火涂料推荐这十家优质公司!
  • 0.机器人的URDF文件修改
  • task1_1.c
  • 解码AVL树
  • LinuxWindows环境下Nacos3.1.0详细安装部署指南:从零到生产就绪
  • JAVA SE 基础语法 —— A / 初识 - 指南
  • 2025年掘进机厂家权威推荐榜:实力品牌与技术创新深度解析
  • 2025机械加工供货厂家权威口碑排行:实力与服务深度解析!
  • NOIP 集训日记 2.0
  • 2025舒适轮胎权威推荐榜:静音科技与驾乘体验口碑之选
  • 2025七水硫酸锌厂家权威推荐榜:优质供应与专业定制首选
  • 深圳网站建设公司权威推荐榜:专业定制与创新设计口碑之选
  • UV面光源实力厂家权威推荐:专业制造与品质保障口碑之选
  • 2025微弧氧化实力厂家推荐:专业表面处理技术深度解析
  • 2025减速机厂家 TOP 企业品牌推荐排行榜,谐波,行星,直角换向器,中空旋转平台,双曲面,RV,伺服,重载,步进减速机推荐这十家公司!
  • 75. 颜色分类
  • 2025压缩机厂家 TOP 企业品牌推荐排行榜,医药冷冻,医疗冷冻,食品冷冻,冰鲜冷冻,蔬菜水果冷冻,冷库,中高温制冷,活塞式半封闭制冷压缩机公司推荐!
  • 英语_阅读_Always-on world_待读