- Miért időzítő, ha késés van ()?
- PIC mikrokontroller időzítők:
- Programozás és munka Magyarázat:
- Áramkör diagram és Proteus szimuláció:
Ez lesz az ötödik oktatóanyag a PIC oktatósorozatunkban, amely segít megtanulni és használni az időzítőket a PIC16F877A-ban. Korábbi oktatóinkban a PIC és az MPLABX IDE bevezetésével kezdtük, majd megírtuk az első PIC programunkat, amely a PIC segítségével villogtatta a LED-et, majd a PIC mikrokontroller késleltetési funkciójának használatával készítettünk egy LED villogó szekvenciát. Most használjuk ugyanazt a LED villogó sorrendet, amelyet a korábbi oktató hardverekben használtunk, és ezzel megtanuljuk, hogyan kell használni az időzítőket a PIC MCU-ban. Éppen most hozzáadtunk még egy gombot a LED táblában ehhez az oktatóanyaghoz. Menjen végig az oktatóanyagon, és tudjon meg többet.
Az időzítők a beágyazott programozó egyik fontos munkalova. Minden általunk tervezett alkalmazás valahogyan magában foglal egy időzítő alkalmazást, például valamilyen be- vagy kikapcsolása egy meghatározott idő után. Oké, de miért van szükségünk időzítőkre, amikor már vannak késleltető makrók (__delay_ms ()), amelyek ugyanazt csinálják !!
Miért időzítő, ha késés van ()?
A Delay makrót „dump” késleltetésnek nevezzük. Mivel a Késleltetés funkció végrehajtása során az MCU csak a késleltetés létrehozásával ül ki a dumpban. E folyamat során az MCU nem hallgathatja meg az ADC értékeit, és nem olvashat el semmit a nyilvántartásaiból. Ezért nem tanácsos a Késleltetés funkciókat használni, kivéve az olyan alkalmazásokat, mint a LED villogása, ahol az Időkésésnek nem kell pontosnak vagy hosszúnak lennie.
A késleltető makrók a következő rövid időn belül jönnek:
- A késleltetés értékének állandónak kell lennie a késleltetési makróknál; a program futtatása során nem változtatható meg. Ezért továbbra is programozó definiálva van.
- A késés nem lesz pontos az Időzítők használatához képest.
- A késések nagyobb értékei nem hozhatók létre makrókkal, például félórás késést nem lehet késleltető makrókkal létrehozni. A maximálisan használható késés az alkalmazott Crystal oszcillátoron alapul.
PIC mikrokontroller időzítők:
Fizikailag az időzítő egy olyan regiszter, amelynek értéke folyamatosan 255-ig növekszik, és akkor kezdődik elölről: 0, 1, 2, 3, 4… 255…. 0, 1, 2, 3……stb.
A PIC16F877A PIC MCU három időzítő modullal rendelkezik. Timer0, Timer1 és Timer2 nevek. A Timer 0 és a Timer 2 8 bites Timer, az Timer 1 pedig egy 16 bites Timer. Ebben az oktatóanyagban a Timer 0-t fogjuk használni alkalmazásunkhoz. Miután megértettük a 0-as időzítőt, könnyű lesz dolgozni az 1-es és 2-es időzítőn is.
A Timer0 modul időzítője / számlálója a következő tulajdonságokkal rendelkezik:
- 8 bites időzítő / számláló
- Olvasható és írható
- 8 bites szoftverrel programozható előmérlegelő
- Belső vagy külső óra kiválasztása
- Megszakítás az FFh-ról 00h-ra történő túlcsorduláskor
- Él kiválasztása a külső órához
Az időzítő használatának megértéséhez meg kell értenünk néhány olyan divatos kifejezést, mint a 8 bites / 16 bites időzítő, az Prescaler, az Időzítő megszakítások és a Focs. Most nézzük meg, mit is jelentenek mindegyikük valójában. Mint korábban említettük, mind a 8, mind a 16 bites időzítők vannak a PIC MCU-ban, a fő különbség közöttük az, hogy a 16 bites időzítő sokkal jobb felbontású, mint a 8 bites időzítő.
Az előmérő egy olyan mikrovezérlő része, amely felosztja az oszcillátor óráját, mielőtt elérné az időzítő állapotát növelő logikát. Az előfeszítő id-tartománya 1 és 256 között van, és az előfeszítő értékét az OPTION regisztráció segítségével állíthatjuk be (ugyanazt, amelyet felhúzó ellenállásokhoz használtunk). Például ha az érték az előosztó 64, akkor minden 64 th impulzus a időzítő lépteti 1.
Amint az időzítő növekszik, és amikor eléri a 255-ös maximális értéket, megszakítást indít és újra 0-ra inicializálja magát. Ezt a megszakítást időzítő megszakításnak hívják. Ez a megszakítás arról tájékoztatja az MCU-t, hogy ez a bizonyos idő letelt.
A Fosc az oszcillátor frekvenciáját jelenti, ez az alkalmazott kristály frekvenciája. Az időzítő regisztrációhoz szükséges idő függ a Prescaler és az Fosc értékétől.
Programozás és munka Magyarázat:
Ebben az oktatóanyagban két gombot állítunk be két bemenetként és 8 LED-et 8 kimenetként. Az első gombbal állíthatja be az időkésleltetést (500 ms minden nyomásra), a második gombbal pedig elindíthatja az időzítő villogását. Például, ha az első gombot háromszor lenyomják (500 * 3 = 1500ms), akkor a késleltetés 1,5 másodpercre lesz állítva, és amikor a kettő gombot megnyomják, minden LED be- és kikapcsol az előre meghatározott késleltetéssel. Ellenőrizze a bemutató végén található bemutató videót.
Most, hogy ezeket az alapokat az arra nézzük meg a program végén közölt a kód részben.
Nem baj, ha nem kaptad meg a programot, de ha igen! Adj magadnak egy sütit, és dobd ki a programot, hogy élvezhesd a kimenetedet. Mások számára a programot értelmes részekre bontom, és elmagyarázom, mi történik az egyes blokkokban.
Mint mindig, a kód első néhány sora a Konfigurációs beállítások és a fejlécfájlok, ezért nem fogom ezt elmagyarázni, mivel a korábbi oktatóanyagoknál már megtettem.
Ezután hagyjuk ki az összes sort, és ugorjunk egyenesen a void főfunkcióba, amelyen belül a Timer0 PORT konfigurációja van.
void main () {/ ***** 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 = 100 értéket is; // 0,0019968s időértékének betöltése; 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 / *********** ______ *********** /
Ennek megértéséhez meg kell vizsgálnunk az OPTION regisztrációt a PIC adatlapunkon.
Amint azt az előző bemutatóban tárgyaltuk, a 7-es bitet a gyenge felhúzási ellenállás engedélyezésére használják a PORTB számára. Nézze meg a fenti ábrát, a 3. bit 0-ra van állítva, hogy utasítsa az MCU-t, hogy a következő beállított előmérőt használja az időzítőhöz, és ne a WatchDogTimer (WDT) -hez. Az időzítő mód kiválasztása az 5 T0CS bit törlésével történik
(OPTION_REG <5>)
Most a bits2-0- t használjuk az időmérő előmérőjének beállításához. Amint azt a fenti táblázat mutatja, az előskálázó 64-es értékének beállításához a biteket 101-nek kell beállítani.
Ezután nézzük meg a Timer0-hoz társított regisztereket
Az időzítő növekszik, miután beállította és túlcsordult, miután elérte a 256-os értéket, az időzítő megszakításának engedélyezéséhez ezen a ponton a TMR0IE regisztert magasra kell állítani. Mivel a 0 időzítő maga egy periféria, engedélyeznünk kell a perifériás megszakítást a PEIE = 1 értékkel. Végül engedélyeznünk kell a globális megszakítást, hogy az MCU értesítést kapjon a megszakításról bármely művelet során, ez a GIE = 1 értékre kerül.
Késleltetés = ((256-REG_val) * (Prescal * 4)) / Fosc
A fenti képletet használjuk a Késés értékének kiszámításához.
Hol
REG_érték = 100;
Prescal = 64
Fosc = 20000000
Ez a számítás során
Késés = 0,0019968 s
A következő sorkészlet az I / O portok beállítása.
/ ***** I / O portkonfiguráció ****** / TRISB0 = 1; // Utasítsa az MCU-t, hogy a PORTB 0 tűt használja az 1. gomb bemenetéhez. TRISB1 = 1; // Utasítsa az MCU-t, hogy a PORTB 1 tűt használja az 1. gomb bemenetéhez. TRISD = 0x00; // utasítsa az MCU-t, hogy a D PORT összes csapja PORTD = 0x00 legyen; // Inicializálja az összes csapot 0-ra / *********** ______ *********** /
Ez megegyezik az előző oktatóanyagunkkal, mivel ugyanazt a hardvert használjuk. Kivéve, hogy bevittünk egy másik gombot. Ezt a TRISB1 = 1 sor végzi.
Ezután kifordítva végtelen míg hurok van két kód blokkokat. Az egyik arra szolgál, hogy az időzítő bemenetét megkapja a felhasználó, a másikat pedig a késleltetéssorozat végrehajtására használja a LED-ek felett. Azzal magyaráztam őket, hogy megjegyzéseket használtam az egyes sorokhoz.
míg (1) {számít = 0; // Ne futtassa az időzítőt a fő hurokban // ******* A számkésleltetést a **** felhasználótól kapja // ////// if (RB0 == 0 && flag == 0) // Mikor megadott bemenet: {get_scnds + = 1; // get_scnds = get_scnds + http: // Inkrement változó zászló = 1; } if (RB0 == 1) // A folyamatos növekmény megakadályozása érdekében flag = 0; / *********** ______ *********** /
A get_scnds nevű változó minden egyes alkalommal növekszik, amikor a felhasználó megnyomja az 1 gombot. Egy zászló (szoftver által definiált) változót használnak az inkrementálási folyamat tartására, amíg a felhasználó eltávolítja az ujját a gombról.
// ******* A szekvencia végrehajtása késéssel **** ////// while (RB1 == 0) {PORTD = 0b00000001 <
A következő blokk működésbe lép, ha megnyomják a kettes gombot. Mivel a felhasználó az első gombbal már meghatározta a szükséges késleltetést, és el lett mentve a get_scnds változóban . Hscnd nevű változót használunk, ezt a változót az ISR (Interrupt service rutin) vezérli.
A megszakítási szolgáltatás rutin egy megszakítás, amelyet minden alkalommal meghívunk, amikor a Timer0 túlcsordul. Lássuk, hogyan vezérli azt az ISR a következő blokkban, mintha minden késleltetésnél fél másodperccel (0,5 másodperccel) szeretnénk növelni az időkésleltetést, majd fél másodpercenként növelnünk kell a hscnd változót. Mivel időzítőnket túlfolyásra programoztuk minden 0,0019968 másodpercre (~ 2ms), így a fél másodperc számlálásának a változónak 250-nek kell lennie, mert 250 * 2ms = 0,5 másodperc. Tehát, amikor a számlálás értéke 250 (250 * 2ms = 0,5 másodperc), az azt jelenti, hogy annak fél másodpercje volt, ezért a hscnd értékét 1- gyel növeljük , és a számlálást nullára inicializáljuk.
void megszakítás timer_isr () {if (TMR0IF == 1) // Az időzítő jelzőt az időzítő túlcsordulása miatt aktiválták {TMR0 = 100; // Az időzítő betöltése: TMR0IF = 0; // Az időzítő megszakításának jelzőszámának törlése ++; } if (szám = = 250) {hscnd + = 1; // a hscnd minden fél másodperc számlálásakor növekszik = 0; }}
Tehát ezt az értéket használjuk és összehasonlítjuk a hscnd-vel, és eltoljuk a LED-et a felhasználó által megadott idő alapján. Ez is nagyon hasonlít az utolsó bemutatóhoz.
Ez az, hogy a programunkat megértsük és működjünk.
Áramkör diagram és Proteus szimuláció:
Mint általában, először a Proteus használatával ellenőrizhetjük a kimenetet, ide kapcsoltam a Proteus sematikus fájljait.
Adjon hozzá egy gombot az előző LED-kártyánkhoz, és hardverünk készen áll a használatra. Valahogy így kell kinéznie:
A kapcsolat létrejötte után töltse fel a kódot, és ellenőrizze a kimenetet. Ha bármilyen problémája van, kérjük, használja a megjegyzések részt. Ellenőrizze az alábbi videót az egész folyamat megértéséhez.