- Miksi ajastin, kun meillä on viive ()?
- PIC-mikrokontrollerin ajastimet:
- Ohjelmointi ja toiminta Selitys:
- Piirikaavio ja Proteus-simulointi:
Tämä on viides opetusohjelma PIC Tutorial -sarjassa, joka auttaa sinua oppimaan ja käyttämään ajastimia PIC16F877A: ssa. Aikaisemmissa opetusohjelmissamme olimme aloittaneet PIC- ja MPLABX IDE -tutkimuksen, sitten kirjoitimme ensimmäisen PIC-ohjelmamme vilkkumaan LED-valoa PIC: n avulla ja teimme sitten LED-merkkivalon vilkkumisjärjestyksen käyttämällä PIC-mikrokontrollerin viivetoimintoa. Käytä nyt samaa LED-vilkkumissarjaa, jota olemme käyttäneet edellisessä opetusohjelmassa, ja tämän avulla opimme käyttämään ajastimia PIC MCU: ssa. Olemme juuri lisänneet vielä yhden painikkeen LED-korttiin tähän opetusohjelmaan. Käy läpi opetusohjelma saadaksesi lisätietoja.
Ajastimet ovat yksi upotetun ohjelmoijan tärkeistä työhevosista. Jokaiseen suunnittelemaamme sovellukseen liittyy jotenkin ajoitussovellus, kuten jonkin virran kytkeminen päälle tai pois tietyn ajan kuluttua. Okei, mutta miksi tarvitsemme ajastimia, kun meillä on jo viivästysmakrot (__delay_ms ()) tekemässä samaa!
Miksi ajastin, kun meillä on viive ()?
Viivästysmakroa kutsutaan "viivästykseksi". Koska viivästystoiminnon suorittamisen aikana MCU istuu dumpissa luomalla vain viiveen. Tämän prosessin aikana MCU ei voi kuunnella ADC-arvojaan tai lukea mitään rekisteristään. Siksi ei ole suositeltavaa käyttää viivetoimintoja paitsi sovelluksissa, kuten LED vilkkuu, jos aikaviiveen ei tarvitse olla tarkka tai pitkä.
Viivästysmakroilla on myös seuraavat lyhyet tulot:
- Viiveen arvon on oltava vakio viivemakroille; sitä ei voi muuttaa ohjelman suorituksen aikana. Siksi se on edelleen ohjelmoija määritelty.
- Viive ei ole tarkka verrattuna ajastimien käyttöön.
- Suurempia viiveiden arvoja ei voida luoda makroilla, esimerkiksi puolen tunnin viivettä ei voida luoda viivemakroilla. Suurin mahdollinen viive, joka voidaan käyttää, perustuu käytettyyn Crystal-oskillaattoriin.
PIC-mikrokontrollerin ajastimet:
Fyysisesti ajastin on rekisteri, jonka arvo kasvaa jatkuvasti 255: een, ja sitten se alkaa uudestaan: 0, 1, 2, 3, 4… 255…. 0, 1, 2, 3……jne.
PIC16F877A PIC MCU on kolme Ajastin moduulit. Ne ovat nimiä Ajastin0, Ajastin1 ja Ajastin2. Ajastin 0 ja Ajastin 2 ovat 8-bittisiä ajastimia ja Ajastin 1 on 16-bittinen ajastin. Tässä opetusohjelmassa käytämme ajastinta 0 sovelluksellemme. Kun ymmärrämme ajastimen 0, on helppo työskennellä myös ajastimilla 1 ja 2.
Timer0-moduulin ajastimella / laskurilla on seuraavat ominaisuudet:
- 8-bittinen ajastin / laskuri
- Luettavissa ja kirjoitettavissa
- 8-bittinen ohjelmoitava esilaajennus
- Sisäisen tai ulkoisen kellon valinta
- Keskeytä ylivuotoa FFh: sta 00h: een
- Reunan valinta ulkoiselle kellolle
Ajastimen käytön aloittamiseksi meidän tulisi ymmärtää joitain hienoja termejä, kuten 8-bittinen / 16-bittinen ajastin, Prescaler, Ajastinkeskeytykset ja Focs. Katsotaan nyt, mitä kukin todella tarkoittaa. Kuten aiemmin mainittiin, PIC MCU: ssa on sekä 8-bittisiä että 16-bittisiä ajastimia, tärkein ero niiden välillä on se, että 16-bittisellä ajastimella on paljon parempi resoluutio kuin 8-bittisellä ajastimella.
Prescaler on nimi mikrokontrollerin osalle, joka jakaa oskillaattorin kellon ennen kuin se saavuttaa logiikan, joka lisää ajastimen tilaa. Esikalkkikortin id-alue on välillä 1 - 256, ja esikalkkikortin arvo voidaan asettaa OPTION-rekisterillä (sama, jota käytimme ylösvetovastuksiin). Esimerkiksi jos arvo prescaler on 64, niin jokaiselle 64 : nnen pulssin ajastimen arvoa kasvatetaan 1: llä.
Kun ajastin kasvaa ja kun se saavuttaa maksimiarvonsa 255, se laukaisee keskeytyksen ja alustaa itsensä takaisin nollaksi. Tätä keskeytystä kutsutaan ajastimen keskeytykseksi. Tämä keskeytys ilmoittaa MCU: lle, että kyseinen aika on kulunut.
Fosc tarkoittaa oskillaattorin taajuuden, se on taajuus Crystal käytetty. Ajastinrekisteriin kuluva aika riippuu Prescalerin arvosta ja Fosc-arvosta.
Ohjelmointi ja toiminta Selitys:
Tässä opetusohjelmassa asetamme kaksi painiketta kahdeksi tuloksi ja 8 LED: n 8 ulostuloksi. Ensimmäistä painiketta käytetään aikaviiveen asettamiseen (500 ms jokaiselle painallukselle) ja toista painiketta käytetään ajastimen vilkkumisen aloittamiseen. Esimerkiksi, jos ensimmäistä painiketta painetaan kolmesti (500 * 3 = 1500 ms), viive asetetaan 1,5 sekunniksi ja kun painetaan kahta painiketta, kukin LED syttyy ja sammuu ennalta määritetyllä viiveellä. Tarkista esittelyvideo tämän opetusohjelman lopussa.
Katsokaamme nyt nämä perusteet mielessä Koodi-osan lopussa annettu ohjelmamme.
Se on ok, jos et saanut ohjelmaa, mutta jos sait! Anna itsellesi eväste ja pudota ohjelma nauttimaan tuotoksestasi. Muille aion jakaa ohjelman merkityksellisiin osiin ja selittää sinulle, mitä kussakin lohkossa tapahtuu.
Kuten aina koodin muutamat ensimmäiset rivit ovat kokoonpanoasetukset ja otsikkotiedostot, en aio selittää tätä, koska olen jo tehnyt sen aiemmissa opetusohjelmissani.
Seuraavaksi ohitetaan kaikki linjat ja siirrytään suoraan tyhjään päätoimintoon, jonka sisällä meillä on PORT-kokoonpano ajastimelle0.
void main () {/ ***** Portin määritykset ajastimelle ****** / OPTION_REG = 0b00000101; // Ajastin0 ulkoisella taajuudella ja 64 preskalaarina // Mahdollistaa myös PULL UPs TMR0 = 100; // Lataa aika-arvo 0,0019968s: lle; 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 / *********** ______ *********** /
Tämän ymmärtämiseksi meidän on tarkasteltava PIC-tietolomakkeen OPTION-rekisteriä.
Kuten edellisessä opetusohjelmassa keskusteltiin, bittiä 7 käytetään mahdollistamaan heikko vetovoima PORTB: lle. Katsokaa yllä olevaa kuvaa, bitti 3 on tehty 0 antamaan MCU: lle ohjeet siitä, että seuraavaa asetettavaa esijauhetta tulisi käyttää ajastimeen eikä WatchDogTimeriin (WDT). Ajastintila valitaan tyhjentämällä bitti 5 T0CS
(VALINTA_REG <5>)
Nyt bittiä 2-0 käytetään ajastimen esikalkkaluokan arvon asettamiseen. Kuten yllä olevassa taulukossa on esitetty, esiasennuslaitteen arvoksi asetetaan 64, bitteiksi on asetettava 101.
Seuraavaksi katsotaan Timer0: een liittyvät rekisterit
Ajastin alkaa kasvaa, kun se on asetettu ja ylivuoto saavutettuaan arvon 256, jotta ajastimen keskeytys olisi mahdollista tässä vaiheessa, rekisterin TMR0IE on oltava korkea. Koska ajastin 0 itsessään on oheislaite, meidän on sallittava perifeerinen keskeytys tekemällä PEIE = 1. Lopuksi meidän on sallittava yleinen keskeytys, jotta MCU: lle ilmoitetaan keskeytyksestä minkä tahansa operaation aikana, tämä tehdään tekemällä GIE = 1.
Viive = ((256-REG_val) * (Prescal * 4)) / Fosc
Yllä olevaa kaavaa käytetään viiveen arvon laskemiseen.
Missä
REG_arvo = 100;
Prescal = 64
Fosc = 20000000
Tämä laskennassa antaa
Viive = 0,0019968s
Seuraava linjajoukko on asettaa I / O-portit.
/ ***** I / O-portin kokoonpano ****** / TRISB0 = 1; // Ohje MCU: lle, että PORTB-nastaa 0 käytetään painikkeen 1 tulona. TRISB1 = 1; // Ohje MCU: lle, että PORTB-nastaa 1 käytetään painikkeen 1 tulona. TRISD = 0x00; // Ohjaa MCU: ta, että kaikki portin D nastat ovat PORTD = 0x00; // Alusta kaikki nastat kohtaan 0 / *********** ______ *********** /
Tämä on sama kuin edellisessä opetusohjelmassa, koska käytämme samaa laitteistoa. Paitsi että olemme lisänneet toisen painikkeen syötteeksi. Tämä tapahtuu rivillä TRISB1 = 1.
Seuraavaksi sisäpuolelta ääretön, kun taas silmukka on kaksi koodilohkoa. Yhtä käytetään saamaan ajastintulo käyttäjältä ja toista viivejärjestyksen suorittamiseksi LEDien yli. Olen selittänyt ne käyttämällä kommentteja jokaista riviä vastaan.
kun taas (1) {count = 0; // Älä suorita ajastinta pääsilmukassa // ******* Hae numeroviive käyttäjältä **** ////// if (RB0 == 0 && flag == 0) // Milloin annettu syöttö {get_scnds + = 1; // get_scnds = get_scnds + http: // Inkrementti muuttujan lippu = 1; } if (RB0 == 1) // Jatkuvan kasvun estämiseksi lippu = 0; / *********** ______ *********** /
Muuttujaa nimeltään get_scnds lisätään joka kerta, kun käyttäjä painaa painiketta 1. Lippua (ohjelmistolla määriteltyä) muuttujaa käytetään pitämään lisäysprosessia, kunnes käyttäjä poistaa sormensa painikkeesta.
// ******* Suorita jakso viiveellä **** ////// while (RB1 == 0) {PORTD = 0b00000001 <
Seuraava lohko aktivoituu, jos painetaan kahta painiketta. Koska käyttäjä on jo määrittänyt vaaditun aikaviiveen painikkeella yksi ja se on tallennettu muuttujaan get_scnds. Käytämme muuttujaa nimeltä hscnd, jota muuttujaa ohjaa ISR (Interrupt service rutiini).
Keskeytyspalvelurutiinin on keskeytys, jota kutsutaan joka kerta, kun Timer0 on ylivuotoja. Katsotaanpa, kuinka ISR ohjaa sitä seuraavassa lohkossa, kuten haluamme lisätä aikaviivettä puolella sekunnilla (0,5 s) jokaisella painalluksella, sitten meidän on lisättävä muuttujaa hscnd joka puoli sekuntia. Koska olemme ajastaneet ajastimen ylivirtaamaan jokaista 0,0019968 sekuntia (~ 2 ms) kohti, niin puolen sekunnin laskentamuuttujan laskemisen tulisi olla 250, koska 250 * 2 ms = 0,5 sekuntia. Joten kun laskenta saa 250 (250 * 2ms = 0,5 sekuntia), se tarkoittaa, että se on ollut puoli sekuntia, joten kasvatamme hscnd 1: llä ja aloitamme laskun nollaan.
void keskeytysajastin_isr () {jos (TMR0IF == 1) // Ajastinlippu on lauennut ajastimen ylivuodon vuoksi {TMR0 = 100; // Lataa ajastin Arvo TMR0IF = 0; // Tyhjennä ajastimen keskeytyslippujen määrä ++; } if (laskenta == 250) {hscnd + = 1; // hscnd kasvaa puolen sekunnin kohdalla = 0; }}
Joten käytämme tätä arvoa ja verrataan sitä hscnd: ään ja siirrämme LED- valojamme käyttäjän määrittämän ajan perusteella. Se on myös hyvin samanlainen kuin viimeinen opetusohjelma.
Se on se, että ohjelmamme on ymmärretty ja toimiva.
Piirikaavio ja Proteus-simulointi:
Kuten tavallista, voit tarkistaa lähdön ensin Proteuksella, olen linkittänyt tähän Proteuksen kaaviotiedostot.
Lisää painike edelliseen LED-korttiin ja laitteistomme on käyttövalmis. Sen pitäisi näyttää tältä:
Kun yhteys on muodostettu, lataa koodi ja tarkista lähtö. Jos sinulla on ongelmia, käytä kommenttiosaa. Tarkista myös alla oleva video ymmärtääksesi koko prosessin.