Forum: Mikrocontroller und Digitale Elektronik Watchdog und Tiny


von Michael W. (michel72)


Lesenswert?

Tach,

ich habe hier einen Tiny85 bei dem ich jetzt den Watchdog implementieren 
möchte. Ich möchte den Watchdog per SW ein-/ ausschalten und den 
Programmablauf überwachen. Bevor der Tiny in den Sleepmode geht schalte 
ich den Watchdog aus.

Das lief jetzt einige Stunden gut und plötzlich wird ständig der Tiny 
resettet. Ich habe deshalb in der Main zuerst den wdt_diabled und dann 
mit der neuen Zeit wieder enabled aber ohne Erfolg. Ich bekomme ständig 
vom Tiny85 Daten gesendet. Was für mich bedeutet der Watchdog schlägt 
früher zu und wartet noch nicht einmal die 8 Sekunden.
Hat Jemand eine Idee ?

Gruß
Michael



Folgendes habe ich bis jetzt "gebastelt"
1
int main(void)
2
{
3
4
    wdt_disable();
5
    wdt_enable(WDTO_8S);
6
7
    unsigned char uniqueID[10];
8
9
    unsigned int i=0;
10
    unsigned int TempH=0;
11
    unsigned int TempL=0;
12
13
    unsigned char eprom;
14
    unsigned char BattH=0;
15
    unsigned char BattL=0;
16
    uint8_t Wake=0;
17
    uint8_t cnt=0;
18
19
20
    uint16_t temp=0;
21
22
    wdt_reset();
23
    portInit();
24
25
    asm("cli");
26
    RFM12init();
27
28
    PRR |= (1<<PRTIM1) | (1<<PRUSI) | (1<<PRADC); // Timer1 abschalten, USI und ADC brauchen wir nicht !
29
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
30
    sleep_enable();
31
32
33
      //---------------------------------------------------------------
34
      // haben wir eine ID im EEPROM?
35
      // Wenn nicht wird eine vom Master angefordert !
36
      // Dabei ist die Seriennummer vom DS1820 unsere vorläufige ID
37
      //---------------------------------------------------------------
38
    start_meas();
39
    temp = read_meas(uniqueID); // Seriennummer vom DS1820
40
    _delay_ms(750); //POR Time
41
      asm("cli");
42
      eprom = EEPROM_read(0);
43
      Wake  = EEPROM_read(1);
44
45
46
      sei();
47
48
      if(eprom==0xff){
49
          start_meas();
50
          temp = read_meas(uniqueID); // Seriennummer vom DS1820
51
          for(i=0;i<8;i++){
52
              UNIQUE[i]         = uniqueID[i];
53
          }
54
          // Verarbeiten der Adressnummer !
55
          INT_nIRQ = 0;
56
          ID = getID(RFM12Message);
57
          sendACK(ACKPacket,RFM12Message);
58
          asm("cli");
59
          EEPROM_write(0,ID);
60
          sei();
61
      }
62
      else{
63
        ID = eprom;
64
      }
65
      if(Wake==0xff){
66
        Wake = 0x09;
67
        asm("cli");
68
        EEPROM_write(1,Wake); // Timer auf ca. 5Minuten
69
        sei();
70
71
      }
72
      _delay_ms(2000);
73
74
      //-----------------------------------------------------------------------
75
      // TEMP - Messung - Hauptroutine
76
      //-----------------------------------------------------------------------
77
78
      //temp = read_meas(uniqueID); // 1x aufrufen um den initialwert 85.0C zu werfen !
79
      while(1){
80
        wdt_reset();
81
        start_meas();
82
        wdt_reset();
83
        temp = read_meas(uniqueID);
84
        wdt_reset();
85
        // High und Low Byte shiften
86
        TempL = temp;
87
        TempH = temp >> 8;
88
89
        // Batteriewert
90
        BattH = getBatt();
91
        BattL = BattH%10;
92
        BattH = BattH/10;
93
94
95
        // Paket für den Master
96
97
        RFM12Message[0]=ID;
98
        RFM12Message[1]=0x01;        // An den Master
99
        RFM12Message[2]=0x08;        // Messagetyp , hier Tempsensor
100
        RFM12Message[3]=0x04;        // Anzahl Datenbytes
101
        RFM12Message[4]=TempH;
102
        RFM12Message[5]=TempL;
103
        RFM12Message[6]=BattH;
104
        RFM12Message[7]=BattL;
105
        wdt_reset();
106
107
        // Temperatur und Batterie verschicken
108
        if(sendPackage(RFM12Message)==0){
109
            wdt_reset();
110
            // ACK erhalten und gleich mal schauen , ob sich darin etwas für den Timer befindet
111
            if(RFM12Message[3]>0x01){
112
               wdt_reset();
113
               if((RFM12Message[5]!=0x00) && (RFM12Message[5] < 0x1F)){
114
                  asm("cli");
115
                  EEPROM_write(1,RFM12Message[5]);
116
                  wdt_reset();
117
                  sei();
118
                  Wake = RFM12Message[5];
119
                  wdt_reset();
120
               }
121
            }
122
        }
123
        // wenn rslt = 1 haben wir kein ACK erhalten bei 0 lief alles problemlos
124
        // wird im Moment nicht ausgewertet vielleicht später mal !
125
126
        // RFM12 abschalten und Sleeptimer setzen !
127
128
        writeCmd(0xEF00 | Wake); // writeCmd(0xEF09); // 294912 ms Sleep , ca. alle 5 min.
129
wdt_reset();
130
        writeCmd(0x8203); // Alles bis auf den WakeupTimer aus !
131
wdt_reset();
132
133
134
135
        GIMSK |= (1<<INT0);  // auf alle Fälle noch den INT zum wecken aktivieren !
136
        MCUCR &= ~(1<<ISC01);                          // fallende Flanke INT0
137
wdt_reset();
138
wdt_disable();
139
140
        sleep_cpu();
141
142
        _delay_ms(100);    // Einschwingzeit Oszillator 5µs
143
 wdt_enable(WDTO_8S);
144
145
        asm("cli");
146
        ID    = EEPROM_read(0);                            // Workaround
147
        Wake  = EEPROM_read(1);                            // Workaround
148
        RFM12init();
149
wdt_reset();
150
        sei();
151
        MCUCR |= (1<<ISC01);
152
        GIMSK |= (1<<INT0);                      // fallende Flanke INT0
153
154
      }
155
}

von Thomas E. (thomase)


Lesenswert?

Michael W. schrieb:
> GIMSK |= (1<<INT0);  // auf alle Fälle noch den INT zum wecken aktivieren !
>
>         MCUCR &= ~(1<<ISC01);

Wo ist denn die ISR?

mfg.

von Michael W. (michel72)


Lesenswert?

Der INT0 ist zum wecken vom Tiny. Aufm Pin/INT0 wird nach Ablauf einer 
Zeit eine Flanke geliefert und entsprechend der Tiny aufgeweckt.

von Thomas E. (thomase)


Lesenswert?

Michael W. schrieb:
> Der INT0 ist zum wecken vom Tiny.
Wenn der Interrupt ausgelöst wird, springt der Controller in die ISR. 
Egal ob er sich in Run oder Sleep befindet. Wenn keine ISR da ist, macht 
der Controller einen Reset.

mfg.

von Thomas E. (thomase)


Lesenswert?

Und noch was:
>MCUCR &= ~(1<<ISC01);                          // fallende Flanke INT0

flankengetriggerte Interrupts funktionieren im Sleepmode nicht.


mfg.

von Michael W. (michel72)


Lesenswert?

ich musste jetzt direkt noch einmal in den Code schauen, ja eine ISR ist 
da, der INT signalisiert zum einen den Wakeup wie auch empfangene Daten.
Ich habe auch den ständigen Reset erst nachdem ich den Watchdog 
eingefügt habe und auch erst dann kommen die ständigen Resets , wenn 
(vermute ich) der Watchdog zugeschlagen hat.

von Michael W. (michel72)


Lesenswert?

Thomas Eckmann schrieb:
> Und noch was:
>>MCUCR &= ~(1<<ISC01);                          // fallende Flanke INT0
>
> flankengetriggerte Interrupts funktionieren im Sleepmode nicht.
>
>
damit lösche ich das Bit.

und hier ein Auszug aus dem Datenblatt :

...Note that if a level triggered interrupt is used for wake-up the 
changed level must be held for
some time to wake up the MCU (and for the MCU to enter the interrupt 
service routine). See
“External Interrupts” on page 51 for details.

von Thomas E. (thomase)


Lesenswert?

Michael W. schrieb:
> damit lösche ich das Bit.
Ja ist OK, hatte ich nicht gesehen. Ich hab' nur den Kommentar gelesen.
Damit steht er dann auf Low Level.

Michael W. schrieb:
> Ich habe auch den ständigen Reset erst nachdem ich den Watchdog
> eingefügt habe und auch erst dann kommen die ständigen Resets
Hast du den Watchdog per Fuse eingeschaltet?

mfg.

von Michael W. (michel72)


Lesenswert?

Nein keine Fuse gesetzt, wollte es per Software mit enable und disable 
machen....

von Thomas E. (thomase)


Lesenswert?

Michael W. schrieb:
> Nein keine Fuse gesetzt, wollte es per Software mit enable und disable
> machen....
Das ist auch gut so. Sonst kannst du den nämlich nicht während der Fahrt 
abschalten.

Ist der INT0-Pin als Ausgang konfiguriert?

mfg.

von Michael W. (michel72)


Lesenswert?

Nö, als Eingang. Ich denke ja jetzt nicht das da ein Problem mit dem 
INT0 besteht. Wie bereits erwähnt liefen die Module 1/2 Jahre ohne 
Probleme und ich wollte jetzt einfach noch zur Sicherheit den Watchdog 
einbauen.
Das Modul hat folgende Aufgabe, Es wird die Umgebungstemperatur gemessen 
und dann über den RFM12 an die Basis gesendet. Wurde erfolgreich 
gesendet (ACK) dann geht das Modul in den Sleepmode. Funktioniert 
soweit, die Welt ist schön ;)

Jetzt kam ich auf die Idee ok baue doch zur Sicherheit noch einen 
Watchdog ein. Umgesetzt , lief anfangs auch weiterhin ohne Probleme , 
doch als ich heute an den Rechner bin sehe ich an der Basis das das 
Modul mit der Watchdog Version plötzlich im 2sek. Takt Daten 
sendet.......

von Thomas E. (thomase)


Lesenswert?

Michael W. schrieb:
> Nö, als Eingang. Ich denke ja jetzt nicht das da ein Problem mit dem
> INT0 besteht. Wie bereits erwähnt liefen die Module 1/2 Jahre ohne
> Probleme und ich wollte jetzt einfach noch zur Sicherheit den Watchdog
> einbauen.

The External Interrupts are triggered by the INT0 pin or any of the 
PCINT5..0 pins. Observe that, if enabled, the interrupts will trigger 
even if the INT0 or PCINT5..0 pins are configured as outputs.

Vielleicht hast du die Probleme nur nicht bemerkt. Bring' das erstmal in 
Ordnung.

mfg.

von Michael W. (michel72)


Lesenswert?

Thomas Eckmann schrieb:
> The External Interrupts are triggered by the INT0 pin or any of the
> PCINT5..0 pins. Observe that, if enabled, the interrupts will trigger
> even if the INT0 or PCINT5..0 pins are configured as outputs.

Bin ja jetzt nicht das Englisch AS aber bedeutet das nicht , dass der 
External Interrupt auch auslöst wenn er als Output geschaltet ist ?

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.