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: 12156, Oldal olvasási idő: kb. 3 perc
Lapozás: OK   2 / 5

3. lecke: Futófény

Ebben a leckében bevezetjük a globális változókat, és létrehozunk egy "shiftregiszter"-t (Ez még nem teljesen az, később lesz igazi is!).
A lecke fájljait ITT töltheted le!


Megtanuljuk:
 - a #pragma udata és a #pragma idata direktívákat statikus változók létrehozásához,
 - #pragma code használatát, melyben a vezérlő által futtatandó kódot tartjuk,
 - A #pragma romdata használatát konstans (csak olvasható) adatok tárolására (a programmemóriában).
 
Kezdésnek nyisd meg a lecke projektjét MPLAB IDE-ben!

Memóriaallokáció:
A 03 Rotate LED.c forrásban beállítunk egy globális változót LED_Number néven, a következőképpen:

/** V A R I A B L E S *************************************************/
#pragma udata // statikus, inicializalatlan valtozot deklaralunk
unsigned char LED_Number;  // 8 bites valtozo

A #pragma udata direktíva jelzi a fordítónak, hogy a következő deklarációk adat változók, melyeket az adatmemóriában kell elhelyezni.

Erre két direktívát használhatunk:
 "udata" -- Kezdőérték nélküli adat. A direktívát követő változók inicializálás nélkül kerülnek be a fájlregiszterekbe.
 "idata" -- Kezdőértékkel ellátott adat. A direktívát követő változók először a programmemóriába kerülnek (értékkel), majd onnan lesznek átmásolva a fájlregiszterekbe, mielőtt a program futása elkezdődik.
 

Ezen deklarációknál megadhatunk egy szekciónevet, melyet a Linker Script SECTION bejegyzése segítségével tesszük a memória egy meghatározott részére. Nézd meg az "MPLAB C18 C Compiler User's Guide" doksit (DS51288) ezzel kapcsolatban! Linker Script nélkül is megadhatunk kezdőcímet, például a LED_Numbert tegyük a 3-as bank elejére:

/** V A R I A B L E S *************************************************/
#pragma udata mysection = 0x300 // statikus, inicializalatlan valtozot deklaralunk
unsigned char LED_Number;  // 8 bites valtozo
AnotherVariable;



Minden további udata vagy idata részben definiált változó a következő címekre kerül, itt például a 16 bites integer AnotherVariable a 0x301 és 0x302 címeken lesz elérhető.
A függvények helyi változói a Sotfware Stackbe kerülnek továbbra is.
A támogatott adattípusokért, méretükért böngészd át az "MPLAB C18 C Compiler User's Guide" (DS51288) doksit!

ROM létrehozása:

A programmemóriában foglalhatunk helyet konstans adatainknak, és persze a programkódnak. Ebben a leckében mindkettőre látunk példát:

/** D E C L A R A T I O N S *******************************************/
// 0x180 cimre konstans adat
#pragma romdata Lesson3_Table = 0x180
const rom unsigned char LED_LookupTable[8] = {0x01, 0x02, 0x04, 0x08,
                                                 0x10, 0x20, 0x40, 0x80};

#pragma code    // mi is fusson?

void main (void)
{



Összefoglalva tehát, két alapvető módszerünk van a programmemória felhasználására:
 - code: programmemória parancsok. Minden ilyen parancs egymást követve kerül be a PIC18F programmemóriájába.
 - romdata: A programmemóriában tárolt adat. A rom kulcsszóval használva a direktívát követő adat a programmemóriában foglal helyet.
 
Ebben a leckében egy konstans tömböt (LED_Lookuptable) használunk, hogy a 0-7 LEDeket reprezentáló számokat bitmintává alakítsuk, melyet a PORTD-re kiírva bekapcsoljuk az adott LED-et. Ezt a konstans tömböt a romdata szekcióban deklaráltuk a rom kulcsszóval. Mivel nincs rá szükség, hogy ezt a tömböt módosítsuk, így megspórolunk egy kis helyet az adatmemóriában az igazi változóknak.
Ne feledjük, hogy most a romdata szekciónak nevet és kezdőcímet (0x180) is adtunk:
#pragma romdata Lesson3_Table = 0x180
Ezek a tetszőleges attribútumok megmondják a fordítónak, hogy mindenképpen az adott címre kerüljük a 8 bájtos kis tömbünk. Ha nem adunk meg címet, a code vagy romdata szekció nem feltétlenül az adott helyre kerül.

Válasszuk ki MPLAB IDE-ben a Project>Build All menüpontot, fordítsuk le a kódot. A View>Program Memory menüpont segítségével megnézhetjük a programmemória lefordított tartalmát. A lecke utasításai a 0x0000 és 0x0146 címek között találhatók.
Mint látható, a tömbünk  0x180-tól 0x186-ig terjed, mint azt fordításkor megadtuk a Linkernek.

A #pragma code direktívával állítottuk be a következő szekciót, mely a main() függvénnyel kezdődik. Mivel nem adtunk meg szekciónevet vagy címet, az utasításokat a Linker az első elérhető helyre teszi. Ha szekciónevet szeretnénk hozzáadni, ugyanúgy járjunk el, mint az adatoknál.

Nézzük hát a forráskódot!

/** V A R I A B L E S *************************************************/
#pragma udata // statikus, inicializalatlan valtozot deklaralunk
unsigned char LED_Number;  // 8 bites valtozo

/** D E C L A R A T I O N S *******************************************/
// 0x180 cimre konstans adat
#pragma romdata Lesson3_Table = 0x180
const rom unsigned char LED_LookupTable[8] = {0x01, 0x02, 0x04, 0x08,
                                                 0x10, 0x20, 0x40, 0x80};

#pragma code    // mi is fusson?

void main (void)
{
    LED_Number = 0;            // init

    TRISD = 0b00000000;         // PORTD  7:0  labak mind kimenetek (0)

    while (1)
    {
        // hasznaljuk a tablat egy-egy LED bekapcsolasahoz
        LATD = LED_LookupTable[LED_Number];   

        LED_Number++;      // forgatunk egyet a kijelzon

        if (LED_Number == 8)
            LED_Number = 0;    // Ha vegigertunk, visszaugrunk az elsore.

        Delay1KTCYx(50);        // Delay 50 x 1000 = 50,000 cycles; 200ms @ 1MHz
    }   
}



Egy alap flowchart a futófényünkről (persze szöveges):

- Változók és portok inicializálása
    A LED_Number változó, mely az aktuálisan világlani kívánt LED sorszámát tárolja, 0 kezdőértéket vesz fel, vagyis az első LED-re ugrunk.
    A TRISD regiszter bitjeit mind 0-ra állítjuk, tehát mind a 8 PORTD láb (RD0-RD7) kimenet lesz.
    
- Végtelen ciklus egy while(1) segítségével:
    Beállítjuk az I/O portot, hogy bekapcsolhassunk egy LED-et.
        A LED_Number egy index a LED_Lookuptable tömbhöz, amely a port aktuális bittérképét adja meg. Ezt az értéket írjuk aztán a LATD regiszterbe, és kapcsoljuk be a megfelelő LED-et.
    Növeljük a LED sorszámot
        Egy if utasításban vizsgáljuk, hogy túlcsordult-e a programunk. Ha igen, akkor beállítjuk az első LED-et, a nulladikat.
    200 ms Delay
        A korábban használt delays könyvtár elemét használjuk, hogy az emberi szem számára láthatóvá tegyük a változást.
        
Fordítsuk le, és égessük be a programot!
Lám, kész van első futófényünk, és nem is kellett hozzá sok idő! A következő leckében ráadásul még az irányát is állítani tudjuk!
 


A cikk még nem ért véget, lapozz!
Következő: »»   2 / 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