AVR Timers – PWM Mode-Part II

AVR Seriestämä artikkeli on jatkoa aiemmalle PWM Postille. Opi ohjelmoimaan ajastimet toimimaan PWM-tilassa! Aloitetaan!

Hello folks! Pitkästä aikaa! 🙂

edellisessä postauksessani olemme käsitelleet PWM: n peruskäsitteitä. Tehdään ensin Yhteenveto.:

  • PWM tarkoittaa Pulssinleveysmodulaatiota.
  • se voidaan tuottaa vertaamalla ennalta määrättyä aaltomuotoa viitejännitetasoon tai tekemällä yksinkertaisia analogisia piirejä.
  • PWM-aaltomuodon toimintasuhde saadaan seuraavasta relaatiosta.
toimintasuhde
  • on olemassa kolme tilaa PWM TOIMINTA-Nopea PWM, vaihe oikea PWM ja taajuus ja vaihe oikea PWM
  • Miten valita ajastin, toimintatila ja vertailla lähtö tila tuottaa halutun PWM.
joten nyt, ilman suurempia ongelmia, katsotaan, miten se toteutetaan AVR-mikrokontrollereilla. Ennen kuin jatkamme, ehdotan, että käyt läpi aiemmat viestini ajastimista ja PWM: stä.

Otetaanpa ongelmalausunto. Meidän on luotava 50 Hz: n PWM-signaali, jonka toimintasuhde on 45%.

analyysi

ottaen huomioon, että

Frequency = 50 Hz

toisin sanoen aikajakso, T

T = T(on) + T(off) = 1/50 = 0.02 s = 20 ms

myös, ottaen huomioon, että

Duty Cycle = 45%

näin ollen, ratkaisemalla edellä esitetyn yhtälön mukaisesti, saamme

T(on) = 9 msT(off) = 11 ms

nyt, tämä voi olla saavutettu kahdella tavalla:

  1. Käytä ajastinta CTC-tilassa
  2. Käytä ajastinta PWM – tilassa

metodologia-CTC-tilassa

Okei, joten en kirjoita tähän mitään koodia (vain pseudokoodia). Oletan, että kun olet lukenut aiemmat viestini, olet tarpeeksi fiksu kirjoittamaan yhden itse! Keskustelemme vain käsitteistä.

valitse ensin sopiva ajastin. Tämän sovelluksen, voimme valita minkä tahansa kolmesta ajastimet saatavilla ATMEGA32. Valitse sopiva prescaler. Aseta sitten ajastin ja jatka normaalisti. Saalis piilee tässä on, että sinun täytyy päivittää verrata arvo OCRx register everytime. Yhtä tällaista tapaa käsitellään alla olevassa pseudokoodissa.

tämä on analoginen perinteisen LED-Välähdyksen kanssa, paitsi että on-ja off-ajat ovat erilaiset.

pseudokoodi

#include <avr/io.h>#include <avr/interrupt.h> uint8_t count = 0; // global counter // initialize timer, interrupt and variablevoid timerX_init(){ // set up timerX with suitable prescaler and CTC mode // initialize counter // initialize compare value // enable compare interrupt // enable global interrupts} // process the ISR that is firedISR (TIMERx_COMPA_vect){ // do whatever you want to do here // say, increment the global counter count++; // check for the global counter // if count == odd, delay required = 11 ms // if count == even, delay required = 9 ms // thus, the value of the OCRx should be constantly updated if (count % 2 == 0) OCRx = 9999; // calculate and substitute appropriate value else OCRx = 10999; // calculate and substitute appropriate value} int main(void){ // initialize the output pin, say PC0 DDRC |= (1 << 0); // initialize timerX timerX_init(); // loop forever while(1) { // do nothing }}

nyt tämä on yksi menetelmä. Ja se on hyvin tehotonta. Voit lisätä sen tehokkuutta kirjoittamalla paremman C-koodin (syntaksiltaan), mutta käsite pysyy samana. Jos sinulla on jokin muu menetelmä/konsepti, olet tervetullut jakamaan sen täällä! 🙂

päivitys: yksi maxembeddedin lukijoista, ”coolpales” on kirjoittanut tämän koodin, ja se toimi hänelle.

huomaa, että tätä koodia ei ole vielä testattu! Joten, jos joku teistä on kokeilla sitä, älä lähetä tuloksia täällä, olisin iloinen nähdä ne! 🙂

metodologia-PWM-moodi

Okei, joten nyt tutustutaan PWM-moodiin. AVR: n PWM-tila on laitteistoohjattu. Tämä tarkoittaa, että kaikki, kaikella tarkoitan ”kaikki”, tehdään AVR-suorittimella. Kaikki mitä sinun tarvitsee tehdä on alustaa ja käynnistää ajastin, ja asettaa toimintasyklin! Siistiä, vai mitä?! Opetellaan miten!

tässä olen käyttänyt atmega32: n Timer0: tä demonstraatioon. Voit valita minkä tahansa muun ajastimen tai AVR mikrokontrollerin. Katsotaanpa rekistereitä.

TCCR0-Timer / Counter0 Control Register

olemme törmänneet tähän rekisteriin Timer0-tutoriaalissani. Tässä, opimme, miten asettaa asianmukaiset bitit ajaa ajastin PWM tilassa.

TCCR0-Rekisteri

TCCR0-Rekisteri

käsittelemme vain niitä bittejä, jotka meitä nyt kiinnostavat.

  • bitti 6,3-WGM01: 0 – aaltomuodon Generointitila – nämä bitit voidaan asettaa joko ”00” tai ”01” riippuen siitä, millaisen PWM: n haluat luoda. Katso ylös.
    aaltomuodon Generointitilan Bittikuvaus

    aaltomuodon Generointitilan Bittikuvaus

  • Bit 5,4-COM01:0 – vertaa Match Output Mode – Nämä bitit on asetettu ohjaamaan käyttäytymistä Output Compare pin (OC0, pin 4 in ATMEGA32) mukaisesti WGM01: 0 bittiä. Seuraavassa hakutaulukossa määritetään OC0-pin: n toiminnot nopeaa PWM-tilaa varten.
    vertaa Lähtötilaa, nopea PWM-tila

    vertaa Lähtötilaa, nopea PWM-tila

    nyt katsotaan nopeita PWM-aaltomuotoja. Yksityiskohtainen selitys löytyy minun edellinen opetusohjelma.

    nopea PWM

    nopea PWM

    nyt Saanen muistuttaa, että AVR PWM on täysin laitteistoohjattu, eli ajastinvertailunkin hoitaa AVR-suoritin. Kaikki mitä meidän tarvitsee tehdä on kertoa CPU mitä tehdä, kun ottelu tapahtuu. COM01: 0 nastat tulevat peliin täällä. Näemme, että asettamalla sen ”10” tai ”11”, lähtö pin OC0 on joko asetettu tai selvitetty (toisin sanoen, se määrittää, onko PWM on ylösalaisin tilassa, tai ei-käänteinen tila).

    vastaavasti Vaihekorjatun PWM: n kohdalla Katso ylös-taulukko ja aaltomuodot menevät näin.

     vertaa Lähtötilaa, Vaihekorjattu PWM-tila

    vertaa Lähtötilaa, Vaihekorjattu PWM-tila

    vaiherikas PWM

    vaiherikas PWM

    täälläkin com01:0: n asettaminen arvoon ”10” tai ”11” määrää OC0-pin: n käyttäytymisen. Kuten aaltomuodot osoittavat, on olemassa kaksi esiintymää-yksi aikana ylös-laskenta, ja muut aikana alas-laskenta. Käyttäytyminen on kuvattu selvästi Katso ylös-taulukossa.

    huomaa, että OC0 on tulostusnappi. Näin ollen WGM: n ja COM: n vaikutukset eivät tule kuvaan, ellei DDRx-rekisteriä ole asetettu oikein. Katso lisätietoja tästä opetusohjelmasta.

  • Bit 2:0 – CS02: 0 – Clock Select Bits – näitä bittejä käsitellään jo Timer0-opetusohjelmassa.

OCR0-Lähtövertailurekisteri

olemme törmänneet jopa tähän rekisteriin Timer0-tutoriaalissani. Käytämme tätä rekisteriä vertailuarvon tallentamiseen. Mutta kun käytämme Timer0 PWM-tilassa, siihen tallennettu arvo toimii toimintasyklinä (tietenkin!). Ongelmalausekkeessa sen huomioiden, että toimintasuhde on 45% eli

OCR0 = 45% of 255 = 114.75 = 115

ja se siitä! Nyt olemme valmiita kirjoittamaan sille koodin! 🙂

Edit: Note

seuraavassa koodissa käsitellään sitä, miten luodaan halutun toimintasyklin PWM-signaali. Jos haluat muuttaa sen taajuus, sinun täytyy muuttaa alkuun arvo, joka voidaan tehdä käyttämällä ICRx register (joka ei tue 8-bittinen ajastimet). 16-bittiselle Timer1: lle sitä voidaan vaihdella ICR1A: n avulla. keskustelen tästä pian, kun keskustelemme servo-ohjauksesta.

koodi

joten tässä menee koodi. Jos haluat lisätietoja I / O-satamatoiminnoista AVR: ssä, katso tämä. Tietää vähän manipulointia, katso tätä. Jos haluat oppia käyttämään AVR Studio 5: tä, katso tämä. Jos haluat tietää, miten tämä koodi on jäsennetty, katso edellinen TIMER0 viesti.

#include <avr/io.h>#include <util/delay.h>void pwm_init(){ // initialize TCCR0 as per requirement, say as follows TCCR0 |= (1<<WGM00)|(1<<COM01)|(1<<WGM01)|(1<<CS00); // make sure to make OC0 pin (pin PB3 for atmega32) as output pin DDRB |= (1<<PB3);} void main(){ uint8_t duty; duty = 115; // duty cycle = 45% of 255 = 114.75 = 115 // initialize timer in PWM mode pwm_init(); // run forever while(1) { OCR0 = duty; }}

Ongelmalausunto

joten otetaan nyt toinen ongelmalausunto. Tämä tulee olemaan enemmän käytännön tavaraa kuin edellinen!

otetaan perinteinen LED-vilkkulaite, jossa on räpytettävä lediä tietyllä taajuudella. Mutta Hei, odota, emmekö keskustelleet siitä kauan sitten tässä viestissä (selaa alaspäin loppua kohti)? Hmm, joten muokataan sitä niin, että se sisältää PWM: n. Toisin kuin perinteinen LED flasher (jossa ledit ovat joko päällä tai pois päältä), antaa sen hehkua suurin kirkkaus, ja sitten hitaasti vähentää sen kirkkautta, kunnes se saavuttaa nolla, ja sitten taas lisätä sen kirkkautta hitaasti, kunnes se tulee suurin.

analyysi ja koodi

Joten miten se tehdään? Arvasit oikein! Vähennä toimintasykliä hitaasti 255: stä nollaan ja nosta sitä sitten nollasta 255: een. Käyttöjaksosta riippuen LEDiin kohdistettu jännite vaihtelee, ja siten kirkkaus. Seuraava kaava antaa jännitteen ja käyttösyklin suhteen.

v_out yhtälö

joten tässä menee koodi. En selitä, voit purkaa sen itse. Jos haluat lisätietoja I / O-satamatoiminnoista AVR: ssä, katso tämä. Tietää vähän manipulointia, katso tätä. Jos haluat oppia käyttämään AVR Studio 5: tä, katso tämä. Jos haluat tietää, miten tämä koodi on jäsennetty, katso edellinen TIMER0 viesti.

// program to change brightness of an LED// demonstration of PWM #include <avr/io.h>#include <util/delay.h> // initialize PWMvoid pwm_init(){ // initialize timer0 in PWM mode TCCR0 |= (1<<WGM00)|(1<<COM01)|(1<<WGM01)|(1<<CS00); // make sure to make OC0 pin (pin PB3 for atmega32) as output pin DDRB |= (1<<PB3);} void main(){ uint8_t brightness; // initialize timer0 in PWM mode pwm_init(); // run forever while(1) { // increasing brightness for (brightness = 0; brightness < 255; ++brightness) { // set the brightness as duty cycle OCR0 = brightness; // delay so as to make the user "see" the change in brightness _delay_ms(10); } // decreasing brightness for (brightness = 255; brightness > 0; --brightness) { // set the brightness as duty cycle OCR0 = brightness; // delay so as to make the user "see" the change in brightness _delay_ms(10); } // repeat this forever }}

näin päättyy toinen paljon odotettu ja pitkä opetusohjelma! Seuraava.. Sarjaviestintä! Nähdään!! 🙂

ja kyllä, jos sinulla on ehdotuksia, epäilyksiä, rakentavaa kritiikkiä jne, Olet erittäin tervetullut pudottamaan nuotin alle! Tilaa blogini tai napata RSS-syötteet pysyä ajan tasalla!

Write a Comment

Sähköpostiosoitettasi ei julkaista.