>應用案例>
/N32G031_SERVO_SMOOTH

讓伺服馬達平順掃動

N32G031_SERVO_SMOOTH

簡介

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