Wydział Informatyki Katedra Systemów Czasu Rzeczywistego Laboratorium Architektury Komputerów |
Data 28.10.2009 |
Ćwiczenie nr 2 Temat: Watchdog Timer. Przerwania. Zespół nr 2 1. Robert Jarocki Grupa nr 6 2. Jarosław Jastrzębski |
Prowadzący …...................... Ocena …...................... |
ZADANIE 2
Ćwiczenie drugie polega na zastosowaniu WDT w trybie watchdog. Należy napisać program, który w przypadku zawieszenia będzie przy pomocy WDT dokonywał restartu i przywracał program do działania. Zawieszenie programu powinno być powodowane przez użytkownika (poprzez naciśnięcie klawisza), a gdy układ zostanie zrestartowany przez WDT, powinno to być pokazane w widoczny sposób. Rozróżnienie, czy układ był restartowany przez WDT czy przez użytkownika zapewnia flaga WDTIFG umiejscowiona w rejestrze IFG1. Podczas restartu układu przez WDT flaga WDTIFG jest automatycznie ustawiana. Sprawdzenie jej stanu pozwala na znalezienie przyczyny restartu.
Rozwiązanie :
Rozwiązaliśmy problem programując w odpowiedni sposób płytkę EasyWeb2 w środowisku IAR w języku C.
Kod:
#include <io430.h>
#define DIODA_PIERWSZA 0x20
#define DIODA_DRUGA 0x40
#define PRZYCISK 0x10
#define ZAPALENIE_DIODY 1
#define ZGASZENIE_DIODY 0
void dioda(int akcja, int adres)
{
if((akcja != 0))
P1OUT |= adres;
else
P1OUT &= ~adres;
}
int przycisk()
{
if((P4IN & PRZYCISK) == 0)
return 1;
else
return 0;
}
void main(void)
{
P1DIR = P1DIR | DIODA_PIERWSZA | DIODA_DRUGA;
dioda(ZGASZENIE_DIODY, DIODA_PIERWSZA);
dioda(ZGASZENIE_DIODY, DIODA_DRUGA);
if((IFG1 & WDTIFG) != 0)
{
IFG1 = IFG1 & ~WDTIFG;
dioda(ZAPALENIE_DIODY, DIODA_PIERWSZA);
}
else
{
dioda(ZAPALENIE_DIODY, DIODA_DRUGA);
}
while(1)
{
if(przycisk())
{
while(1);
}
else
{
WDTCTL = WDTPW + WDTCNTCL;
}
}
}
Opis działania :
Aby zrealizować zadanie korzystaliśmy z biblioteki <io430.h> oraz zdefiniowaliśmy diodę pierwszą (0x20), diodę drugą (0x40), przycisk (0x10), zapalenie diody ustawiliśmy na stałą wartość 1, a jej zgaszenie na 0.
Funkcja „ void dioda(int akcja, int adres) ” odpowiada za ustawienie wyjścia P1.
Funkcja „ int przycisk() ” zwraca „1” lub „0” w zależności od tego czy przycisk został wciśnięty.
W funkcji „void main(void)” ustawiamy port P1 i dwie diody za pomocą „ P1DIR = P1DIR | DIODA_PIERWSZA | DIODA_DRUGA; ” oraz wywołujemy funkcje dioda. Następnie sprawdzamy czy flaga WDTIFG jest ustawiona w rejestrze IFG1, jeżeli tak to wiemy że program został zrestartowany przez watchdog'a i usuwamy flagę z rejestru - „ IFG1 = IFG1 & ~WDTIFG; ” oraz sygnalizujemy restart WDT za pomodą diody pierwszej - „dioda(ZAPALENIE_DIODY, DIODA_PIERWSZA); „. W przeciwnym przypadku zapalamy diodę drugą sygnalizującą normaly start - „ dioda(ZAPALENIE_DIODY, DIODA_DRUGA); „.
W nieskończonej pętli while tworzymy kolejną nieskończoną pętlę while aby WDT zadziałał generując sygnał reset jeśli przycisk został wciśnięty. Jeżeli przycisk nie został wciśnięty następuje zerowanie zegara WDT aby licznik nie uległ przepełnieniu i nie spowodował restartu - „ WDTCTL = WDTPW + WDTCNTCL; ”.