- Kas yra PWM signalas?
- Programavimas PIC generuoti PWM ant GPIO kaiščių
- Grandinės schema
- Modeliavimas
- Aparatinės įrangos sąranka servovarikliui valdyti naudojant PIC mikrovaldiklį
PWM signalo generavimas yra gyvybiškai svarbus įrankis kiekviename įterptųjų inžinierių arsenale. Jie labai praverčia daugelyje programų, pavyzdžiui, valdant servovariklio padėtį, perjungiant keletą galios elektroninių keitiklių / keitiklių IC ir netgi paprastam LED ryškumo valdymui. PIC mikrovaldikliuose PWM signalai gali būti generuojami naudojant „ Compare“, „Capture“ ir „PWM“ (CCP) modulius nustatant reikiamus registrus. Mes jau išmokome tai padaryti PIC PWM pamokoje. Tačiau taikant šį metodą yra vienas didelis trūkumas.
PIC16F877A gali generuoti PWM signalus tik smeigtukai RC1 ir RC2, jei mes naudojame BPK modulius. Tačiau galime susidurti su situacijomis, kai mums reikia daugiau kaiščių, kad galėtume naudoti PWM funkcionalumą. Pavyzdžiui, mano atveju aš noriu valdyti 6 RC servovariklius savo robotų rankos projektui, kurio CCP modulis yra beviltiškas. Tokiais atvejais galime užprogramuoti GPIO kaiščius, kad jie generuotų PWM signalus, naudodami laikmačio modulius. Tokiu būdu mes galime sugeneruoti kuo daugiau PWM signalų naudodami bet kurį reikalingą kaištį. Yra ir kitų aparatinės įrangos įsilaužimų, tokių kaip multiplekserio IC naudojimas, bet kodėl verta investuoti į aparatinę įrangą, kai tą patį galima pasiekti programuojant. Taigi šioje pamokoje sužinosime, kaip konvertuoti PIC GPIO kaištį į PWM kaištį, ir, norėdami jį išbandyti, imituosime jį proteuse su skaitmeniniu osciloskopu, taip patvaldykite servo variklio padėtį naudodami PWM signalą ir keiskite jo veikimo ciklą keisdami potenciometrą.
Kas yra PWM signalas?
Prieš įsigilindami į detales, šiek tiek patikslinkime, kokie yra PWM signalai. Pulso pločio moduliacija (PWM) yra skaitmeninis signalas, kuris dažniausiai naudojamas valdymo grandinėse. Šis signalas nustatytas iš anksto (5v) ir žemas (0v) iš anksto nustatytu laiku ir greičiu. Laikas, per kurį signalas išlieka aukštas, vadinamas „įjungimo laiku“, o laikas, per kurį signalas lieka žemas, vadinamas „išjungimo laiku“. Yra du svarbūs PWM parametrai, kaip aptarta toliau:
PWM darbo ciklas
Laiko procentas, per kurį PWM signalas lieka AUKŠTAS (laiku), vadinamas darbo ciklu. Jei signalas visada įjungtas, jis yra 100% darbo ciklo, o jei jis visada išjungtas, jis yra 0%.
Darbo ciklas = Įjungti laiką / (Įjungti laiką + Išjungti laiką)
Kintamojo pavadinimas |
Nurodo |
PWM_Dažnis |
PWM signalo dažnis |
T_TOTAL |
Bendras viso PWM ciklo laikas |
T_ON |
Įjungus PWM signalo laiką |
T_OFF |
PWM signalo išjungimo laikas |
Duty_cycle |
PWM signalo veikimo ciklas |
Taigi dabar atlikime matematiką.
Tai yra standartinės formulės, kai dažnis yra tiesiog abipusis laikas. Dažnio vertę turi nuspręsti ir nustatyti vartotojas, atsižvelgdamas į savo taikymo reikalavimus.
T_TOTAL = (1 / PWM_Dažnis)
Kai vartotojas pakeičia „Duty cycle“ vertę, mūsų programa turėtų automatiškai pagal tai koreguoti T_ON laiką ir T_OFF laiką. Taigi pirmiau pateiktas formules galima naudoti apskaičiuojant T_ON pagal Duty_Cycle ir T_TOTAL vertę.
T_ON = (Duty_Cycle * T_TOTAL) / 100
Kadangi viso viso ciklo PWM signalo trukmė bus įjungimo ir išjungimo laiko suma. Mes galime apskaičiuoti išjungimo laiką T_OFF, kaip parodyta aukščiau.
T_OFF = T_TOTAL - T_ON
Atsižvelgdami į šias formules, galime pradėti programuoti PIC mikrovaldiklį. Programa apima PIC laikmačio modulį ir PIC ADC modulį, kad būtų sukurtas PWM signalas, pagrįstas įvairiu darbo ciklu pagal ADC vertę iš POT. Jei dar nesinaudojate šiais moduliais, labai rekomenduojama perskaityti atitinkamą mokymo programą spustelėjus hipersaitus.
Programavimas PIC generuoti PWM ant GPIO kaiščių
Visa programa šiai pamoka gali būti rasti svetainės kaip visada apačioje. Šiame skyriuje supraskime, kaip iš tikrųjų rašoma programa. Kaip ir visos programos, mes pradedame nuo konfigūracijos bitų nustatymo. Aš naudoju atminties peržiūros parinktį, kad ją nustatyčiau man.
// CONFIG #pragma config FOSC = HS // Oscilatoriaus pasirinkimo bitai (HS osciliatorius) #pragma config WDTE = OFF // Watchdog Timer Įjungti bitą (WDT išjungtas) #pragma config PWRTE = OFF / Paleidimo laikmatis Įgalinti bitą (PWRT) išjungtas) #pragma config BOREN = ĮJUNGTA // Išjungtas iš naujo Įgalinti bitą (įjungtas BOR) #pragma config LVP = IŠJUNGTAS // Žemos įtampos (vieno maitinimo) grandinės nuosekliojo programavimo įgalinimo bitas (RB3 yra skaitmeninis įvesties / išvesties išėjimas, Programuojant reikia naudoti „HV on MCLR“) #pragma config CPD = OFF // Duomenų EEPROM atminties kodo apsaugos bitai (duomenų EEPROM kodo apsauga išjungta) #pragma config WRT = OFF // „Flash“ programos atminties įrašymas Įgalinti bitus (nurašymo apsauga; visa programos atmintis gali būti įrašyta EECON valdikliu) #pragma config CP = OFF // „Flash“ programos atminties kodo apsaugos bitas (kodo apsauga išjungta) // #pragma config sakiniai turėtų būti pateikiami prieš įtraukiant projekto failą. // ĮJUNGTI ir IŠJUNGTI naudokite projekto sąrašus, o ne #define. # įtraukti
Tada mes paminime aparatinėje įrangoje naudojamą laikrodžio dažnį, čia mano aparatūra naudoja 20MHz kristalą, vertę galite įvesti pagal savo aparatinę įrangą. Po to seka PWM signalo dažnio vertė. Kadangi čia siekiu valdyti hobio RC servo variklį, kuriam reikalingas 50W PWM dažnis, nustatiau 0,05KHz kaip dažnio vertę, taip pat galite tai pakeisti pagal savo programos reikalavimus.
#define _XTAL_FREQ 20000000 #define PWM_Frequency 0.05 // KHz (50Hz)
Dabar, kai turime dažnio vertę, galime apskaičiuoti T_TOTAL naudodami aukščiau aptartas formules. Rezultatas padalijamas iš 10, kad gautumėte laiko vertę mili sekundėmis. Mano atveju T_TOTAL vertė bus 2 mili sekundės.
int T_TOTAL = (1 / PWM_Dažnis) / 10; // apskaičiuokite bendrą laiką iš dažnio (mili sekundėmis)) // 2msek
Po to mes inicijuojame ADC modulius potenciometro padėčiai nuskaityti, kaip aptarta mūsų ADC PIC pamokoje. Tada turėsime pertraukiamojo aptarnavimo rutiną, kuri bus kviečiama kiekvieną kartą, laikmatis perpildytas, prie kurio vėl grįšime, kol kas patikrinkime pagrindinę funkciją.
Pagrindinės funkcijos viduje mes sukonfigūruojame laikmačio modulį. Čia sukonfigūravau laikmačio modulį perpildyti kas 0,1 ms. Laiko vertę galima apskaičiuoti naudojant toliau pateiktas formules
„RegValue“ = 256 - ((vėlavimas * Fosc) / (Prescalar * 4)) uždelsimas sekundėmis ir Fosc hz
Mano atveju, esant 0,0001 sekundės (0,1 ms) vėlavimui, kai preskalaras yra 64 ir „Fosc“ - 20 MHz, mano registro (TMR0) vertė turėtų būti 248. Taigi konfigūracija atrodo taip
/ ***** Laikmačio prievado konfigūracija ****** / OPTION_REG = 0b00000101; // „Timer0“ su išoriniu dažniu ir 64 kaip išankstinis skalė . // Įkelkite laiko vertę 0,0001 s; „delayValue“ gali būti tik tarp 0–256 TMR0IE = 1; // Įjungti laikmačio pertraukimo bitą PIE1 registre GIE = 1; // Įgalinti visuotinį pertraukimą PEIE = 1; // Įgalinti periferinį pertraukimą / *********** ______ *********** /
Tada mes turime nustatyti įvesties ir išvesties konfigūraciją. Čia mes naudojame AN0 kaištį ADC vertei ir PORTD kaiščiams nuskaityti, kad išvestumėte PWM signalus. Taigi pradėkite juos kaip išvesties kaiščius ir padarykite juos žemus naudodami žemiau esančias kodo eilutes.
/ ***** prievado konfigūracija I / O ****** / TRISD = 0x00; // Nurodykite MCU, kad visi PORT D kaiščiai būtų išvedami PORTD = 0x00; // Inicializuokite visus kaiščius į 0 / *********** ______ *********** /
„Infinite while loop“ viduje mes turime apskaičiuoti laiko vertę (T_ON) iš darbo ciklo. Įjungimo laikas ir darbo ciklas skiriasi priklausomai nuo POT padėties, todėl mes darome tai pakartotinai ciklo viduje , kaip parodyta žemiau. 0.0976 yra reikšmė, kurią reikia padauginti iš 1024, kad gautume 100, o norėdami apskaičiuoti T_ON, mes ją padauginome iš 10, kad gautume vertę per mili sekundes.
o (1) { POT_val = (ADC_Read (0)); // Perskaitykite POT reikšmę naudodami ADC Duty_cycle = (POT_val * 0.0976); // Žemėlapis nuo 0 iki 1024 iki 0 iki 100 T_ON = ((Duty_cycle * T_TOTAL) * 10/100); // Apskaičiuokite įjungimo laiką naudodami formulių vienetą mili sekundėmis __delay_ms (100); }
Kadangi laikmatis yra nustatytas per dideliam srautui kas 0,1 ms, laikmačio pertraukimo paslaugos kasdieninė ISR bus iškviesta kas 0,1 ms. Aptarnavimo rutinoje mes naudojame kintamąjį, vadinamą count ir didiname jį kas 0,1 ms. Tokiu būdu galime stebėti laiką. Norėdami sužinoti daugiau apie PIC mikrovaldiklio pertraukimus, eikite į nuorodas
jei (TMR0IF == 1) // Laikmačio vėliava suveikė dėl laikmačio perpildymo -> nustatyta perpildyti kas 0,1 ms { TMR0 = 248; // Įkelti laikmatį Reikšmė TMR0IF = 0; // Išvalyti laikmačio pertraukimo vėliavų skaičių ++; // Skaičiavimo prieaugis už kiekvieną 0,1 ms -> skaičius / 10 suteiks skaičiaus reikšmę ms }
Pagaliau atėjo laikas perjungti GPIO kaištį pagal T_ON ir T_OFF vertę. Mes turime skaičiavimo kintamąjį, kuris stebi laiką mili sekundėmis. Taigi mes naudojame šį kintamąjį, kad patikrintume, ar laikas yra trumpesnis nei laiku , jei taip, mes palaikome įjungtą GPIO kaištį, mes jį išjungiame ir išjungiame, kol prasideda naujas ciklas. Tai galima padaryti palyginus jį su bendru vieno PWM ciklo laiku. Tą patį darantis kodas parodytas žemiau
if (skaičius <= (T_ON)) // Jei laikas mažesnis nei laiku RD1 = 1; // Įjungti GPIO else RD1 = 0; // Kitas išjungti GPIO if (skaičius> = (T_TOTAL * 10)) // Laikykite jį išjungtą, kol prasidės naujas ciklas = 0;
Grandinės schema
Grandinės schema, skirta PWM generuoti su PIC mikrovaldiklio GPIO kaiščiu, yra tikrai paprasta, tiesiog įjunkite PIC su osciliatoriumi ir prijunkite potenciometrą prie AN0, o servovariklis - prie RD1, mes galime naudoti GPIO kaištį PWM signalui gauti, aš pasirinkau RD1 tiesiog atsitiktinai. Tiek potenciometrą, tiek servo variklį maitina 5 V, kurį reguliuoja nuo 7805, kaip parodyta žemiau grandinės schemoje.
Modeliavimas
Norėdami imituoti projektą, aš naudoju savo proteus programinę įrangą. Sukurkite žemiau parodytą grandinę ir susiekite kodą su savo modeliavimu ir paleiskite jį. Jūs turėtumėte gauti PWM signalą ant RD1 GPIO kaiščio pagal mūsų programą, o PWM veikimo ciklas turėtų būti valdomas atsižvelgiant į potenciometro padėtį. Žemiau pateiktas GIF rodo, kaip PWM signalas ir servo variklis reaguoja, kai per potenciometrą keičiama ADC vertė.
Aparatinės įrangos sąranka servovarikliui valdyti naudojant PIC mikrovaldiklį
Mano visas aparatinės įrangos nustatymas parodytas žemiau, žmonėms, kurie seka mano vadovėlius, ši lenta turėtų atrodyti pažįstama, tai yra ta pati plokštė, kurią aš naudojau visose savo mokymo programose. Jei norite sužinoti, kaip aš jį kuriu, galite kreiptis į „Mirksinčio LED“ mokymo programą. Priešingu atveju tiesiog vadovaukitės pirmiau pateikta schema ir viskas turėtų veikti gerai.
Įkelkite programą ir keiskite potenciometrą, ir jūs turėtumėte pamatyti, kaip servo keičia padėtį, atsižvelgiant į potenciometro padėtį. Visas projekto darbas parodytas vaizdo įraše, pateiktame šio puslapio pabaigoje. Tikiuosi, kad supratote projektą ir jums patiko kurti, jei turite norų, nedvejodami paskelbkite juos forume ir aš pasistengsiu atsakyti.
Aš planuoju tęsti šį projektą, įtraukdamas galimybes valdyti kelis servovariklius ir taip pastatydamas iš jo robotinę ranką, panašią į jau pastatytą „Arduino“ robotų ranką. Taigi iki tol žiūrėk !!