STM32F4 ARM MCU ilə Servo Motor İdarəetmə: 4 addım
STM32F4 ARM MCU ilə Servo Motor İdarəetmə: 4 addım
Anonim
STM32F4 ARM MCU ilə Servo Motor İdarəetmə
STM32F4 ARM MCU ilə Servo Motor İdarəetmə
STM32F4 ARM MCU ilə Servo Motor İdarəetmə
STM32F4 ARM MCU ilə Servo Motor İdarəetmə

Yenə salam dostlar:) Beləliklə, bu layihədə STM32F4 ARM MCU ilə bir servo mühərriki idarə edəcəyik. Mənim vəziyyətimdə kəşf lövhəsindən istifadə edəcəyəm, amma problemin mahiyyətini başa düşsəniz, hər MCU üçün tətbiq edə bilərsiniz. Belə ki. gəlin başlayaq:)

Addım 1: Avadanlıq və Proqram Tələbləri

Avadanlıq baxımından bizə lazım olacaq:

  • Mənim vəziyyətimdə STM32f4 Discovery lövhəsi olan bir MCU
  • SG90 və ya digərləri kimi ümumi bir servo motor

Proqram təminatı baxımından bizə lazım olacaq:

  • STM32CubeMX
  • Keil uVision

Bunların hamısı varsa, növbəti addıma keçin:)

Addım 2: STM32CubeMX Konfiqurasiyası

Bildiyiniz kimi, servo mühərriki idarə etmək üçün PWM siqnalına ehtiyacımız var. PWM siqnalı baxımından tələblər belədir:

  • PWM müddəti 20 mS olmalıdır
  • Vaxt 0,5 mS ilə 2,5 mS arasında olmalıdır. Vaxtında 0,5 mS olduqda, servo 0 dərəcə, 90 dərəcə üçün 1,5 mS və 180 dərəcə üçün 2,5 mS dönəcək.

Beləliklə, PWM -ni konfiqurasiya etməliyik və bunun üçün Timer1 -dən istifadə edəcəyik.

  • Əvvəlcə Taymerlər bölməsindən TIM1 seçin. Bu addım
  • Sonra Mode bölməsindən

    1. Daxili Saat Bu addımı seçin
    2. PWM Generation CH1 Bu addım
  • Sonra, Konfiqurasiya bölməsindən

    1. Prescaler -ı 160 -a təyin edin Bu addım
    2. Sayaç Dövrünü 2000 -ə təyin edin Bu addım
    3. Pulse -u 50 -yə qoyun Bu addım
  • Əlavə olaraq Saat Konfiqurasiyasından APB1 Timer saatlarını 16 MHz -ə təyin edin. Bu addım

İndi bu addım haqqında bir az danışaq:

APB1 Timer saatımızın tezliyi 16 MHz -dir. Deməli, 1 saniyə əldə etmək üçün 16 000 000 gənə tələb olunur. Bununla birlikdə, prescalerimizi 160 olaraq təyin edirik. Yəni, tezliyimizi bu saya bölürük və gənə sayını 100 minə qədər azaldırıq. Beləliklə, 1 saniyə üçün 100 000 gənəyə ehtiyacımız var. Ancaq əvvəllər qeyd etdiyimiz kimi 20 mS PWM müddətinə ehtiyacımız var. Beləliklə, sadə riyazi hesablamalara görə 20mS üçün 2000 gənəyə ehtiyacımız var. Beləliklə, Counter Period -u 2000 -ə təyin edərək 20 mS olan PWM siqnalının müddətini təyin edirik. İndi 0.5mS -dən 2.5mS -ə qədər On dəfə daxil olmaq üçün qeyd sayını təyin etməliyik. Bu tənliyi sadə riyaziyyatdan əldə edə bilərik və belədir:

On_Time = (Tick_Number / 100). Unutmayın ki, bu servo motorun bucağını dəyişən on_time. Beləliklə, aşağıda bu addımı ümumiləşdirirəm. Hər hansı bir sualınız varsa, şərhlərdə yazın və mümkün qədər tez cavab verəcəyəm.

Hesablamalar şəkli

Bütün bunları etdikdən sonra kod yaradın:)

Addım 3: Keil UVision Kodlaşdırma

Beləliklə, əvvəlcə nə etmək istədiyimizi təyin edək? İstəyirik ki, dərəcəni qəbul edən bir funksiyanı yazaq və servoya yazaq. Yaxşı, bunu necə edəcəyik? Daha əvvəl dediyimiz kimi, bucağı dəyişdirmək üçün vaxtını dəyişdirməliyik. Bucaqlarımız [0, 180] ilə vaxtında [50, 250] arasında dəyişən gənə sayımız arasında dəyişir. Beləliklə, gənələrin sayına görə verilən bucağı xəritələndirən bir Xəritəçəkmə funksiyasına ehtiyacımız var. Məsələn, 0 dərəcə 50 gənə, 180 dərəcə 250 gənə və sair üçün … Elə isə Xəritəçəkmə funksiyamızı yazaq:

int xəritəsi (int st1, int fn1, int st2, int fn2, int dəyəri) {qayıt (1.0*(dəyər-st1))/((fn1-st1)*1.0)*(fn2-st2)+st2; }

Bu, Xəritəçəkmə funksiyamızdır. Necə yarandığı ilə maraqlanırsınızmı? Sonra bunu oxuyun. Beləliklə, aralığımızı və xəritədə görmək istədiyimiz dəyəri götürürük.

İndi bucağı qəbul edən və onu gənə aralığına uyğunlaşdıran bir funksiya yazaq:

boş servo_write (int açısı) {htim1. Instance-> CCR1 = xəritə (0, 180, 50, 250, bucaq); }

Gördüyünüz kimi, bu kod bucağı qəbul edir və onu gənə sayına uyğunlaşdırır. Daha sonra, gənələrin sayı, vaxtı və bucağı idarə edən CCR1 reyestrinə verilir.

Ancaq bunların hamısının işləməsi üçün əvvəlcə yalnız bir kod xətti ilə edilə bilən pwm -i işə salırıq:

HAL_TIM_PWM_Start (& htim1, TIM_CHANNEL_1);

Beləliklə, bucağı qəbul edən və servoya yazan bir funksiyamız var. Gəlin sınayaq və çox asan olan süpürmə funksiyamızı yazaq:

void servo_sweep (void) {for (int i = 0; i <= 180; i ++) {servo_write (i); HAL_Delay (10); } üçün (int i = 180; i> = 0; i--) {servo_write (i); HAL_Delay (10); }}

Beləliklə, 180 -ə qədər, sonra 0 -a qədər saymaq və bu dəyərləri servoya yazmaq:) Beləliklə, nəticəni görək!

Addım 4: Nəticə:)

Deməli, bu sondur. Hər hansı bir sualınız varsa, soruşun. Onlara cavab vermək üçün xoşbəxt olacağam. Oxuduğunuz üçün çox sağ olun və inşallah növbəti layihədə görüşəcəyəm:)

Tövsiyə: