Forum: Mikrocontroller und Digitale Elektronik MSP430 Watchdog aktivieren nach definierter Zeit


von mikrocomputerstudent (Gast)


Lesenswert?

Hallo,
ich komme gerade bei einer Hausaufgabe für die Uni nicht weiter.
Es wäre nett wenn mir jemand dabei helfen könnte.

Aufgabe:
Man soll eine grüne LED mit f = 4 Hz blinken lassen. (Die rote LED habe 
ich nur zum Debuggen hinzugeschaltet)
Falls man den Button drückt, dann soll der Controller in einen 
künstlichen Deadlock geraten und nach 5,5 Sekunden durch den Watchdog 
Timer zurückgesetzt werden. Um den Watchdog Timer zu initialisieren, 
soll man ACLK als Watchdog Timer Source benutzen und das Watch Dog Timer 
Control Register entsprechend setzen.

Achso, ACLK hat eine Frequenz von 32768 Hz.

Hier wäre mein Code dazu:
1
#include <msp430g2553.h>
2
3
int buttonPressed;
4
5
int main(void)
6
{
7
    WDTCTL = WDTPW | WDTHOLD;  // stop watchdog timer
8
9
    // initialization of the basic clock module
10
    BCSCTL3 |= LFXT1S_2;
11
12
    // initialization of wdtctl register
13
    WDTCTL = (WDTPW | WDTSSEL | WDTCNTCL );
14
15
    // P1.4 -> output to red LED
16
    // P1.0 -> output to green LED
17
    P1DIR |= BIT0;
18
    P1DIR |= BIT4;
19
20
    // Initialization for interrupts
21
    // P1.3 -> input of button
22
    P1SEL &= (~BIT3); // set P1.3 SEL as GPIO
23
    P1DIR &= (~BIT3); // set P1.3 SEL as Input
24
    P1IES |= (BIT3); // falling edge 1 -> 0
25
    P1IFG &= (~BIT3); // clear interrupt flag for P1.3
26
    P1IE |= (BIT3); // enable interrupt for P1.3
27
    P1REN |= BIT3;  // enable pull-up/-down resistor
28
29
    __enable_interrupt();
30
31
    buttonPressed = 0;
32
33
34
    while (1) {
35
        P1OUT ^= BIT0;
36
        if (buttonPressed == 1) {
37
            P1OUT ^= BIT4;
38
            P1OUT = 0x00;
39
            buttonPressed = 0;
40
            while (1) {
41
                // artificially created dead-lock
42
            }
43
        } else {
44
            // f = 4 Hz => T = 1 s / 4 Hz = 250 ms
45
            __delay_cycles(250000);
46
        }
47
        WDTCTL = (WDTPW | WDTSSEL | WDTCNTCL );  // feed the dog
48
    }
49
}
50
51
52
// Port 1 interrupt vector
53
#pragma vector = PORT1_VECTOR
54
__interrupt void Port_1(void)
55
{
56
    buttonPressed = 1;
57
    P1IFG &= ~BIT3; // clear interrupt flag
58
}


Probleme/Fragen hierzu:
- Wenn ich den Button drücke, dann hört die rote und die grüne LED für 
ein paar Sekunden auf zu blinken. Woraus ich schlussfolgere dass sich 
der Controller im Deadlock befindet. Danach blinkt nur noch die grüne 
LED und wenn ich den Button nochmal drücke, scheint der Controller nicht 
darauf zu reagieren, also es ändert sich nichts mehr an dem Zustand. 
Woran liegt das, was genau ist passiert?
- Wie kann ich gewährleisten dass der Watchdog den Deadlock nach exakt 
5,5 Sekunden zurücksetzt?
- Fallen jemandem irgendwelche Fehler bei meinem Code auf?

ps: Ich erwarte natürlich nicht dass hier jemand meine Aufgabe für mich 
löst. Ein paar hilfreiche Antworten erhoffe ich mir allerdings schon :)

von mikrocomputerstudent (Gast)


Lesenswert?

Ich habe noch eine Frage:
Mit dem Bitwert von WDTTMSEL kann man die watchdog timer+ mode 
einstellen, bei einer gesetzten 0 kommt er laut Datenblatt in die 
watchdog mode und bei einer 1 in die interval timer mode.
Ich bin jetzt davon ausgegangen dass man dies einstellt in dem man für 
eine 1 WDTCTL = ... | WDTTMSEL hinzuverodert und das für eine 0 einfach 
weglässt.
Denn WDTCTL = ... | ~WDTTMSEL für eine logische 0 scheint nicht zu 
funktionieren.
Ist dies korrekt?

von Clemens L. (c_l)


Lesenswert?

mikrocomputerstudent schrieb:
> Wie kann ich gewährleisten dass der Watchdog den
> Deadlock nach exakt 5,5 Sekunden zurücksetzt?

Schau dir mal die Doku zu WDTCTL an.

mikrocomputerstudent schrieb:
> Fallen jemandem irgendwelche Fehler bei meinem Code auf?

P1OUT.3 wird am Anfang nicht initialisiert, und dann in der Schleife 
überschrieben.

von mikrocomputerstudent (Gast)


Lesenswert?

Clemens L. schrieb:
> mikrocomputerstudent schrieb:
>> Fallen jemandem irgendwelche Fehler bei meinem Code auf?
>
> P1OUT.3 wird am Anfang nicht initialisiert, und dann in der Schleife
> überschrieben.

O man, du hast natürlich recht, danke.

Habe den entsprechenden Abschnitt jetzt wie folgt korrigiert:
1
...
2
    P1OUT |= BIT0;  // ---- das ist neu
3
4
    __enable_interrupt();
5
6
    pb5Pressed = 0;
7
8
9
    while (1) {
10
        P1OUT ^= BIT0;
11
        if (pb5Pressed == 1) {
12
            P1OUT ^= BIT4;
13
            P1OUT &= (~BIT0);  // ---- das ist neu
14
            pb5Pressed = 0;
15
            while (1) {
16
                // artificially created dead-lock
17
...
 und es funktioniert.
Ich kann den Watchdog Timer jetzt auch mehrmals mit dem Button auslösen, 
so wie es sein sollte :)

Clemens L. schrieb:
> Schau dir mal die Doku zu WDTCTL an.

Dann sehe ich mir nochmal die Doku an. Echt mühselig das ganze :)

von mikrocomputerstudent (Gast)


Lesenswert?

Also das mit den 5,5 Sekunden habe ich jetzt glaub hingekriegt, bin mir 
aber nicht ganz sicher warum es so funktioniert.
Habe es mit einer Stoppuhr nachgemessen :)

Ich habe etwas im MSP430_Guide rumgesucht und bin darauf gekommen, dass 
man ja auch die Basic Clock Modul Frequenz verkleinern kann.
Das habe ich dann auch getan, mit dem Hinzufügen folgender Code-Zeile:
1
    
2
    // divide ACLK with 2
3
    BCSCTL1 |= DIVA0;
Laut dem Datenblatt wird die Basic Clock, die in diesem Fall ja gleich 
ACLK ist und somit eine Frequenz von 32768 Hz hat, durch 2 geteilt.
Also müsste sie ja 16384 Hz betragen.
Im Datenblatt steht dass der Watchdog aktiv wird sobald einmal "eine 
Periode" hochgezählt wurde. Warum ist der Intervall dann nicht 2 
Sekunden?
Oder 4 Sekunden, falls nur bei der falling oder rising edge gezählt 
wird?

von Clemens L. (c_l)


Lesenswert?

mikrocomputerstudent schrieb:
> Im Datenblatt steht dass der Watchdog aktiv wird sobald einmal "eine
> Periode" hochgezählt wurde. Warum ist der Intervall dann nicht 2
> Sekunden?

Die Periode wird mit den WDTIS-Bits eingestellt.

Aber solange der Quarz-Oszillator nicht korrekt initialisiert wurde, 
läuft ACLK nicht mit 32768 Hz. Und schau mal nach, was du in BCSCTL3 
eingestellt hast.

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.