Watchdog und Tiny

OP #2386215
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
}
OP #2386512
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.
OP #2386525
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.
OP #2386615
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.......
#2386627
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren