WebElektronika

Portkezelés a PIC32-es mikrokontrollereknél

person access_time 2014.10.29.
A PIC32MX-es mikrovezérlőket bemutató sorozat első része a portkezelést mutatja be példák segítségével.


A következő öt példa segítségével átnézzük a PIC32MX mikrovezérlők portkezelési lehetőségeit. Használni fogjuk a speciális regisztereket (TRISx, stb), a fordítóhoz tartozó makrókat, de írunk sajátfüggvényeket is.
 

 

1. példa


Először a "B" port (16 bites) összes bitjét állítsuk kimenetre (TRISB) és állítsuk mind a 16 kimeneti bitet logikai 1-be (LATB). Ahhoz, hogy az "A" és a "B" port minden egyes bitjét használni tudjuk, tiltani kell a JTAG-et. Erre több lehetőségünk van, első esetben a JTAGEN bitet állítsuk logikai 0-ba. Ez a bit a DDPCON regiszterben található. Tekintettel arra, hogy nem szeretnénk az egész regisztert írni / maszkolni (32 bit), ezért használjuk a "bitmező" (DDPCONbits.JTAGEN = 0;) megoldást.
 

#include <p32xxxx.h>

main()
{
    TRISB = 0x0000;

    LATB = 0xFFFF;
    DDPCONbits.JTAGEN = 0;

    while(1);
}

 

Ahhoz, hogy a main() függvény ne érjen véget, betettünk egy végtelen ciklust, amelyet ";"-vel zártunk le. A kimenetre (B port) csak logikai 1-est írtunk, de van olyan bit, amelyhez tartozó LED nem világít. Vajon miért? 

Nos, láthatjuk a PIC32MX130F064B mikrovezérlő lábkiosztását mutató ábrán, hogy szinte mindegyik lábhoz több funkció tartozik. Ezért nekünk néha nem elég beállítani az adott portbitet kimenetnek, kénytelenek vagyunk az adott funkciót is tiltani.
 

 

2. példa


A következő példában a JTAG-et már a "config" regiszter írásával tiltjuk. Egy paraméternélküli (Futofeny()) és egy paraméteres sajátfüggvényt (Keses(int Eddig)) használunk fel a futófény megvalósításához. A "B" port alsó 8 bitjén (RB0..7) futófényt jelenítünk meg.

Szintén minden "B" portbit kimenet és ezeket nullázzuk. A while(1) végtelen ciklusban állandón meghívjuk a Futofeny() sajátfüggvényt, amelyben a for ciklus ciklusváltozóját kettesével szorozzuk. A ciklusváltozót egyenlővé tesszük a "B" port kimenetével. Hogy követhető legyen az emberi szemmel a futófény, betettünk a ciklusmagba egy késleltetést, amelyet egy másik sajátfüggvény valósít meg.
 

#include <p32xxxx.h>

#pragma config JTAGEN = OFF

void Keses(int Eddig);
void Futofeny();

main()
{
    TRISB = 0x0000;
    LATB = 0x0000;

    while(1)
        Futofeny();
}

void Keses(int Eddig)
{
    int i;
    for(i = 0; i <= Eddig; i++);
}

void Futofeny()
{
    int i;
    for(i = 1; i <= 255; i*=2)
    {
        LATB = i;
        Keses(30000);
    }
}

 

3. példa


Idáig olyan példákat néztünk, amelyekben a portbeállításokat speciális fileregiszterek (TRISx, LATx, PORTx) írásával készültek.

Az MCC32-es fordító rendelkezik különböző makrókkal, függvényekkel, amelyek segítségével a portműveletek könnyebbé (?) válnak. Ahhoz, hogy ezeket a függvényeket, makrókat használni tudjuk, be kell tenünk ezt a sort: #include <plib.h>

Nézzük most ezeket!

A JTAG-et most egy makróval tiltottuk le, ennek a paraméterlistájába akár a "0"-t is írhattuk volna. A következő makró segítségével beállítottuk a "B" port két alsó bitjét (RB0,1) kimenetté, azután pedig a RB7-es bitet digitális bemenetté.

Ezek után a beállítások után a két alkalmazni kívánt logikai kimenetet töröltük, a kimenetükön logikai nulla van.
 

#include <p32xxxx.h>
#include <plib.h>

main()
{
    // tiltjuk a JTAG-et
    mJTAGPortEnable(DEBUG_JTAGPORT_OFF);

    //RB0, RB1 kimenetek
    mPORTBSetPinsDigitalOut(BIT_0 | BIT_1);

    // RB7 digitális bemenet
     mPORTBSetPinsDigitalIn(BIT_7);

    // töröljük az RB0, RB1 biteket
    mPORTBClearBits(BIT_0 | BIT_1);

    while(1)
    {
        if(PORTBbits.RB7)
        {
            mPORTBClearBits(BIT_0);
            mPORTBSetBits(BIT_1);
        }
        else
        {
            mPORTBClearBits(BIT_1);
            mPORTBSetBits(BIT_0);
        }
    }
}

 

A végtelen ciklusban állandóan figyeljük az RB7 bemenet állapotát. Ha RB7 logikai egyben van, akkor az RB1 kimeneten lévő LED világít (LD2), egyébként pedig az RB0 van logikai 1-ben (tehát akkor az LD1 LED világít).

Ha az első példánál nem a TRISB regiszter értékadásával állítjuk be a "B" portot kimenetté, hanem a most tanult makrót alkalmazzuk, akkor az RB.4 biten lévő LED (LD5) is világítani fog (mPORTBSetPinsDigitalOut(BIT_0 | BIT_1 | BIT_2 | BIT_3 | BIT_4 | BIT_5 | BIT_6 | BIT_7);).

Felmerülhet a kérdés, hogy ha az összes portbeállítást makrókkal (plib.h) valósítottuk meg, akkor a LED-ek állapotváltását megoldhatjuk-e makrókkal?

 

4. példa


#include <p32xxxx.h>
#include <plib.h>

main()
{
    mJTAGPortEnable(DEBUG_JTAGPORT_OFF);
    mPORTBSetPinsDigitalOut(BIT_0 | BIT_1);
    mPORTBSetPinsDigitalIn(BIT_7);

    mPORTBClearBits(BIT_0);
    mPORTBSetBits(BIT_1);

    while(1)
    {
        mPORTBToggleBits(BIT_0 | BIT_1);
        Keses(30000);
    }
}

void Keses(int Eddig)
{
    int i;
    for(i = 0; i <= Eddig; i++);
}


A "mPORTBToggleBits(BIT_0 | BIT_1)" makró segítségével az előbb említett két "B" portkimenetet villogtatjuk. A szoftveres úton megvalósított késleltetés miatt a villogást látni lehet a tesztpanelon.

 

 

5. példa


Ez a néhánysoros kód minden sora ismerős már. A "B" portot minden bitjét kimenetre állítjuk, majd az RB7-es bitet átállítjuk bemenetre, hiszen ezen helyzkedik el a tesztpanelon a nyomógomb. A DDPCON regisztert írjuk azért, hogy a JTAG-et tiltsuk.

A "B" port állapotát nullázzuk, ezért egy LED sem fog világítani. A portbeállítás és a JTAG tiltása után a bekerül a vezérlés a végtelen ciklusba, majd várakozunk a nyomógomb (SW2) megnyomására, illetve elengedésére. Amikor ez megtörténik, akkor a LATB regiszter értékét eggyel növeljük, majd megint várakozunk a nyomógomb megnyomására és elengedésére.

Ezzel a programmal a nyomógomb megnyomását / elengedését tudjuk számolni és az eredményt binárisan megjeleníteni.
 

#include <p32xxxx.h>

main()
{
    TRISB = 0x0000;
    TRISBbits.TRISB7 = 1;
    LATB = 0x0000;
    DDPCONbits.JTAGEN = 0;

    while(1)
    {
        while(PORTBbits.RB7);
        while(!PORTBbits.RB7);
        LATB++;        
    }
}

 

Sorozatunk következő részében (2014.11.05.) kitérünk a Reset lehetőségekre, majd folytatjuk az órajel beállításának lehetőségeivel.