简介
这是一个面向初学者的项目,通过 N32G031 微控制器讲解舵机控制,重点实现连贯、无顿挫的平滑扫描(Smooth Sweep)。它非常适合作为机器人技术和 for 循环应用的基础学习项目,并已针对 UnityMbed 跨平台工作流完成优化。
目标 MCUNations N32G031 (Cortex-M0)
有效信号引脚PA1 (软件模拟 PWM)
运动模式平滑扫描 (0°–90°)
演示视频
接线与硬件连接
| 设备 | 线材/器件引脚 | N32G031 开发板引脚 | 备注与安全提示 |
|---|---|---|---|
| 舵机(例如 SG90) | 棕色/黑色 | GND | 系统共地 |
| 舵机(例如 SG90) | 红色(VCC) | 5V | 电机主电源 |
| 舵机(例如 SG90) | 橙色/黄色 | PA1 | 控制信号引脚(软件模拟 PWM) |
运行方式与执行逻辑
接通电源后,舵机臂将持续按照以下四个阶段平滑扫描:
阶段 1:0° ➔ 45°
从 0° 平滑扫描至 45°
从 0° 平滑扫描至 45°(PULSE_0_DEG ➔ PULSE_45_DEG),然后保持位置。
阶段 2:45° ➔ 90°
从 45° 平滑扫描至 90°
从 45° 平滑扫描至 90°(PULSE_45_DEG ➔ PULSE_90_DEG),然后保持位置。
阶段 3:90° ➔ 45°
从 90° 平滑返回至 45°
从 90° 平滑返回至 45°(PULSE_90_DEG ➔ PULSE_45_DEG),然后保持位置。
阶段 4:45° ➔ 0°
从 45° 平滑返回至 0°
从 45° 平滑返回至 0°(PULSE_45_DEG ➔ PULSE_0_DEG),保持位置后重新开始循环。
main.c
// UnityMbed — 舵机平滑扫描控制 @ N32G031
#include "n32g031.h"
#include "n32g031_gpio.h"
#include "n32g031_rcc.h"
/* ====================================================================
* [硬件校准区]
* 各校准角度位置对应的脉宽参数
* ==================================================================== */
#define PULSE_0_DEG 2250 // 0 度(最左侧)
#define PULSE_45_DEG 3325 // 45 度(左侧中间位置)
#define PULSE_90_DEG 4400 // 90 度(垂直/中心位置)
/* 简单的软件延时循环 */
void Delay_Loop(volatile uint32_t count) {
while(count--) { __NOP(); }
}
/* ====================================================================
* 子程序:发送单步脉冲(软件模拟 PWM)
* ==================================================================== */
void Servo_Step(uint32_t pulse_width) {
GPIO_SetBits(GPIOA, GPIO_PIN_1);
Delay_Loop(pulse_width);
GPIO_ResetBits(GPIOA, GPIO_PIN_1);
Delay_Loop(100000);
}
/* ====================================================================
* 核心运动程序:在脉冲角度之间平滑过渡
* ==================================================================== */
void Smooth_Move(uint32_t start_pulse, uint32_t end_pulse) {
// 如果目标角度更大,则平滑增加脉宽
if (start_pulse < end_pulse) {
for (uint32_t p = start_pulse; p <= end_pulse; p += 20) {
Servo_Step(p);
}
}
// 如果目标角度更小,则平滑减小脉宽
else {
for (uint32_t p = start_pulse; p >= end_pulse; p -= 20) {
Servo_Step(p);
}
}
}
/* ====================================================================
* 主程序入口:周期性平滑扫描循环
* ==================================================================== */
int main(void) {
/* 初始化 GPIOA 外设时钟,并将引脚 1 配置为推挽输出 */
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);
GPIO_InitType GPIO_InitStructure;
GPIO_InitStruct(&GPIO_InitStructure);
GPIO_InitStructure.Pin = GPIO_PIN_1;
GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
while(1) {
/* 1. 将舵机臂从 0 度平滑扫描至 45 度 */
Smooth_Move(PULSE_0_DEG, PULSE_45_DEG);
Delay_Loop(5000000); // 保持位置
/* 2. 将舵机臂从 45 度平滑扫描至 90 度 */
Smooth_Move(PULSE_45_DEG, PULSE_90_DEG);
Delay_Loop(5000000);
/* 3. 将舵机臂从 90 度平滑返回至 45 度 */
Smooth_Move(PULSE_90_DEG, PULSE_45_DEG);
Delay_Loop(5000000);
/* 4. 将舵机臂从 45 度平滑返回至 0 度并重新开始循环 */
Smooth_Move(PULSE_45_DEG, PULSE_0_DEG);
Delay_Loop(5000000);
}
}学习与 AI 扩展思路
学习者可以使用 UnityMbed IDE 内置的 AI Assistant 探索、调试和修改本项目:
1
平滑运动
理解让机器人瞬间“跳转”到目标位置与使用 Smooth_Move 函数逐步移动之间的差异,从而创建自然、流畅的动画。
2
硬件校准
通过调整真实硬件参数(脉宽),亲手完成 0°、90° 和 180° 角度的精确校准。
3
for 循环应用
观察数值递增或递减时机械臂如何逐步移动,直观理解 for 循环的运行方式。
4
调整扫描步长
尝试修改 Smooth_Move 函数中的步进增量(p += 20、p += 50 或 p += 5),观察速度变化和慢动作效果。
构建与烧录指南
1
打开项目: 直接在 IDE 中打开此项目文件夹。
2
Build & Flash: 只需点击界面工具栏上的 Build 和 Flash 按钮。