สารบัญ:

การควบคุมเซอร์โวมอเตอร์ด้วย STM32F4 ARM MCU: 4 ขั้นตอน
การควบคุมเซอร์โวมอเตอร์ด้วย STM32F4 ARM MCU: 4 ขั้นตอน

วีดีโอ: การควบคุมเซอร์โวมอเตอร์ด้วย STM32F4 ARM MCU: 4 ขั้นตอน

วีดีโอ: การควบคุมเซอร์โวมอเตอร์ด้วย STM32F4 ARM MCU: 4 ขั้นตอน
วีดีโอ: 50. How to connect a Hobby Servo to the ARM Microcontroller Part 2 - ARM STM32 Microcontroller 2024, พฤศจิกายน
Anonim
การควบคุมเซอร์โวมอเตอร์ด้วย STM32F4 ARM MCU
การควบคุมเซอร์โวมอเตอร์ด้วย STM32F4 ARM MCU
การควบคุมเซอร์โวมอเตอร์ด้วย STM32F4 ARM MCU
การควบคุมเซอร์โวมอเตอร์ด้วย STM32F4 ARM MCU

สวัสดีอีกครั้งเพื่อน:) ดังนั้นในโครงการนี้ เราจะควบคุมเซอร์โวมอเตอร์ด้วย STM32F4 ARM MCU ในกรณีของฉัน ฉันจะใช้บอร์ดค้นพบ แต่ถ้าคุณเข้าใจส่วนสำคัญของปัญหาแล้ว คุณสามารถใช้มันกับทุก MCU ได้ ดังนั้น. มาเริ่มกันเลย:)

ขั้นตอนที่ 1: ข้อกำหนดด้านฮาร์ดแวร์และซอฟต์แวร์

ในแง่ของฮาร์ดแวร์เราต้องการ:

  • MCU ซึ่งในกรณีของฉัน STM32f4 Discovery board
  • เซอร์โวมอเตอร์ทั่วไป เช่น SG90 หรืออื่นๆ

ในแง่ของซอฟต์แวร์เราจะต้อง:

  • STM32CubeMX
  • Keil uVision

หากคุณมีทั้งหมดนี้ข้ามไปยังขั้นตอนถัดไป:)

ขั้นตอนที่ 2: การกำหนดค่า STM32CubeMX

อย่างที่คุณทราบ สำหรับการควบคุมเซอร์โวมอเตอร์ เราจำเป็นต้องมีสัญญาณ PWM ข้อกำหนดในแง่ของสัญญาณ PWM เป็นดังนี้:

  • ระยะเวลา PWM ต้องเป็น 20 mS
  • ตรงเวลาต้องอยู่ระหว่าง 0.5 mS ถึง 2.5 mS เมื่อตรงเวลาคือ 0.5 mS เซอร์โวจะเปลี่ยนเป็น 0 องศา, 1.5 mS สำหรับ 90 องศา และ 2.5 mS สำหรับ 180 องศา

ดังนั้น เราจำเป็นต้องกำหนดค่า PWM และเพื่อจุดประสงค์นั้น เราจะใช้ Timer1

  • ขั้นแรก เลือก TIM1 จากส่วนตัวจับเวลา ขั้นตอนนี้
  • จากนั้นจากส่วนโหมด

    1. เลือกนาฬิกาภายใน ขั้นตอนนี้
    2. PWM Generation CH1 ขั้นตอนนี้
  • จากนั้นจากส่วนการกำหนดค่า

    1. ตั้งค่า Prescaler เป็น 160 ขั้นตอนนี้
    2. ตั้งระยะเวลาที่เคาน์เตอร์เป็น 2000 ขั้นตอนนี้
    3. ตั้งค่า Pulse เป็น 50 ขั้นตอนนี้
  • นอกจากนี้ จากการกำหนดค่านาฬิกา ตั้งค่านาฬิกาจับเวลา APB1 เป็น 16MHz ขั้นตอนนี้

ทีนี้มาพูดถึงขั้นตอนนี้กันสักหน่อย:

ความถี่ของนาฬิกาจับเวลา APB1 ของเราคือ 16MHz ดังนั้นจึงหมายความว่าต้องใช้ 16,000, 000 เห็บเพื่อรับ 1 วินาที อย่างไรก็ตาม เราตั้งค่าพรีสเกลเลอร์เป็น 160 ซึ่งหมายความว่า เราหารความถี่ด้วยจำนวนนั้น และลดจำนวนขีดลงเหลือ 100, 000 ครั้ง ดังนั้น เป็นเวลา 1 วินาที เราต้องการ 100, 000 เห็บ อย่างไรก็ตาม เราต้องการช่วงเวลา PWM 20mS ตามที่เราระบุไว้ก่อนหน้านี้ จากการคำนวณทางคณิตศาสตร์อย่างง่าย เราต้องการ 2,000 tick สำหรับ 20mS ดังนั้นโดยการตั้งค่า Counter Period เป็น 2000 เราจึงกำหนดระยะเวลาของสัญญาณ PWM ซึ่งก็คือ 20mS ตอนนี้เราจำเป็นต้องกำหนดจำนวนติ๊กเพื่อรับ On จาก 0.5mS ถึง 2.5mS เราสามารถหาสมการนี้ได้จากคณิตศาสตร์อย่างง่าย และได้ดังนี้

On_Time = (Tick_Number / 100) โปรดทราบว่านี่คือ on_time ที่เปลี่ยนมุมของเซอร์โวมอเตอร์ ดังนั้นภาพด้านล่างฉันสรุปขั้นตอนนี้ หากคุณมีคำถามใด ๆ เขียนในความคิดเห็นและฉันจะตอบโดยเร็วที่สุด

ภาพการคำนวณ

หลังจากสร้างโค้ดทั้งหมดเหล่านี้แล้ว:)

ขั้นตอนที่ 3: การเข้ารหัส Keil UVision

ก่อนอื่นมาพิจารณากันก่อนว่าเราต้องการทำอะไร? เราต้องการเขียนฟังก์ชันที่รับปริญญาและเขียนไปยังเซอร์โว แล้วเราจะทำอย่างนั้นได้อย่างไร? ดังที่เราได้กล่าวไว้ก่อนหน้านี้ เพื่อที่จะเปลี่ยนมุม เราต้องเปลี่ยนเวลาให้ตรงเวลา มุมของเราเปลี่ยนระหว่าง [0, 180] และจำนวนเห็บซึ่งกำหนดการเปลี่ยนแปลงของเวลาระหว่าง [50, 250] ดังนั้นเราจึงต้องการฟังก์ชันการทำแผนที่ที่จับคู่มุมที่กำหนดกับช่วงของจำนวนเห็บ ตัวอย่างเช่น สำหรับ 0 องศา 50 ขีด สำหรับ 180 องศา 250 ขีด และอื่นๆ… ลองเขียนฟังก์ชันการทำแผนที่ของเรา:

แผนที่ int (int st1, int fn1, int st2, int fn2, ค่า int){ return (1.0*(value-st1))/((fn1-st1)*1.0) * (fn2-st2)+st2; }

นี่คือฟังก์ชันการทำแผนที่ของเรา คุณสนใจว่ามันเกิดขึ้นได้อย่างไร? จากนั้นอ่านว่า ดังนั้นเราจึงใช้ช่วงและค่าที่เราต้องการทำแผนที่

ตอนนี้ มาเขียนฟังก์ชันที่ยอมรับมุมและแมปกับช่วงของขีด:

เป็นโมฆะ servo_write (มุม int) { htim1. Instance->CCR1 = แผนที่ (0, 180, 50, 250, มุม); }

อย่างที่คุณเห็น รหัสนี้ยอมรับมุมและจับคู่กับช่วงของจำนวนเห็บ จากนั้นจำนวนเห็บจะถูกกำหนดให้กับการลงทะเบียน CCR1 ซึ่งควบคุมเวลาตรงและมุม

อย่างไรก็ตาม เพื่อให้สิ่งเหล่านี้ทำงานได้ ขั้นแรกให้เริ่ม pwm ซึ่งสามารถทำได้โดยใช้โค้ดเพียงบรรทัดเดียว:

HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);

ดังนั้นเราจึงมีฟังก์ชันที่รับมุมและเขียนไปยังเซอร์โว มาทดสอบกันและเขียนฟังก์ชั่นการกวาดของเราซึ่งง่ายมาก:

เป็นโมฆะ servo_sweep (เป็นโมฆะ) { สำหรับ (int i = 0; i <= 180; i ++) { servo_write (i); HAL_Delay(10); } สำหรับ (int i = 180; i>= 0; i--) { servo_write (i); HAL_Delay(10); } }

มันก็แค่นับได้ถึง 180 แล้วลงไปที่ 0 แล้วเขียนค่าเหล่านี้ไปที่เซอร์โว:) แล้วมาดูผลลัพธ์กัน !

ขั้นตอนที่ 4: ผลลัพธ์:)

ดังนั้นนี่คือจุดสิ้นสุด หากคุณมีคำถามใด ๆ โปรดถาม ฉันจะมีความสุขเพื่อที่จะตอบพวกเขา ขอบคุณมากสำหรับการอ่านและหวังว่าจะได้พบคุณในโครงการต่อไป:)

แนะนำ: