- Mikä on PWM-signaali?
- PIC: n ohjelmointi tuottamaan PWM GPIO-nastoille
- Piirikaavio
- Simulointi
- Laitteiston asetukset servomoottorin ohjaamiseksi PIC-mikrokontrollerilla
PWM-signaalin tuottaminen on tärkeä työkalu jokaisessa sulautettujen insinöörien arsenaalissa, ja ne ovat erittäin hyödyllisiä monissa sovelluksissa, kuten servomoottorin aseman ohjauksessa, muutaman tehoelektroniikan IC: n kytkemisessä muuntimiin / inverttereihin ja jopa yksinkertaiseen LED-kirkkauden säätöön. PIC-mikrokontrollereissa PWM-signaalit voidaan tuottaa käyttämällä vertailu-, sieppaus- ja PWM (CCP) -moduuleja asettamalla vaaditut rekisterit, olemme jo oppineet tekemään sen PIC PWM -oppaassa. Mutta tällä menetelmällä on yksi huomattava haitta.
PIC16F877A voi tuottaa PWM-signaaleja vain nastat RC1 ja RC2, jos käytämme CCP moduulit. Mutta saatamme kohdata tilanteita, joissa tarvitsemme lisää nastoja PWM-toiminnon saamiseksi. Esimerkiksi minun tapauksessani haluan ohjata kuutta RC-servomoottoria robottihankeprojektiini, johon CCP-moduuli on toivoton. Näissä tilanteissa voimme ohjelmoida GPIO-nastat tuottamaan PWM-signaaleja ajastinmoduuleilla. Tällä tavalla voimme tuottaa niin monta PWM-signaalia millä tahansa vaaditulla tapilla. On myös muita laitteisto-hakkereita, kuten multiplekseri-IC: n käyttö, mutta miksi investoida laitteistoon, kun sama voidaan saavuttaa ohjelmoinnin aikana. Joten tässä opetusohjelmassa opitaan kuinka muuntaa PIC GPIO -nasta PWM-nastaksi ja testata sitä simuloimme sitä proteuksessa digitaalisella oskilloskoopilla ja myösohjaa servomoottorin asemaa PWM-signaalilla ja muuta sen käyttöjaksoa vaihtelemalla potentiometriä.
Mikä on PWM-signaali?
Ennen kuin pääsemme yksityiskohtiin, harjoittelemme hieman PWM-signaaleja. Pulssileveyden modulaatio (PWM) on digitaalinen signaali, jota käytetään yleisimmin ohjauspiireissä. Tämä signaali on asetettu korkealle (5v) ja matalalle (0v) ennalta määritetyssä ajassa ja nopeudessa. Aikaa, jonka aikana signaali pysyy korkealla, kutsutaan “päälläoloaikaksi” ja aikaa, jonka aikana signaali pysyy matalana, ”sammutusajaksi”. PWM: llä on kaksi tärkeää parametria, kuten alla käsitellään:
PWM: n toimintajakso
Prosenttiaikaa, jonka aikana PWM-signaali pysyy KORKEAna (ajallaan), kutsutaan työjaksoksi. Jos signaali on aina päällä, se on 100%: n käyttöjaksossa ja jos se on aina pois päältä, se on 0%: n käyttöjakso.
Käyttösykli = Kytke päälle aika / (Kytke päälle aika + Sammuta aika)
Muuttujan nimi |
Viittaa |
PWM_Frequency |
PWM-signaalin taajuus |
T_TOTAL |
Yhden kokonaisen PWM-syklin kokonaisaika |
T_ON |
PWM-signaalin aika |
T_OFF |
PWM-signaalin sammutusaika |
Duty_cycle |
PWM-signaalin toimintajakso |
Joten nyt, tehdään matematiikka.
Tämä on vakiokaava, jossa taajuus on yksinkertaisesti ajan vastavuoroinen. Käyttäjän on päätettävä ja asetettava taajuuden arvo sovellustarpeidensa perusteella.
T_TOTAL = (1 / PWM_taajuus)
Kun käyttäjä muuttaa käyttöjakson arvoa, ohjelmamme tulisi säätää automaattisesti T_ON-aika ja T_OFF-aika sen mukaan. Joten yllä olevia kaavoja voidaan käyttää laskemaan T_ON Duty_Cycle- ja T_TOTAL-arvojen perusteella.
T_ON = (Duty_Cycle * T_TOTAL) / 100
Koska PWM-signaalin kokonaisaika yhdelle täysjaksolle on aika- ja sammutusajan summa. Voimme laskea sammutusajan T_OFF kuten yllä on esitetty.
T_OFF = T_TOTAL - T_ON
Nämä kaavat huomioon ottaen voimme aloittaa PIC-mikrokontrollerin ohjelmoinnin. Ohjelma sisältää PIC-ajastinmoduulin ja PIC ADC -moduulin PWM-signaalin luomiseksi vaihtelevaan käyttöjaksoon POT: n ADC-arvon mukaisesti. Jos et ole vielä käyttänyt näitä moduuleja, on erittäin suositeltavaa lukea sopiva opetusohjelma napsauttamalla hyperlinkkejä.
PIC: n ohjelmointi tuottamaan PWM GPIO-nastoille
Täydellinen ohjelma tähän opetusohjelma löytyy alareunassa verkkosivuilla kuten aina. Tässä osassa ymmärretään, miten ohjelma todella kirjoitetaan. Kuten kaikki ohjelmat, aloitamme asettamalla kokoonpanobitit. Olen käyttänyt muistinäkymävaihtoehtoa sen asettamiseksi minulle.
// CONFIG #pragma config FOSC = HS // Oskillaattorin valintabitit (HS-oskillaattori) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT pois käytöstä) #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT) pois käytöstä) #pragma config BOREN = PÄÄLLÄ // Ruskea-out Nollaa bitti (BOR käytössä) #pragma config LVP = OFF // Pienjännite (yksisyöttö) Piirin sisäinen sarjaliitäntäohjelmointi Aktivoi bitti (RB3 on digitaalinen I / O, Ohjelmoinnissa on käytettävä HV on MCLR) #pragma config CPD = OFF // Data EEPROM -muistikoodisuojabitti (Data EEPROM- koodisuojaus pois päältä) #pragma config WRT = OFF // Flash-ohjelmamuistin kirjoitus Salli bitit (kirjoitus suojaus pois; koko ohjelmamuisti voidaan kirjoittaa EECON-ohjauksella) #pragma config CP = OFF // Flash-ohjelman muistikoodin suojausbitti (koodinsuojaus pois päältä) // #pragma config -lausekkeiden tulisi edeltää projektitiedostojen sisältämistä. // Käytä projektin enums sijasta #define ON ja OFF. #sisältää
Sitten mainitaan laitteistossa käytetty kellotaajuus, tässä laitteistoni käyttää 20 MHz: n kristallia, voit syöttää arvon laitteistosi perusteella. Tätä seuraa PWM-signaalin taajuusarvo. Koska tavoitteenani on ohjata harrastus-RC-servomoottoria, joka vaatii PWM-taajuuden 50 Hz, olen asettanut taajuusarvoksi 0,05 KHz, voit myös muuttaa tätä sovelluksesi vaatimusten perusteella.
#define _XTAL_FREQ 20000000 #define PWM_Frequency 0.05 // in KHz (50Hz)
Nyt kun meillä on taajuuden arvo, voimme laskea T_TOTAL käyttämällä yllä käsiteltyjä kaavoja. Tulos jaetaan 10: llä, jotta aika saadaan millisekunteina. Minun tapauksessani T_TOTAL-arvo on 2 miljoonaa sekuntia.
int T_TOTAL = (1 / PWM_taajuus) / 10; // laskea kokonaisaika taajuudelta (millisekunteina) // // ms
Sen jälkeen alustamme ADC-moduulit potentiometrin sijainnin lukemiseen, kuten ADC PIC -opetusohjelmassa on keskusteltu. Seuraavaksi meillä on keskeytyspalvelurutiini, jota kutsutaan joka kerta, ajastin ylittää, palataan tähän myöhemmin, tarkistetaan nyt päätoiminto.
Päätoiminnon sisällä konfiguroimme ajastinmoduulin. Tässä olen määrittänyt ajastinmoduulin ylivuotamaan 0,1 ms välein. Ajan arvo voidaan laskea käyttämällä alla olevia kaavoja
RegValue = 256 - ((Delay * Fosc) / (Prescalar * 4)) viive sekunteina ja Fosc hz
Minun tapauksessani 0,0001 sekunnin (0,1 ms) viive, kun esiasetusarvo on 64 ja Fosc 20 MHz, rekisterini (TMR0) arvon tulisi olla 248. Joten kokoonpano näyttää tältä
/ ***** Portin määritys ajastimelle ****** / OPTION_REG = 0b00000101; // Ajastin0 ulkoisella taajuudella ja 64 preskalaarina // Mahdollistaa myös PULL UPs TMR0 = 248; // Lataa aika-arvo 0,0001 sekunnille; delayValue voi olla välillä 0-256 vain TMR0IE = 1; // Ota ajastimen keskeytysbitti käyttöön PIE1-rekisterissä GIE = 1; // Ota globaali keskeytys käyttöön PEIE = 1; // Ota käyttöön oheislaitteiden keskeytys / *********** ______ *********** /
Sitten meidän on määritettävä tulo- ja lähtöasetukset. Tässä käytämme AN0-nastaa ADC-arvon lukemiseen ja PORTD-nastat PWM-signaalien lähettämiseen. Joten aloita ne lähtötapina ja tee niistä matala käyttämällä alla olevia koodirivejä.
/ ***** I / O- porttien määritykset ****** / TRISD = 0x00; // Ohjaa MCU: ta, että kaikki portin D nastat ovat PORTD = 0x00; // Alusta kaikki nastat kohtaan 0 / *********** ______ *********** /
Infinite while -silmukan sisällä meidän on laskettava aika-arvo (T_ON) käyttöjaksosta. Ajoissa ja velvollisuus sykli vaihtelee asennosta POT niin teemme sen toistuvasti sisällä , kun silmukan, kuten on esitetty alla. 0,0976 on arvo, joka on kerrottava 1024: llä 100: n saamiseksi ja T_ON-arvon laskemiseksi olemme kertoneet sen 10: llä saadaksesi arvon millisekunnissa.
kun (1) { POT_val = (ADC_Lue (0)); // Lue POT: n arvo käyttämällä ADC Duty_cycle = (POT_val * 0.0976); // Kartta 0-1024 - 0-100 T_ON = ((Duty_cycle * T_TOTAL) * 10/100); // Laske Päällä-aika käyttämällä kaavan yksikköä millisekunnissa __viive_ms (100); }
Koska ajastin on asetettu ylivirtaukselle 0,1 ms välein, ajastimen keskeytyspalvelurutiini ISR kutsutaan 0,1 ms välein. Huoltorutiinin sisällä käytämme muuttujaa nimeltä count ja kasvatamme sitä 0,1 ms: n välein. Näin voimme seurata f-aikaa. Jos haluat lisätietoja PIC-mikrokontrollerin keskeytyksistä, seuraa linkkejä
jos (TMR0IF == 1) // Ajastinlippu on lauennut ajastimen ylivuodon vuoksi -> asetettu ylivuotoon 0,1 ms välein { TMR0 = 248; // Lataa ajastin Arvo TMR0IF = 0; // Tyhjennä ajastimen keskeytyslippujen määrä ++; // Laskurin lisäykset 0,1 ms välein -> count / 10 antaa laskennan arvon ms: na }
Lopuksi on aika vaihtaa GPIO-nasta T_ON- ja T_OFF-arvojen perusteella. Meillä on laskentamuuttuja, joka seuraa aikaa millisekunnissa. Joten käytämme tätä muuttujaa tarkistaaksemme, onko aika vähemmän kuin ajoissa , jos kyllä, pidämme GPIO-nastan päällä, muuten sammutamme sen ja pidämme sen pois päältä, kunnes uusi sykli alkaa. Tämä voidaan tehdä vertaamalla sitä yhden PWM-syklin kokonaisaikaan. Sama tekevä koodi näkyy alla
if (määrä <= (T_ON)) // Jos aika on pienempi kuin ajalla RD1 = 1; // Kytke GPIO päälle muu RD1 = 0; // Muuten sammuta GPIO, jos (count> = (T_TOTAL * 10)) // Pidä se pois päältä, kunnes uusi sykli alkaa laskea = 0;
Piirikaavio
Piirikaavio PWM: n tuottamiseksi PIC-mikrokontrollerin GPIO-nastalla on todella yksinkertainen, vain virtaa PIC oskillaattorilla ja kytke potentiometri nastalle AN0 ja servomoottori nastalle RD1, voimme käyttää GPIO-nastaa PWM-signaalin saamiseksi, olen valinnut RD1 vain satunnaisesti. Sekä potentiometri että servomoottori saavat virtaa 5 V: sta, jota ohjataan 7805: stä alla olevan piirikaavion mukaisesti.
Simulointi
Simuloimaan projektia käytin proteus-ohjelmistoni. Rakenna alla esitetty piiri ja linkitä koodi simulaatioosi ja suorita se. Sinun pitäisi saada PWM-signaali RD1 GPIO -nastalle ohjelmamme mukaisesti ja PWM: n käyttöjaksoa tulisi hallita potentiometrin sijainnin perusteella. Alla oleva GIF näyttää kuinka PWM-signaali ja servomoottori reagoivat, kun ADC-arvoa muutetaan potentiometrin kautta.
Laitteiston asetukset servomoottorin ohjaamiseksi PIC-mikrokontrollerilla
Täydellinen laitteistoni kokoonpano näkyy alla, ihmisille, jotka seuraavat opetusohjelmiani, tämän levyn tulisi näyttää tutulta, se on sama levy, jota olen käyttänyt kaikissa tähänastisissa oppaissani. Voit tutustua vilkkuvaan LED-opetusohjelmaan, jos olet kiinnostunut tietämään, miten rakennan sen. Muussa tapauksessa seuraa vain yllä olevaa piirikaaviota ja kaikkien pitäisi toimia hyvin.
Lataa ohjelma ja vaihda potentiometriä, ja sinun pitäisi nähdä servo muuttavan asentoa potentiometrin sijainnin perusteella. Projektin täydellinen työskentely näkyy tämän sivun lopussa olevassa videossa. Toivottavasti ymmärrät projektin ja nautit rakentamisesta. Jos sinulla on tarpeita, voit lähettää ne foorumille ja yritän parhaani vastata.
Aion viedä tämän projektin eteenpäin lisäämällä vaihtoehtoja useiden servomoottoreiden ohjaamiseksi ja siten rakentamalla siitä robottivarren, samanlainen kuin jo rakentamamme Arduino-robottivarsi. Joten siihen asti nähdä!