簡介
這是一個適合初學者的專案,透過 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 按鈕。