WebElektronika

Watchdog Timer használata a PIC32MX családban

person access_time 2016.04.06.
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.


A PIC32MX795F512L mikrovezérlő Watchdog Timer (WDT) blokkvázlatát mutatja az első ábra. 

kep
1. ábra   A Watchdog Timer felépítése
 

A WDT működésének beállításához fel kell programoznunk a Timer konfigurációs regiszterét, a WDTCON-t (2. ábra).

A WDT működéséhez be kell kapcsolnunk a Timer-t (ON bit), a törléshez pedig a WDTCLR bitnek kell logikai 1-et adnunk, ezt a bitet is a WDTCON regiszterben találjuk.

kep
2. ábra   A WDTCON regiszter
 

A WDT-nek önálló belső RC oszcillátora van, ezt az órajelet számolja a WDT. A számlálás ideje (az órajel osztása) a WDTPS bitek írásával módosítható (3. ábra). A példaprogramok a 01010 beállítást tartalmazzák, azaz kb 1.024s-ként a timer alapállapotba hozza a mikrovezérlőt.

kep
3. ábra   A kiválasztható osztási lehetőségek
 

 

1. példa

Az első programnál a FWDTEN=ON hatására a WDT-t engedélyezzük, ezután a D portot beállítjuk kimenetre, majd az összes LED-et kikapcsoljuk (D port). A Keses() függvény meghívása (és annak lefutása) után a D porton lévő minden LED-et bekapcsoljuk.

Tekintettel arra, hogy a WDT kb 1.024 másodperc után túlcsordul, ezért a végtelen ciklusból kilép a vezérlés, és újra indul. A D porton lévő LED-ek tehát villogni fognak.

#include <p32xxxx.h>
#pragma config FWDTEN = ON
#pragma config WDTPS = PS1024

void Keses(int szam);
main()
{
    DDPCONbits.JTAGEN = 0;
    TRISD = 0x0000;
    LATD = 0x0000;
    Keses(10000);
    LATD = 0xFFFF;    
    while(1);
}

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

 

2. példa

Készítünk most egy makrót (WdtTorles()), amelynek segítségével a WDT értékét töröljük. A while(1) végtelen ciklusban ezt a makrót állandóan meghívjuk, így nem tud túlcsordulni a WDT, ezért a mikrovezérlő alapállapotba helyezése elmarad.

#include <p32xxxx.h>
#pragma config FWDTEN = ON
#pragma config WDTPS = PS1024

#define    WdtTorles() {WDTCONbits.WDTCLR = 1;}

void Keses(int szam);
main()
{
    DDPCONbits.JTAGEN = 0;
    TRISD = 0x0000;
    LATD = 0x0000;
    Keses(10000);
    LATD = 0xFFFF;

    while(1)
        WdtTorles();
}

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

 

3. példa

Most a fordító (MCC32) makróit használjuk fel a Watchdog Timer használatához. Érdemes kipróbálni külön-külön a PS1024 és a PS128-as makrókat is.

Az EnableWDT() makróval engedélyezzük a WDT működését, a ClearWDT() segítéségvel töröljük a WDT aktuális értékét. A Readpostscaler() visszaadja a WDT osztójának értékét bitszinten. Ezt az értéket az A porton jelenítjük meg.

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

//#pragma config WDTPS = PS1024
#pragma config WDTPS = PS128

void Keses(int szam);
main()
{
    DDPCONbits.JTAGEN = 0;
    EnableWDT();
    TRISA = 0x0000;
    TRISD = 0x0000;
    LATD = 0x0000;
    Keses(10000);
    LATD = 0xFFFF;

    while(1)
    {
        ClearWDT();
        LATA = ReadPostscalerWDT();
    }    
}

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

 

4. példa

Végül nézzünk meg egy példát arra, amikor fontos tudni azt, hogy a mikrovezérlőnket mi helyezte alapállapotba. Ehhez az RCON regiszter flag-jeit kell vizsgálni. Fontos, hogy a flag-ek értékét szoftveresen kell törölni. Például az EXTR flag az MCLR hatását mutatja, a WDTO pedig a Watchdog Timer túlcsordulását.

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

#pragma config WDTPS = PS1024

void Keses(int szam);
main()
{
    DDPCONbits.JTAGEN = 0;
    EnableWDT();
    TRISB = 0x0000;
    TRISD = 0x0000;
    LATB = 0x0000;
    LATD = 0x0000;
    Keses(10000);
    LATD = 0xFFFF;

    if(RCONbits.EXTR)
    {
        RCONbits.EXTR = 0;
        LATBbits.LATB0 = 1;
    }
    if(RCONbits.WDTO)
    {
        RCONbits.WDTO = 0;
        LATBbits.LATB1 = 1;
    }
    if(RCONbits.BOR)
    {
        RCONbits.BOR = 0;
        LATBbits.LATB2 = 1;
    }
    if(RCONbits.POR)
    {
        RCONbits.POR = 0;
        LATBbits.LATB3 = 1;
    }


    while(1)
        ClearWDT();
}

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

 

Ha a while(1) ciklus után pontosvesszőt teszünk, akkor a WDT újra fogja indítani a mikrovezérlőt, tehát a B port 1. bitjén logikai 1 lesz.