- Mi az a PWM jel?
- PIC programozása PWM előállítására a GPIO csapokon
- Kördiagramm
- Szimuláció
- Hardverbeállítás a szervomotor vezérléséhez PIC mikrokontrollerrel
A PWM jelgenerálás létfontosságú eszköz minden beágyazott mérnöki arzenálban, nagyon sok alkalmazáshoz nagyon hasznosak, például a szervomotor helyzetének szabályozásához, kevés erőátviteli áramkör átkapcsolásához a konverterekben / inverterekben, sőt az egyszerű LED-es fényerő-szabályozáshoz is. A PIC mikrovezérlőkben a PWM jeleket az összehasonlítás, a rögzítés és a PWM (CCP) modulok segítségével lehet előállítani a szükséges regiszterek beállításával, ezt már megtanultuk a PIC PWM oktatóanyagban. Ennek a módszernek azonban van egy jelentős hátránya.
A PIC16F877A csak az RC1 és RC2 érintkezőkön képes PWM jeleket generálni, ha a CCP modulokat használjuk. De előfordulhat, hogy olyan helyzetekre van szükség, ahol több csapra van szükségünk a PWM működéséhez. Például az én esetemben 6 RC szervomotort akarok vezérelni robotkar projektemhez, amelyre a CCP modul reménytelen. Ezekben a forgatókönyvekben programozhatjuk a GPIO csapokat PWM jelek előállítására időzítő modulok segítségével. Így annyi PWM jelet tudunk előállítani bármelyik szükséges tűvel. Vannak más hardveres hackek is, mint például a multiplexer IC használata, de miért érdemes befektetni a hardverre, ha ugyanez programozással elérhető. Tehát ebben az oktatóanyagban megtanuljuk, hogyan kell átalakítani a PIC GPIO tűt PWM tűvé, és teszteléséhez szimuláljuk a proteuson digitális oszcilloszkóppal, valamintvezérelje a szervomotor helyzetét a PWM jel segítségével, és a potenciométer változtatásával változtassa meg a működési ciklust.
Mi az a PWM jel?
Mielőtt rátérnénk a részletekre, fejtsük ki egy kicsit a PWM jeleket. Az impulzusszélesség-moduláció (PWM) egy digitális jel, amelyet leggyakrabban a vezérlő áramkörökben használnak. Ezt a jelet magasra (5v) és alacsonyra (0v) állítják be egy előre meghatározott idő és sebesség mellett. Azt az időtartamot, amely alatt a jel magas marad, „bekapcsolási időnek” nevezzük, és azt az időt, amely alatt a jel alacsony marad, „kikapcsolási időnek”. A PWM-nek két fontos paramétere van, az alábbiak szerint:
A PWM munkaciklusa
Az az idő százalékos aránya, amelyben a PWM jel HIGH marad (időben), ciklusnak számít. Ha a jel mindig BE van kapcsolva, akkor 100% -os működési ciklusban van, és ha mindig ki van kapcsolva, akkor 0% -os működési ciklus.
Üzemeltetési ciklus = bekapcsolási idő / (bekapcsolási idő + kikapcsolási idő)
Változó neve |
Utal rá |
PWM_Frequency |
A PWM jel frekvenciája |
T_TOTAL |
A PWM egy teljes ciklusához szükséges összes idő |
TONNA |
A PWM jel bekapcsolásakor |
FICSÚR |
A PWM jel kikapcsolási ideje |
Duty_cycle |
A PWM jel munkaciklusa |
Tehát most végezzük a matekot.
Ez az a szokásos képlet, ahol a frekvencia egyszerűen az idő reciproka. A frekvencia értékét a felhasználónak kell meghatároznia és beállítania az alkalmazási igénye alapján.
T_TOTAL = (1 / PWM_frekvencia)
Amikor a felhasználó megváltoztatja a Duty cycle értéket, programunknak automatikusan ennek megfelelően kell beállítania a T_ON és a T_OFF időt. Tehát a fenti képletek felhasználhatók a T_ON kiszámítására a Duty_Cycle és a T_TOTAL értéke alapján.
T_ON = (Duty_Cycle * T_TOTAL) / 100
Mivel a PWM jel teljes ideje egy teljes ciklusra a bekapcsolási és a kikapcsolási idő összege lesz. A fent leírt módon kiszámíthatjuk a T_OFF kikapcsolási időt.
T_OFF = T_TOTAL - T_ON
Ezeket a képleteket szem előtt tartva megkezdhetjük a PIC mikrovezérlő programozását. A program magában foglalja a PIC időzítő modult és a PIC ADC modult, hogy POT jelet hozzon létre változó munkaciklus alapján, a POT ADC értéke alapján. Ha még nem ismeri ezeket a modulokat, akkor erősen ajánlott, hogy a hiperhivatkozásokra kattintva olvassa el a megfelelő oktatóanyagot.
PIC programozása PWM előállítására a GPIO csapokon
Az oktatóanyag teljes programja a weboldal alján található, mint mindig. Ebben a szakaszban értsük meg, hogyan is íródik a program. Mint minden program, itt is a konfigurációs bitek beállításával kezdjük. A memória nézetek opciót használtam a beállításhoz.
// CONFIG #pragma config FOSC = HS // Oscillator Selection bit (HS oszcillator ) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT) letiltva) #pragma config BOREN = BE // Brown-out Reset bit engedélyezése (BOR engedélyezve) #pragma config LVP = OFF // Kisfeszültségű (egyszeres tápellátás) Áramkörön belüli soros programozás Engedélyező bit (az RB3 digitális I / O, A programozáshoz a HV on MCLR-t kell használni) #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off) #pragma config WRT = OFF // Flash program memória írása Bitek engedélyezése (Írási védelem ki; az összes programmemóriát az EECON vezérlés írhatja) #pragma config CP = OFF // Flash program memória kódvédő bit (kódvédelem ki) // #pragma config utasításoknak meg kell előzniük a projektfájlokat. // Projektdokumentumokat használjon a #define helyett ON és OFF állapotban. #include
Ezután megemlítjük a hardverben használt órajel frekvenciát, itt a hardverem 20MHz kristályt használ, az értéket megadhatja a hardver alapján. Ezt követi a PWM jel frekvenciaértéke. Mivel célom egy olyan hobbi RC szervomotor vezérlése, amelynek PWM frekvenciája 50 Hz, a frekvencia értékeként 0,05 kHz-t állítottam be, ezt az alkalmazás követelményeinek megfelelően módosíthatja is.
#define _XTAL_FREQ 20000000 #define PWM_Frequency 0.05 // KHz (50Hz)
Most, hogy megvan a Frekvencia értéke, kiszámíthatjuk a T_TOTAL értéket a fent tárgyalt képletek segítségével. Az eredményt elosztjuk 10-gyel, hogy megkapjuk az idő értékét másodpercben. Az én esetemben a T_TOTAL értéke 2 milli másodperc lesz.
int T_TOTAL = (1 / PWM_frekvencia) / 10; // a teljes idő kiszámítása a frekvenciából (milli másodpercben)) // 2msec
Ezt követően inicializáljuk az ADC modulokat a potenciométer helyzetének leolvasására, az ADC PIC oktatóanyagunkban leírtak szerint. Ezután megkapjuk az Interrupt service rutint, amelyet minden alkalommal meghívunk, az időzítő túlcsordul, erre később visszatérünk, most ellenőrizzük a fő funkciót.
A fő funkción belül konfiguráljuk az időzítő modult. Itt úgy állítottam be az Időzítő modult, hogy minden 0,1 ms-on túlcsorduljon. Az idő értékét az alábbi képletek segítségével lehet kiszámítani
RegValue = 256 - ((késleltetés * Fosc) / (Prescalar * 4)) késleltetés másodpercben és Fosc késleltetés hz-ben
Az én esetemben 0,0001 másodperc (0,1 ms) késéssel, 64-es előskalárral és 20 MHz-es Fosc-szel a regiszterem értéke (TMR0) 248 legyen. Tehát a konfiguráció így néz ki
/ ***** Portkonfiguráció az időzítőhöz ****** / OPTION_REG = 0b00000101; // Timer0 külső frekvenciával és 64 mint prescalar // Engedélyezi a PULL UPs TMR0 = 248 értéket is; // Az időérték betöltése 0,0001 másodpercig; a delayValue csak 0-256 között lehet, TMR0IE = 1; // Időzítő megszakítási bit engedélyezése a GIE = 1 PIE1 regiszterben ; // Globális megszakítás engedélyezése PEIE = 1; // Engedélyezze a perifériás megszakítást / *********** ______ *********** /
Ezután be kell állítanunk az Input és Output konfigurációt. Itt az AN0 tűt használjuk az ADC érték és a PORTD csapok leolvasására a PWM jelek kimenetéhez. Tehát kezdeményezze őket kimeneti csapokként, és tegye alacsonyra az alábbi kódsorok használatával.
/ ***** I / O portkonfiguráció ****** / TRISD = 0x00; // utasítsa az MCU-t, hogy a D PORT összes csapja PORTD = 0x00 legyen; // Inicializálja az összes csapot 0-ra / *********** ______ *********** /
A végtelen míg hurokban belül ki kell számolnunk az idő értékét (T_ON) a munkaciklusból. A bekapcsolási idő és az üzemi ciklus a POT pozíciójától függően változik, ezért a while cikluson belül ismételten megtesszük, az alábbiak szerint. A 0.0976 az az érték, amelyet meg kell szorozni 1024-vel, hogy 100-t kapjunk, és a T_ON kiszámításához szorozzuk 10-vel, hogy milli másodpercben kapjuk meg az értéket.
while (1) { POT_val = (ADC_Read (0)); // Olvassa el a POT értékét az ADC Duty_cycle = (POT_val * 0,0976) használatával; // Térkép 0-1024- től 0-ig 100 T_ON = ((Duty_cycle * T_TOTAL) * 10/100); // A bekapcsolási idő kiszámítása a képletek mértékegységével milli másodpercben __ késleltetés_ms (100); }
Mivel az időzítő 0,1 ms-onként túlfolyásra van állítva, az időzítő megszakítási szolgáltatási rutin ISR-t 0,1 ms-onként hívják meg. A szerviz rutinon belül használunk egy változónak nevezett változót, és 0,1 ms-onként növeljük. Így nyomon tudjuk követni az f időt. Ha többet szeretne megtudni a PIC mikrovezérlő megszakításairól, kövesse a hivatkozásokat
ha (TMR0IF == 1) // Az időzítő jelző az időzítő túlcsordulása miatt aktiválódott -> 0,1 ms- onként túlcsordulásra állítva { TMR0 = 248; // Az időzítő betöltése: TMR0IF = 0; // Az időzítő megszakításának jelzőszámának törlése ++; // Count lépésekben minden 0.1ms -> száma / 10 ad értéke count ms }
Végül itt az ideje váltani a GPIO csapot a T_ON és a T_OFF értéke alapján. Megvan a számláló változó, amely milli másodpercben követi az időt. Tehát ezt a változót használjuk annak ellenőrzésére, hogy az idő kevesebb-e, mint az idő , ha igen, akkor a GPIO csapot bekapcsolt állapotban kapcsoljuk ki, és kikapcsoljuk, amíg az új ciklus meg nem kezdődik. Ezt úgy tehetjük meg, hogy összehasonlítjuk egy PWM-ciklus teljes idejével. Az ehhez hasonló kód az alábbiakban látható
if (count <= (T_ON)) // Ha az idő kevesebb, mint az RD1 = 1 időpontban ; // Kapcsolja be a GPIO-t , RD1 = 0; // Egyébként kapcsolja ki a GPIO-t, ha (count> = (T_TOTAL * 10)) // Tartsa kikapcsolva, amíg egy új ciklus meg nem kezdődik = 0;
Kördiagramm
A PWM előállításának kapcsolási rajza a PIC mikrovezérlő GPIO tűjével nagyon egyszerű, csak kapcsolja be a PIC-t oszcillátorral, és csatlakoztassa a potenciométert az AN0, a szervomotort pedig az RD1 tűhöz, a GPIO csap segítségével használhatjuk a PWM jelet, kiválasztottam RD1 csak véletlenszerűen. Mind a potenciométert, mind a szervomotort 5 V-os tápfeszültség táplálja, amelyet a 7805-től vezérelnek, az alábbiakban a kapcsolási rajz szerint.
Szimuláció
A projekt szimulációjához a proteus szoftveremet használtam. Készítse el az alább látható áramkört, és kapcsolja össze a kódot a szimulációval, és futtassa azt. A programunknak megfelelően PWM jelet kell kapnia az RD1 GPIO csapon, és a PWM működési ciklusát a potenciométer pozíciója alapján kell vezérelni. Az alábbi GIF megmutatja, hogyan reagál a PWM jel és a szervomotor, amikor az ADC értéket megváltoztatják a potenciométeren keresztül.
Hardverbeállítás a szervomotor vezérléséhez PIC mikrokontrollerrel
A teljes hardverbeállításom az alábbiakban látható, azok számára, akik követik az oktatóanyagomat, ennek a táblának ismerősnek kell lennie, ugyanaz a tábla, amelyet eddig minden oktatóanyagomban használtam. Hivatkozhat a villogó LED oktatóanyagra, ha kíváncsi arra, hogyan építem fel. Ellenkező esetben csak kövesse a fenti kapcsolási rajzot, és minden rendben működik.
Töltse fel a programot, és változtassa meg a potenciométert, és látnia kell, hogy a szervo megváltoztatja a pozíciót a potenciométer helyzete alapján. A projekt teljes működését az oldal végén található videó mutatja. Remélem, megértette a projektet, és élveztem az építkezést. Ha igényei vannak, nyugodtan tegye fel őket a fórumra, és én mindent megteszek a válaszadásban.
Úgy tervezem, hogy tovább viszem ezt a projektet, több opció hozzáadásával több szervomotor vezérléséhez, és ezáltal egy robotkar építéséhez, hasonlóan az Arduino robotkarhoz, amelyet már építettünk. Szóval addig láss !!