WebElektronika

Timer-ek használata a PIC32-es mikrovezérlőnél

person access_time 2014.11.23.
Folytatjuk tovább a PIC32MX család megismerését, sorozatunk mostani részében a Timer-eket nézzük megy gyakorlati szinten. Készítünk programokat, néhánynál a perifériakönyvtár függvényeit, makróit is felhasználjuk.


A sorozatunk mostani részében a PIC32MX család Timer1 (1. ábra) modulja kerül bemutatásra, gyakorlati megközelítésben.

A PBCLK (periféria órajel) jelet használjuk fel a számlálásra, ezért a TGATE és a TCS multilexer select lábakat logikai nullába kell tennünk. Az előosztó értékét a TCKPS jelekkel tudjuk beállítani.

Amikor a TMR1 értéke megegyezik a PR1 regiszter értékével, akkor a T1IF flag állapotot vált, nullából egybe kerül. Ez a flag csak szoftveresen törölhető.

 

kep
1. ábra   A Timer1 blokkvázlata (forrás)
 

 

Ennek a Timer-nek a beállítását (Timer1, 2. ábra) a T1CON konfigurációs regiszter megfelelő írásával tudjuk elvégezni.

 

kep
2. ábra   A T1CON regiszter "belseje" (forrás)
 

 

A PIC32MX mikrokontrollercsalád tagjait tudjuk úgy programozni, hogy a konfigurációs regisztereket írjuk közvetlenül, de úgy is, hogy függvényeket és makrókat hívunk meg a plib.h-ból (#include <plib.h>).

 

 

1. példa

 

Az első megoldásnál a TMR1 regiszter tartalmát egy lokális változó (Ido) értékével hasonlítjuk össze. Amíg ez a változó nagyobb, mint a TMR1-ben lévő szám, addig a B port 0. bitje logikai 1-ben van. Amikor ez a két szám megegyezik (vagy már nagyobb lesz), törlődni fog a TMR1 tartalma és a B port 0. bitje állapotot vált, a kimeneten logikai 0 lesz. A végtelen ciklus miatt ez a folyamat ismétlődik.

A Timer1 beállítását a T1CON regiszter közvetlen írásával érjük el. 

 

#include <p32xxxx.h>

main()
{
    unsigned int Ido = 10000;
    DDPCONbits.JTAGEN = 0;

    TRISB = 0x0000;

    T1CONbits.TGATE = 0;
    T1CONbits.TCS = 0;
    T1CONbits.ON = 1;
    T1CONbits.TCKPS0 = 1;
    T1CONbits.TCKPS1 = 0;
    T1CONbits.TSYNC = 0;

    LATB = 0x0000;    

    while(1)
    {
        while(TMR1 < Ido)
            LATBbits.LATB0 = 1;

        TMR1 = 0;

        while(TMR1 < Ido)
            LATBbits.LATB0 = 0;

        TMR1 = 0;
    }
}

 

 

2. példa

 

A múlt cikkünkben már részletesebben szóltunk a "#pragma config" beállításokról. Használjuk most fel ezeket. Beállítjuk a belső FRC-t (8 MHz) órajelnek, és a watchdog timer-t is kikapcsoljuk.

A "B" portot kimenetként állítjuk be a PORTSetPinsDigitalOut() függvény segítségével, majd ezt a portot reseteljük. A JTAG-et tiltjuk, de úgy, hogy erre egy makrót hívunk meg.

A Timer1-et most nem a T1CON regiszter közvetlen írásával konfiguráljuk fel, hanem az OpenTimer1() függvény meghívásával. 

Ahhoz, hogy ezeket a függvényeket, makrót meg tudjuk hívni, a file-hoz hozzá kell adnunk a plib.h file-t. Ezt a második sorban tettük meg.

 

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

#pragma config FNOSC = FRC
#pragma config POSCMOD = OFF
#pragma config FSOSCEN = OFF
#pragma config FWDTEN = OFF

main()
{
    unsigned int b = 1;

    PORTSetPinsDigitalOut(IOPORT_B, BIT_7 | BIT_6 | BIT_5 | BIT_4 | BIT_3 | BIT_2 | BIT_1 | BIT_0);
    PORTClearBits(IOPORT_B, BIT_7 | BIT_6 | BIT_5 | BIT_4 | BIT_3 | BIT_2 | BIT_1 | BIT_0);

    mJTAGPortEnable(0);

    OpenTimer1(T1_ON | T1_PS_1_1 | T1_SOURCE_INT, 60000);

    while(1)
    {
        if(mT1GetIntFlag())
        {
            mT1ClearIntFlag();
            LATB++;
        }
    }
    CloseTimer1();
}

Amikor a Timer1 eléri a 60000-et (PR1 regiszterben ez van), akkor a T1IF flag állapotot vált, nullából egybe vált. Ezt az állapotot figyeljük a végtelen ciklusban az mT1GetIntFlag() makróval. Ha TMR1=PR1, akkor a feltételes szerkezetben töröljük ezt a flag-et és a B port értékét eggyel növeljük.

A CloseTimer1() függvény beírása inkább "megszokás", hiszen ez a függvény soha nem kerül felhasználásra, hiszen a végtelen ciklsuból nem lépünk ki.

 

 

3. példa

 

Ez a példa nagyon hasonló az előzőhöz, a különbség annyi, hogy nem egy Timer kerül alkalmazásra, hanem kettő. Mind a két Timer (1, 2) működési tulajdonságait az OpenTimer() függvény segítségével állítottuk be.

 

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

#pragma config FNOSC = FRC
#pragma config POSCMOD = OFF
#pragma config FSOSCEN = OFF
#pragma config FWDTEN = OFF

main()
{
    
PORTSetPinsDigitalOut(IOPORT_B, BIT_7 | BIT_6 | BIT_5 | BIT_4 | BIT_3 | BIT_2 | BIT_1 | BIT_0);

    PORTClearBits(IOPORT_B, BIT_7 | BIT_6 | BIT_5 | BIT_4 | BIT_3 | BIT_2 | BIT_1 | BIT_0);

    mJTAGPortEnable(0);

    OpenTimer1(T1_ON | T1_PS_1_1 | T1_SOURCE_INT, 60000);
    OpenTimer2(T2_ON | T2_PS_1_4 | T2_SOURCE_INT, 60000);

    while(1)
    {
        if(mT1GetIntFlag())
        {
            mT1ClearIntFlag();
            LATBbits.LATB0 = ~LATBbits.LATB0;
        }
        if(mT2GetIntFlag())
        {
            mT2ClearIntFlag();
            LATBbits.LATB1 = ~LATBbits.LATB1;
        }
    }
    CloseTimer1();
    CloseTimer2();

}