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

衡山派开发板RT-Thread实战:SG90舵机PWM驱动与角度控制详解

衡山派开发板RT-Thread实战:SG90舵机PWM驱动与角度控制详解

最近在做一个机械臂的小项目,用到了SG90舵机,正好手头有衡山派(HSPI)开发板,就想着把舵机驱动移植到RT-Thread系统上。整个过程下来,发现从原理理解到代码实现,再到实际调试,有不少需要注意的细节。今天我就把这次实战的经验整理出来,手把手教你怎么在衡山派开发板上用PWM精准控制SG90舵机的角度。

这篇文章适合正在学习嵌入式开发,特别是对RISC-V、RT-Thread和舵机控制感兴趣的朋友。我会从SG90舵机的基本原理讲起,一步步带你完成驱动代码的移植、配置和验证,最后还会分析核心代码,让你不仅知道怎么做,更明白为什么这么做。

1. 认识我们的“演员”:SG90舵机

在开始写代码之前,咱们得先了解要控制的对象。SG90是一种微型舵机,在机器人、航模里非常常见。

核心参数一览:

参数规格说明
驱动电压3V ~ 7.2V推荐使用5V供电,电压太低扭矩不足,太高可能烧坏。
工作扭矩1.6 kg/cm在1厘米的力臂上能产生1.6公斤的力,驱动小负载没问题。
控制信号PWM(脉冲宽度调制)这是关键,舵机角度由PWM信号的脉冲宽度决定。
转动角度180度这是我们今天要控制的范围,从0度到180度。
信号周期20 ms控制信号需要每20ms发送一次,也就是频率为50Hz。

注意:市面上还有一种360度连续旋转的舵机,它不能控制角度,只能控制旋转速度和方向。咱们今天用的是180度的版本,别买错了。

PWM控制原理(小白版):你可以把舵机想象成一个听话的“小弟”。你不需要告诉它具体转多少度,而是通过发送一种特殊的“暗号”(PWM波)来指挥它。这个暗号就是每20ms发送一个高电平脉冲,舵机会根据这个高电平持续的时间长短,来判断应该转到哪个位置。

  • 0.5ms脉冲-> 对应0度位置
  • 1.5ms脉冲-> 对应90度中间位置
  • 2.5ms脉冲-> 对应180度位置

所以,控制角度的核心任务,就是让衡山派开发板产生一个周期20ms(50Hz),且高电平宽度在0.5ms到2.5ms之间可调的PWM信号。

2. 工程搭建与驱动移植

拿到舵机后,第一步不是急着接线写代码,而是把开发环境准备好,把官方提供的驱动代码“搬”到我们的工程里。

2.1 获取资料与驱动代码

原始资料里提供了驱动代码的压缩包,你需要从资料下载中心找到它。通常它会被放在类似\luban-lite\application\rt-thread\helloworld\user-bsp的文件夹下。如果你没看到user-bsp这个文件夹,说明你还没完成模块移植的前置配置,需要先去完成必要的环境搭建操作。

2.2 修改Kconfig文件

驱动代码放好后,需要修改工程的Kconfig文件,这样后续的配置菜单里才会出现SG90舵机的选项。

  1. 用VSCode打开你的工程,找到这个文件:application\rt-thread\helloworld\Kconfig
  2. 在文件末尾的#endif语句之前,添加下面这行代码:
    # SG90舵机 source "application/rt-thread/helloworld/user-bsp/sg90-steering-engine/Kconfig"
    这行代码的作用是告诉构建系统:“嘿,我这里还有一个SG90舵机的配置目录,你把它也包含进来。”

2.3 使用menuconfig配置工程

接下来,我们要在图形化配置界面里启用SG90舵机模块。

  1. 双击工程根目录下的win_env.bat脚本,打开RT-Thread的Env配置工具。
  2. 在Env命令行中,输入scons --list-def查看所有可用的默认配置。找到名为d13x_JLC_rt-thread_helloworld的配置(这是衡山派开发板的默认配置),记住它的编号(比如是7)。
  3. 应用这个配置:
    scons --apply-def=7
    或者直接用配置名:
    scons --apply-def=d13x_JLC_rt-thread_helloworld_defconfig
  4. 输入scons --menuconfig进入图形化配置菜单。
  5. 在菜单中,用方向键找到Porting code using the LCKFB module选项,按Y键选中它(前面会出现[*])。
  6. 按回车键进入这个子菜单。
  7. 在里面找到Using SG90 steering engine选项,同样按Y键选中它。
  8. 最后,用左右方向键切换到<Save>,按回车保存配置,然后退出菜单。

2.4 编译与烧录

配置保存后,就可以编译了。在Env命令行中输入:

scons

如果你的电脑CPU核心多,想加快编译速度,可以用-j参数,比如scons -j16。编译成功后,在\luban-lite\output\d13x_JLC_rt-thread_helloworld\images目录下会生成一个d13x_JLC_v1.0.0.img的镜像文件。

最后,使用烧录工具将这个镜像文件烧录到衡山派开发板中,具体烧录方法可以参考官方文档。

3. 核心代码解析与原理

烧录完成,硬件准备就绪,现在我们来深入看看驱动代码到底是怎么工作的。理解了代码,你才能举一反三。

3.1 头文件与宏定义 (bsp_sg90.h)

头文件很简单,就是声明了三个我们要用到的函数:

int SG90_Init(void); // 初始化舵机 int SG90_DeInit(void); // 反初始化(关闭) int Set_Servo_Angle(uint32_t Angle); // 设置角度,范围0-180

3.2 初始化函数 (SG90_Init)

这是整个驱动的起点,在bsp_sg90.c文件中。我把它拆开一步步讲:

第一步:降低PWM时钟频率

ret = hal_pwm_set_tb(SG90_PWMA_CHANNEL, 1000000);

这行代码非常关键!衡山派开发板PWM的默认时钟频率是24MHz。在这个频率下,计数器计满一个20ms周期所需要的数值会非常大,可能超出寄存器能设置的范围,导致无法产生我们需要的长周期信号。所以这里先把PWM1通道的时钟频率降低到1MHz,这样后续设置周期值就游刃有余了。这是我调试时遇到的第一个坑,原文也特别强调了。

第二步:查找PWM设备

pwm_dev = (struct rt_device_pwm *)rt_device_find(SG90_PWM_NAME);

RT-Thread中,外设都抽象为“设备”。这行代码就是根据设备名(这里是”pwm”)在系统中找到PWM设备,拿到它的操作句柄。

第三步:设置PWM周期和初始脉宽

ret = rt_pwm_set(pwm_dev, SG90_PWMA_CHANNEL, SG90_PERIOD, 0);
  • pwm_dev: 刚才找到的设备句柄。
  • SG90_PWMA_CHANNEL: 使用的PWM通道号,这里是1。
  • SG90_PERIOD: 周期值,定义为20000000纳秒(ns),也就是20毫秒(ms)。
  • 0: 初始脉冲宽度(高电平时间),设为0意味着舵机初始状态没有脉冲,是安全的。

第四步:使能PWM输出

ret = rt_pwm_enable(pwm_dev, SG90_PWMA_CHANNEL);

最后这步是“打开开关”,让PWM信号实际从对应的硬件引脚输出。

3.3 角度控制函数 (Set_Servo_Angle)

这是最核心的函数,实现了角度到脉冲宽度的映射。

int Set_Servo_Angle(uint32_t Angle) { float pulse; // 1. 角度范围检查 if (Angle > 180) { LOG_E("Angle out of range !!"); return -RT_ERROR; } // 2. 角度到脉宽的换算(核心算法) pulse = 500000.0f + ((2000000.0f / 180.0f) * (float)Angle); // 3. 设置新的脉宽 if (RT_EOK != rt_pwm_set(pwm_dev, SG90_PWMA_CHANNEL, SG90_PERIOD, (uint32_t)pulse)) { LOG_E("rt_pwm_set failed !!"); return -RT_ERROR; } return RT_EOK; }

重点解释一下换算公式:

  • 500000.0f: 这是0度角对应的脉冲宽度,单位是纳秒(ns),即0.5ms。
  • 2000000.0f / 180.0f: 这是“每度对应的脉冲宽度增量”。总脉冲变化范围是2.5ms - 0.5ms = 2.0ms,即2,000,000 ns。把它平分成180份,得到每度大约11111 ns。
  • (2000000.0f / 180.0f) * (float)Angle: 计算当前角度相对于0度需要增加的脉冲宽度。
  • 两者相加,就得到了目标角度对应的精确脉冲宽度。

例如,设置90度时:pulse = 500000 + (11111 * 90) ≈ 1,500,000 ns,正好是1.5ms。

3.4 测试线程 (test_sg90_steering_engine.c)

官方提供了一个测试线程,它创建了一个任务,让舵机在0到180度之间自动来回摆动,非常适合验证驱动是否正常工作。

线程入口函数逻辑:

  1. 初始化舵机 (SG90_Init)。
  2. 依次将舵机转到45度、90度、0度,每个状态保持1秒,做一个“开机自检”动作。
  3. 进入主循环,让角度变量Angle从0递增到180,再递减回0,循环往复。
  4. 每次循环调用Set_Servo_Angle(Angle)设置角度,并延时100ms。这个延时决定了舵机运动的速度,延时越小,运动越快。

如何使用这个测试:代码最后用MSH_CMD_EXPORT将函数导出为了Finsh/MSH命令行命令。这意味着当程序运行起来,并通过串口连接到开发板后,你只需要在终端里输入:

test_sg90_module

舵机就会开始自动来回转动。想停止它,就输入:

test_exit_sg90_module

4. 硬件连接与最终验证

代码烧录进去之后,最后一步就是把舵机接上开发板。

接线很简单:

  1. 舵机红线(电源)-> 接开发板的5V引脚。
  2. 舵机棕线(地)-> 接开发板的GND引脚。
  3. 舵机橙线(信号)-> 接开发板指定的PWM输出引脚(具体是哪个引脚,需要根据你使用的PWM通道和衡山派的引脚复用表来确定,请参考开发板原理图)。

提示:务必确保共地!即开发板和舵机的地线(GND)要连接在一起,这是信号正常工作的基础。

连接好硬件和串口调试器后,给开发板上电。打开串口终端(如Putty、MobaXterm等),设置波特率为115200。

在终端中,输入test_sg90_module命令并回车。如果一切顺利,你应该能立刻听到舵机转动的声音,并看到它开始周期性地在0到180度之间摆动。

看到舵机乖乖听你指挥转动起来,是不是很有成就感?这个过程涵盖了从原理理解、环境配置、代码移植、编译烧录到硬件验证的完整嵌入式开发流程。你可以基于这个驱动,去开发更复杂的项目,比如多舵机协同的机械臂、云台摄像头等等。遇到问题别怕,多看看串口日志,理解每个函数返回值的含义,调试的过程就是进步最快的时候。

http://www.jsqmd.com/news/488709/

相关文章:

  • UML时序图实战:用微信支付案例手把手教你6大核心元素
  • ESP32+WS2812B彩灯实战:从手动IO控制到FastLED库的华丽转身
  • LiuJuan Z-Image Generator效果展示:显存优化前后连续生成100张图稳定性记录
  • 数字IC验证工程师的一天:从测试点分解到UVM环境搭建全流程揭秘
  • 从李雅普诺夫函数到双曲正切:深入理解滑模控制的稳定性设计
  • 从零定制:基于STM32F401CCU开发板的INAV飞控移植实战
  • Python+Selenium实战:教你用自动化脚本搞定12306远程抢票(附邮箱交互技巧)
  • [无缝衔接3D工作流] 设计师与工程师的Rhino到Blender无损数据迁移方案
  • RK3576开发板ROS部署避坑指南:解决Ubuntu下5个最常见编译错误
  • Pi0开源机器人模型安全审计:代码漏洞扫描+第三方依赖风险评估
  • 插件管理的混沌困境:如何用ComfyUI-Manager构建AI创作的秩序引擎
  • apiSQL+GoView:从零到一构建高效数据大屏的实战指南
  • 软件工程学习必备:如何高效利用课后习题提升理解(附第四版答案)
  • Oracle|从进程句柄到数据重生:DBF文件误删的在线恢复实战
  • MogFace模型Claude Code协作编程:利用AI助手完成模型调用代码重构与优化
  • STM32F103RCT6基于CubeMX与XCP协议:从零构建openBLT BootLoader的工程实践
  • 避开这5个坑!用LoRA+SFT微调LLaMA-2的实战避坑指南
  • RimSort:开源环世界MOD管理效率提升解决方案
  • NBTExplorer:Minecraft数据编辑与修复的专业解决方案
  • 玩客云OneCloud刷机后必装!Docker安装与镜像源优化全攻略(附SSH连接技巧)
  • WeKnora产品文档系统:基于Vue3的前端界面开发指南
  • OBS多平台直播无缝整合:效能倍增的多平台推流技术解决方案
  • 立创开源DIY:基于STM32的多功能示波器音乐视频手表(ZHAO-Watch 2设)
  • 香橙派5分钟搞定Klipper固件刷写(2023最新避坑指南)
  • Phi-3-vision-128k-instruct开源生态:对接LangChain、LlamaIndex插件实践
  • Qwen2-VL-2B-Instruct在运维自动化中的应用:智能日志分析
  • TikTok双旋验证码实战:从算法原理到高性能API服务的工程化落地
  • 从BIOS到SSD:一文看懂ROM、RAM和FLASH在计算机系统中的实际应用
  • 通义千问2.5-0.5B实战案例:基于vLLM的高吞吐推理部署教程
  • Qwen3-14b_int4_awq镜像免配置:开箱即用的AWQ量化大模型Web服务体验