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ő.
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.
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>).
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;
}
}
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.
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();
}
Október közepén elindítjuk az Atmel 8 bites mikrovezérlőkről szóló sorozatunkat. Ehhez használnunk kell természetesen egy fejlesztőkörnyezetet is. Több ilyen is létezik, például a WinAVR, vagy az Atmel Studio. Mi az Atmel Studio-t fogjuk használni, e. . . .
A PIC18F mikrovezérlők ma is népszerű a fejlesztők körében. Noha 8 bites architektúráról beszélünk, számos érdekes és hasznos alkalmazás megvalósítható vele. Elég csak az USB-re, vagy akár az Ethernetre gondolnunk. Ezért a Szerkesztőség egy sorozat k. . . .
Megnézzük most néhány példa segítségével a Watchog Timer (WDT) használatát. Írni fogunk közvetlenül regisztert, de használni fogunk makrókat is.. . . .