- Što je PWM signal?
- Programiranje PIC-a za generiranje PWM-a na GPIO pinovima
- Kružni dijagram
- Simulacija
- Postavljanje hardvera za upravljanje servo motorom pomoću PIC mikrokontrolera
Generiranje PWM signala je vitalni alat u svakom ugrađenom arsenalu inženjera, vrlo su korisni za mnoštvo aplikacija kao što je kontrola položaja servo motora, prebacivanje nekoliko elektroničkih IC-a u pretvaračima / pretvaračima, pa čak i za jednostavnu kontrolu svjetline LED-a. U PIC mikrokontrolerima PWM signali mogu se generirati pomoću modula Usporedba, Hvatanje i PWM (CCP) postavljanjem potrebnih Registra, već smo naučili kako to učiniti u PIC PWM vodiču. Ali postoji jedan znatan nedostatak kod te metode.
PIC16F877A može generirati PWM signala samo na igle RC1 i RC2, ako ćemo koristiti KPK modula. No, mogli bismo naići na situacije u kojima nam treba više pinova da bismo imali PWM funkcionalnost. Na primjer, u mom slučaju želim kontrolirati 6 RC servo motora za svoj projekt robotske ruke za koji je CCP modul beznadan. U tim scenarijima možemo programirati GPIO pinove za proizvodnju PWM signala pomoću modula s vremenom. Na taj način možemo generirati što više PWM signala bilo kojim potrebnim pinom. Postoje i drugi hardverski hakovi poput upotrebe multipleksera IC, ali zašto ulagati u hardver kad se to isto može postići programiranjem. Tako ćemo u ovom tutorialu naučiti kako pretvoriti PIC GPIO pin u PWM pin i kako bismo ga testirali simulirat ćemo ga na proteusu digitalnim osciloskopom, a takođerkontrolirajte položaj servo motora pomoću PWM signala i mijenjajte njegov radni ciklus mijenjanjem potenciometra.
Što je PWM signal?
Prije nego što uđemo u detalje, razjasnimo malo što su PWM signali. Modulacija širine impulsa (PWM) digitalni je signal koji se najčešće koristi u upravljačkim krugovima. Ovaj je signal postavljen na visoku (5v) i nisku (0v) u unaprijed definiranom vremenu i brzini. Vrijeme tijekom kojeg signal ostaje visok naziva se "on time", a vrijeme tijekom kojeg signal ostaje nizak "vrijeme isključenja". Postoje dva važna parametra za PWM o kojima se govori u nastavku:
Radni ciklus PWM
Postotak vremena u kojem PWM signal ostaje VISOK (na vrijeme) naziva se radnim ciklusom. Ako je signal uvijek UKLJUČEN, on je u 100% radnom ciklusu, a ako je uvijek isključen, to je 0% radnog ciklusa.
Radni ciklus = Vrijeme UKLJUČIVANJA / (Vrijeme UKLJUČIVANJA + Vrijeme isključivanja)

|
Naziv varijable |
Odnosi se na |
|
PWM_frekvencija |
Učestalost PWM signala |
|
UKUPNO |
Ukupno vrijeme potrebno za jedan cjeloviti ciklus PWM-a |
|
TONA |
Na vrijeme PWM signala |
|
T_OFF |
Vrijeme isključenja PWM signala |
|
Radnog ciklusa |
Radni ciklus PWM signala |
Pa sada, napravimo matematiku.
Ovo su standardne formule u kojima je frekvencija jednostavno recipročna vremenu. Vrijednost frekvencije mora odrediti i postaviti korisnik na temelju zahtjeva za prijavu.
T_TOTAL = (1 / frekvencija PWM)
Kad korisnik promijeni vrijednost radnog ciklusa, naš bi program trebao automatski prilagoditi T_ON vrijeme i T_OFF vrijeme. Dakle, gornje formule mogu se koristiti za izračunavanje T_ON na temelju vrijednosti Duty_Cycle i T_TOTAL.
T_ON = (Duty_Cycle * T_TOTAL) / 100
Budući da će ukupno vrijeme PWM signala za jedan puni ciklus biti zbroj vremena i vremena isključenja. Vrijeme izračunavanja T_OFF možemo izračunati kako je gore prikazano.
T_OFF = T_TOTAL - T_ON
Imajući na umu ove formule, možemo započeti s programiranjem PIC mikrokontrolera. Program uključuje PIC modul za mjerenje vremena i PIC ADC modul za stvaranje PWM signala na temelju različitog radnog ciklusa prema vrijednosti ADC iz POT-a. Ako ne koristite ove module, preporučujemo vam da pročitate odgovarajući vodič klikom na hiperveze.
Programiranje PIC-a za generiranje PWM-a na GPIO pinovima
Kompletan program za ovaj udžbenik može se naći na dnu web stranice kao i uvijek. U ovom odjeljku shvatimo kako je program zapravo napisan. Kao i svi programi, započinjemo postavljanjem bitova za konfiguraciju. Koristio sam opciju memorijskih prikaza da bih je postavio za mene.
// CONFIG #pragma config FOSC = HS // Bitovi za odabir oscilatora (HS oscilator) #pragma config WDTE = OFF // Bit za aktiviranje nadzornog sata (WDT onemogućen) #pragma config PWRTE = OFF // Bit za omogućavanje timera za uključivanje (PWRT onemogućeno) #pragma config BOREN = ON // Bit za resetiranje smeđeg reseta (omogućen BOR) #pragma config LVP = OFF // Bit za omogućavanje serijskog programiranja u krugu niskog napona (s jednim napajanjem) (RB3 je digitalni I / O, HV na MCLR-u mora se koristiti za programiranje) #pragma config CPD = OFF // Bit zaštite podataka EEPROM memorijskog koda (zaštita podataka EEPROM koda isključena) #pragma config WRT = OFF // Flash programiranje bita Omogući bitove (isključiti zaštitu; sva programska memorija može biti upisana na EECON kontrolu) #pragma config CP = OFF // Bit programa za zaštitu memorijskog koda Flash programa (zaštita koda isključena) // #pragma config naredbe trebaju prethoditi uključivanju datoteke projekta. // Upotrijebi nabrajanje projekata umjesto #define za UKLJUČENO i ISKLJUČENO. #include
Zatim spominjemo frekvenciju takta koja se koristi u hardveru, ovdje moj hardver koristi kristal od 20 MHz, a vrijednost možete unijeti u svoj hardver. Slijedi vrijednost frekvencije PWM signala. Budući da mi je ovdje cilj kontrolirati hobi RC servo motor koji zahtijeva PWM frekvenciju od 50Hz, postavio sam 0,05KHz kao vrijednost frekvencije, a to možete promijeniti i prema zahtjevima aplikacije.
#define _XTAL_FREQ 20000000 #define PWM_Frequency 0,05 // u KHz (50Hz)
Sada, kada imamo vrijednost Frekvencije, možemo izračunati T_TOTAL koristeći gore raspravljene formule. Rezultat se zaranja za 10 da bi se dobila vrijednost vremena u milli sekundama. U mom slučaju vrijednost T_TOTAL bit će 2 milli sekunde.
int T_TOTAL = (1 / frekvencija PWM) / 10; // izračunavanje ukupnog vremena iz frekvencije (u milli sek)) // 2msec
Nakon toga inicijaliziramo ADC module za očitavanje položaja potenciometra kako je raspravljeno u našem vodiču za ADC PIC. Dalje imamo rutinu usluge Interrupt koja će se pozivati svaki put, timer prelijeva, vratit ćemo se na to kasnije, za sada provjerimo glavnu funkciju.
Unutar glavne funkcije konfiguriramo modul za mjerenje vremena. Ovdje sam konfigurirao modul Timer da se prelijeva za svakih 0,1 ms. Vrijednost vremena može se izračunati pomoću donjih formula
RegValue = 256 - ((Odgoda * Fosc) / (Prescalar * 4)) kašnjenje u sek i Fosc u hz
U mom slučaju za kašnjenje od 0,0001 sekunde (0,1 ms) s pretkalarom od 64 i Fosc od 20 MHz, vrijednost mog registra (TMR0) trebala bi biti 248. Dakle, konfiguracija izgleda ovako
/ ***** Konfiguracija porta za odbrojavanje ****** / OPTION_REG = 0b00000101; // Timer0 s vanjskom frekvencijom i 64 kao predskalarom // Omogućuje i PULL UPs TMR0 = 248; // Učitavanje vremenske vrijednosti za 0,0001s; delayValue može biti između 0-256 samo TMR0IE = 1; // Omogući bit prekida timera u PIE1 registru GIE = 1; // Omogući globalni prekid PEIE = 1; // Omogući periferni prekid / *********** ______ *********** /
Zatim moramo postaviti ulaznu i izlaznu konfiguraciju. Ovdje koristimo pin AN0 za čitanje ADC vrijednosti i PORTD pinove za izlaz PWM signala. Dakle, pokrenite ih kao izlazne igle i umanjite ih koristeći donje retke koda.
/ ***** Konfiguracija porta za I / O ****** / TRISD = 0x00; // uputite MCU da svi pinovi na PORTU D imaju izlaz PORTD = 0x00; // Inicijalizirajte sve pribadače u 0 / *********** ______ *********** /
Unutar beskonačne while petlje moramo izračunati vrijednost vremena (T_ON) iz radnog ciklusa. Na vrijeme i dužnost ciklus varira ovisno o položaju u lonac pa smo to učiniti više puta unutar while petlje kao što je prikazano u nastavku. 0,0976 je vrijednost koju treba pomnožiti s 1024 da bi se dobilo 100, a za izračunavanje T_ON pomnožili smo je s 10 da bismo dobili vrijednost u milli sekundi.
while (1) { POT_val = (ADC_Read (0)); // Očitavanje vrijednosti POT pomoću ADC Duty_cycle = (POT_val * 0.0976); // Karta 0 do 1024 do 0 do 100 T_ON = ((Duty_cycle * T_TOTAL) * 10/100); // Izračunaj vrijeme pomoću jedinice formule u milli sekund __delay_ms (100); }
Budući da je tajmer postavljen na prekomjerni protok za svakih 0,1 ms, rutinska usluga usluge prekida tajmera pozivat će se za svakih 0,1 ms. Unutar rutine usluge koristimo varijablu koja se naziva count i povećavamo je za svakih 0,1 ms. Na taj način možemo pratiti vrijeme. Da biste saznali više o Prekidima u PIC mikrokontroleru, slijedite poveznice
if (TMR0IF == 1) // Oznaka odbrojavanja pokrenuta je zbog preljeva odbrojavanja -> postavljeno na preljev za svakih 0,1 ms { TMR0 = 248; // Učitaj timer Vrijednost TMR0IF = 0; // Očisti broj zastavica prekida timera ++; // Koraci brojanja za svakih 0,1 ms -> count / 10 dat će vrijednost brojanja u ms }
Napokon je vrijeme da prebacite GPIO pin na osnovu vrijednosti T_ON i T_OFF. Imamo varijablu count koja prati vrijeme u milli sekundama. Dakle, koristimo tu varijablu da provjerimo je li vrijeme kraće od vremena , ako da, onda GPIO pin držimo uključenim, inače ga isključujemo i držimo isključenim dok novi ciklus ne započne. To se može učiniti usporedbom s ukupnim vremenom jednog PWM ciklusa. Kôd za isto je prikazan u nastavku
if (count <= (T_ON)) // Ako je vrijeme manje od vremena RD1 = 1; // Uključi GPIO inače RD1 = 0; // U suprotnom isključite GPIO ako (count> = (T_TOTAL * 10)) // Držite ga isključenim dok novi ciklus ne započne count = 0;
Kružni dijagram
Shema sklopa za generiranje PWM-a s GPIO pinom PIC mikrokontrolera je zaista jednostavna, samo napajajte PIC oscilatorom i povežite potenciometar na pin AN0, a servo motor na pin RD1, možemo koristiti GPIO pin za dobivanje PWM signala, odabrao sam RD1 samo slučajno. Potenciometar i servo motor napaja se s naponom od 5 V, što je regulirano od 7805, kao što je prikazano dolje u shemi spojeva.

Simulacija
Za simulaciju projekta koristio sam svoj softver proteus. Izgradite donji krug i povežite kôd sa svojom simulacijom i pokrenite ga. Trebali biste dobiti PWM signal na RD1 GPIO pinu prema našem programu, a radni ciklus PWM-a trebao bi se kontrolirati na temelju položaja potenciometra. Donji GIF prikazuje kako PWM signal i servo motor reagiraju kada se vrijednost ADC promijeni kroz potenciometar.

Postavljanje hardvera za upravljanje servo motorom pomoću PIC mikrokontrolera
Moja kompletna hardverska postavka prikazana je u nastavku, za ljude koji slijede moje tutorijale ova bi ploča trebala izgledati poznato, to je ista ploča koju sam do sada koristio u svim svojim tutorijalima. Možete se obratiti vodiču za trepćuće LED diode ako vas zanima kako ga gradim. U suprotnom samo slijedite gornju shemu i svi bi trebali raditi u redu.

Prenesite program i promijenite potenciometar i trebali biste vidjeti kako servo mijenja položaj na temelju položaja potenciometra. Kompletan radni projekta je prikazan u videu dao na kraju ove stranice. Nadam se da ste razumjeli projekt i uživali u gradnji, ako imate želje, slobodno ih objavite na forumu, a ja ću se potruditi odgovoriti.
Planiram ovaj projekt nastaviti naprijed dodavanjem opcija za upravljanje višestrukim servo motorima i tako od njega izgraditi robotsku ruku, slično Arduino Robotic Arm koju smo već izgradili. Pa do tada se vidimo !!
