Turinys:

Servo variklio valdymas naudojant STM32F4 ARM MCU: 4 žingsniai
Servo variklio valdymas naudojant STM32F4 ARM MCU: 4 žingsniai

Video: Servo variklio valdymas naudojant STM32F4 ARM MCU: 4 žingsniai

Video: Servo variklio valdymas naudojant STM32F4 ARM MCU: 4 žingsniai
Video: Arduino pamoka Nr. 8: Servo mechanizmas 2024, Liepa
Anonim
Servo variklio valdymas su STM32F4 ARM MCU
Servo variklio valdymas su STM32F4 ARM MCU
Servo variklio valdymas su STM32F4 ARM MCU
Servo variklio valdymas su STM32F4 ARM MCU

Sveiki dar kartą bičiuliai:) Taigi, šiame projekte mes valdysime servo variklį su STM32F4 ARM MCU. Mano atveju naudosiu atradimų lentą, bet jei suprasite problemos esmę, galėsite ją pritaikyti kiekvienam MCU. Taigi. Pradėkime:)

1 žingsnis: Techninės ir programinės įrangos reikalavimai

Kalbant apie aparatūrą, mums reikės:

  • MCU, kuris mano atveju yra STM32f4 „Discovery“lenta
  • Įprastas servo variklis, kaip SG90 ar bet kuris kitas

Kalbant apie programinę įrangą, mums reikės:

  • STM32CubeMX
  • Keil uVision

Jei turite visa tai, pereikite prie kito žingsnio:)

2 veiksmas: „STM32CubeMX“konfigūravimas

Kaip žinote, norint valdyti servo variklį, mums reikia PWM signalo. PWM signalo reikalavimai yra tokie:

  • PWM laikotarpis turi būti 20 mS
  • Laikas turi būti nuo 0,5 mS iki 2,5 mS. Kai laikas yra 0,5 mS, servo sistema pasuks 0 laipsnių, 1,5 mS - 90 laipsnių ir 2,5 mS - 180 laipsnių.

Taigi, turime sukonfigūruoti PWM ir tam tikslui naudosime „Timer1“.

  • Pirmiausia skyriuje „Laikmačiai“pasirinkite TIM1. Šis žingsnis
  • Tada skiltyje „Režimas“

    1. Pasirinkite Vidinis laikrodis Šis veiksmas
    2. PWM karta CH1 Šis žingsnis
  • Tada iš konfigūracijos skyriaus

    1. Nustatykite prescaler į 160 Šis žingsnis
    2. Nustatykite skaitiklio laikotarpį į 2000 Šis žingsnis
    3. Nustatykite pulsą į 50 Šis žingsnis
  • Be to, iš laikrodžio konfigūracijos nustatykite APB1 laikmačio laikrodžius į 16 MHz. Šis žingsnis

Dabar šiek tiek pakalbėkime apie šį žingsnį:

Mūsų APB1 laikmačio dažnis yra 16 MHz. Taigi, tai reiškia, kad norint gauti 1 sekundę reikia 16 000 000 erkių. Tačiau mes nustatėme savo prescalerį į 160. Tai reiškia, kad mes padalijame savo dažnį iš to skaičiaus ir sumažiname erkių skaičių iki 100 000. Taigi, 1 sekundei mums reikia 100 000 erkių. Tačiau mums reikia 20 mS PWM laikotarpio, kaip minėjome anksčiau. Taigi, remiantis paprasta matematika, mums reikia 2000 erkių 20 mS. Taigi, nustatydami skaitiklio periodą į 2000, mes nustatome PWM signalo laikotarpį, kuris yra 20 mS. Dabar turime nustatyti erkių skaičių, kad įjungimo laikas būtų nuo 0,5 mS iki 2,5 mS. Šią lygtį galime gauti iš paprastos matematikos ir ji yra tokia:

„On_Time“= (varnelės numeris / 100). Atminkite, kad būtent „on_time“keičia servo variklio kampą. Taigi, žemiau esančiame paveikslėlyje apibendrinu šį žingsnį. Jei turite kokių nors klausimų, rašykite komentaruose ir aš atsakysiu kuo greičiau.

Skaičiavimų vaizdas

Atlikę visus šiuos veiksmus sugeneruokite kodą:)

3 žingsnis: Keil UVision kodavimas

Taigi, pirmiausia nuspręskime, ką norime daryti? Mes norime parašyti funkciją, kuri priima laipsnį, ir parašyti ją į servo. Taigi, kaip mes tai padarysime? Kaip jau minėjome anksčiau, norėdami pakeisti kampą, turime pakeisti laiką. Mūsų kampai kinta tarp [0, 180] ir erkių skaičius, o tai lemia laiko pokyčius tarp [50, 250]. Taigi, mums reikia kartografavimo funkcijos, kuri susieja tam tikrą kampą su erkių skaičiaus diapazonu. Pavyzdžiui, 0 laipsnių 50 erkių, 180 laipsnių 250 erkių ir pan. Taigi parašykime savo žemėlapio funkciją:

int žemėlapis (int st1, int fn1, int st2, int fn2, int value) {return (1,0*(vertė-st1))/((fn1-st1)*1,0)*(fn2-st2)+st2; }

Tai yra mūsų kartografavimo funkcija. Ar jus domina, kaip jis gaunamas? Tada perskaityk tai. Taigi, imame savo diapazonus ir vertę, kurią norime susieti.

Dabar parašykime funkciją, kuri priima kampą ir susieja jį su erkių diapazonu:

void servo_write (int kampas) {htim1. Instance-> CCR1 = žemėlapis (0, 180, 50, 250, kampas); }

Kaip matote, šis kodas priima kampą ir susieja jį su erkių skaičiaus diapazonu. Tada erkių skaičius pateikiamas CCR1 registrui, kuris kontroliuoja įjungimo laiką ir taip kampą.

Tačiau, kad visa tai veiktų, pirmiausia paleidžiame pwm, kurį galima padaryti naudojant tik kodo eilutę:

HAL_TIM_PWM_Start (& htim1, TIM_CHANNEL_1);

Taigi, mes turime funkciją, kuri priima kampą ir įrašo jį į servo. Išbandykime ir parašykime savo valymo funkciją, kuri yra labai paprasta:

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

Taigi, tiesiog suskaičiuokite iki 180 ir tada iki 0 ir įrašykite šias vertes į servo:) Taigi, pažiūrėkime rezultatą!

4 žingsnis: rezultatas:)

Taigi, tai yra pabaiga. Jei turite kokių nors klausimų, klauskite. Aš būsiu laimingas, galėdamas jiems atsakyti. Labai ačiū, kad skaitote, ir tikiuosi, kad susitiksime kitame projekte:)

Rekomenduojamas: