Fórum témák

» Több friss téma
Cikkek » PicKit3 Debug Express - Tananyag kezdőknek II.rész
PicKit3 Debug Express - Tananyag kezdőknek II.rész
Szerző: zimpee, idő: Okt 25, 2011, Olvasva: 12112, Oldal olvasási idő: kb. 4 perc
Lapozás: OK   4 / 5

Ebben a leckében a Timer0-t használjuk a LEDek léptetésére számlálóciklusok helyett. A nyomógombbal a léptetés irányát változtathatjuk.

Fájlok ITT.

Megismerjük:
 - a hardveres timert, ami órajelet vagy külső eseményeket számol,
 - ennek előnyeit a delay ciklusokkal szemben,
 - az előosztó használatát, melynek segítségével megadjuk, hány órajelet számoljon egynek a timerünk.
 
A Timer0 a PIC18F45K20 időzítő/számláló perifériája, mellyel akár külső eseményeket is számolhatunk a T0CKI lábon. 8 és 16 bites üzemmódja létezik, tehát 0-tól 255-ig, vagy 0-tól 65535-ig tud számolni. Ha a számláló túlcsordul, beállít egy flaget, amelyet polling módszerrel vizsgálhatunk.
A Timer0 része egy előosztó (prescaler), amely a számláló elérése előtt osztja az órajelet. 1:1-es előosztót használva a timer egyet ugrik minden utasításórajelre (Ami, mint azt már megtanultuk, az oszcillátor órajelének negyede). 1:8 előosztásnál minden 8 utasításórajelre számol egyet az időzítő. Bármikor írjuk a timert, az előosztó törlődik.

Ha a Timer0-t 16 bites módban használjuk, az időzítő értékének írása és olvasása kicsit bonyolultabb: A 16 bites értékünként. TMR0H akkor frissül, amikor TMR0L-t olvassuk,k alsó bájtját a TMR0L SFR-en keresztül írhatjuk és olvashatjuk. A felső bájt azonban nem érhető el direkt, hanem a TMR0H SFR-ben tartja a vezérlő puffer vagy írjuk. Ha TMR0L-t írjuk, akkor íródik meg a tényleges TMR0H a felső bájtba. Így egyszerre tudjuk olvasni a teljes 16 bites értéket. Tehát, ha olvasni szeretnénk a Timer0 számlálóját, először az alsó bájtot kell olvasnunk, utána a felsőt. Ha írni szeretnénk, akkor először a felsőt írjuk, utána az alsót.
A Timer0-t a T0CON SFR-en keresztül vezérelhetjük.



Ahhoz, hogy a Timer0 leválthassa a softwares delayünket, úgy kell beállítanunk, hogy 2-300 ms-ként túlcsorduljon. A T0CON SFR-ben ezt így állíthatjuk be:

- T08BIT = 0
    Timer0 16 bites, hogy bemutathassuk a TMR0H pufferelését.
- T0CS = 0
    Timer0 a belső utasításciklusról fut. Fosc=1MHz esetén ez 250kHz-et jelent.
- T0SE = 0
    Ha a Timer0 a T0CKI lábról futna, ezzel állítanánk be, hogy fel-, vagy lefutó élre számoljunk. Mivel mi ezt most nem használjuk, ez a bit számunkra nem érdekes (Házi feladat!). Ezt a szakszöveg "Don't care"-nek mondja, és a beállításainkat ez a bit nem változtatja meg.
- PSA = 1
    A timer 65536 számolás után túlcsordul. 250kHz-en ez azt jelenti, hogy minden 65536 *(1/250000) = 262 ms-enként. Ez az idő nekünk megfelelő, szóval nem kell előosztót beállítanunk.
- T0PS2:T0PS0 = 000
    Mivel nem használunk előosztót ezek a rész "don't care".
- TMR0ON = 0
    Ezzel a bittel kapcsolhatjuk be és ki az időzítőnket. Most kikapcsoljuk, mivel majd a beállítás után indítjuk el.

Ezen beállítások használatához írjuk a 0b00001000 értéket a T0CON-ba.
(A PIC18F45K20 további 2 beállítható időzítővel rendelkezik. Ezekről bővebben a vezérlő adatlapjában olvashatsz)

Nyissuk meg a forráskódot, és böngésszük végig! Vegyük észre, hogy a 05 Timer.h-ban létrehozunk két új típust:

    typedef enum { LEFT2RIGHT, RIGHT2LEFT} LEDDirections;
    typedef enum { FALSE, True} BOOL;


Ezekkel a típusokkal deklarálhatunk új változókat a main() függvényben:

    LEDDirections Direction = LEFT2RIGHT;
    BOOL SwitchPressed = FALSE;

A Direction változóban tároljuk a LEDek forgásirányát, a SwitchPressed figyeli, hogy megnyomtuk-e a gombot. A gombnyomással a LEDek forgásirányát változtathatjuk.

A következő kód állítja be a while(1) ciklus előtt a Timer0 modult:

// Init Timer
INTCONbits.TMR0IF = 0;        // 1. sor
T0CON = 0b00001000;            // 2. sor
// T0CON = 0b00000001; (ignore commented line for now)
TMR0H = 0;                     // 3. sor
TMR0L = 0;                     // 4. sor
T0CONbits.TMR0ON = 1;         // 5. sor


Nézzük végig a számozott sorokat, mit is csinálunk pontosan!
Az 1. sorban töröljük a TMR0IF flaget az INTCON SFR-ben. Ez a flag lesz beállítva mindig, amikor az időzítő túlcsordul, tehát ezt fogjuk folyamatosan lekérdezni, hogy megtudjuk, mikor kell léptetni a LEDeket. Ez a bit nem törlődik hardveresen, nekünk kell törölnünk azt, hogy a timerünk rendben fusson.
A 2. sor a korábban tárgyalt beállításokat tölti a T0CON regiszterbe.
A 3. sorban töröljük a TMR0H buffert. Emlékezzünk, ez csak a felső bájtja a számlálónak! A 0 érték csak akkor íródik be, amikor az alsót is beírjuk!
A 4. sorban töröljük a TMR0L regisztert, amivel a vezérlőnk törli a TMR0H-t is. Tehát a teljes 16 bites időzítőnk a 0x0000 értékkel lesz megtöltve.
Az 5. sor beállítja a TME0ON bitet a T0CON regiszterben, így bekapcsolja az időzítőt, ami elkezd számolni. A T0CONbits.TMR0ON SFR bit használatával ezt tudjuk be- és kikapcsolni a többi érték megváltoztatása nélkül.

Figyelem! Néhány esetben ezen SFR uniók használata hatással van más bitekre! Pontosabban az történik, hogy az utasítás alatt a bitet olvassuk, újra beállítjuk, és ekkor a teljes regiszter újraíródik. Ezt Read-Modify-Write-nak hívja a szaknyelv. Ha egy bit más értéket ad vissza, mint amire utoljára beállítottuk, az hatással lehet a regiszter más bitjeire is. Nézzük át alaposan az SFR bitek leírását! A T0CON esetében minden bitet szoftverből állítunk, a hardver nem fog hozzányúlni a regiszterhez.

A while(1) ciklusban a LED_Display változót beállítjuk, hogy az '1' bitet léptesse a Direction változó tartalmának megfelelően, majd frissítse a kijelzőt (LATD).
A do{...} while() ciklus ezek után megnézi a kapcsolót, hogy történt-e gombnyomás, amíg a timer túlcsordulására várunk. Ez egyszerű példája annak, hogy segíti a timer a vezérlő gyors működését: Nem kell számítási teljesítményt áldozni arra, hogy teljen az idő, közben tudunk fontosabb dolgokkal foglalkozni.
Ha megnyomjuk a gombot, a Direction változó értéke megváltozik. A do{...}while() ciklus if-else if ágát figyelve láthatjuk, hogyan történik mindez.

Végül, amikor a Timer0 túlcsordul, és beállítja a TMR0IF flaget, a do{...}while() ciklus kilép, A TMR0IF-et töröljük szoftverből, és előlről kezdjük az egészet.

Fordítsuk le, és égessük be a programot a demópanelünk vezérlőjébe! A futófény futni fog, a gombbal pedig az irányt változtatjuk meg.

Az előosztó

Menjünk csak vissza a Timer0 beállításaihoz! Mi az a kommentezett sor? Vegyük ki a kommentet, és nézzük meg, mi változott!

- PSA = 0
    Az előosztót most bekapcsoltuk, és a T0PSx értéke fogja beállítani az osztást.
- T0PS2:T0PS0 = 001
    Ezzel az értékkel az előosztót 1:4-re állítjuk, tehát az időzítőnk minden negyedik utasítást fogja számolni. Tehát pontosan négyszer annyi időbe telik elszámolni 65536-ig, és, ha megnézzük, ez már több, mint egy másodperc!
   
Fordítsuk le újra a forráskódot, és égessük be! A LEDek pontosan négyszer olyan lassan fognak változni.


A cikk még nem ért véget, lapozz!
Következő: »»   4 / 5
Értékeléshez bejelentkezés szükséges!
Bejelentkezés

Belépés

Hirdetés
XDT.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem