Forum: Mikrocontroller und Digitale Elektronik Problem mit dem Watchdog beim ATtiny44


von H. G. (ledi)


Lesenswert?

Hallo!

Ich habe ein Problem mit dem Watchdog bei einem langen Tastendruck.
Bei einem Tastendruck wird die ISR0 ausgelöst und entsprechend 
ausgewertet.

Unter main habe ich folgenden Code:
1
void main(void)
2
{   
3
  SPI_Master_Init();            // Init SPI & MCU Settings
4
  Init_ADC();                   // Init ADC
5
  Init_Interrupt ();            // Init Interrupt 0
6
7
  wdt_enable(WDTO_4S);          // Enable watch-dog-timer 4 seconds
8
9
  MCUCR  |= (1<<SE);            // Sleep enable
10
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);  // Sleep Mode vorbereiten
11
    
12
  while(1)
13
    {  
14
    wdt_reset();                // reset watchdog
15
    ADCSRA   &= !(1<<ADEN);     // ADC deaktivieren
16
    wdt_disable();
17
    sleep_mode();
18
    wdt_enable(WDTO_4S);        // Enable watch-dog-timer 4 seconds
19
    }
20
}

Hat wer eine Idee, woran es liegen könnte?

Danke!

von Peter D. (peda)


Lesenswert?

Nicht alles zugleich, sondern nacheinander entwickeln:

1.Schritt: die Applikation schreiben und testen.
2.Schritt: falls gewünscht, Sleepmode hinzufügen und testen
3.Schritt: falls gewünscht, Watchdog hinzufügen und testen.


Peter

von avrGerd (Gast)


Lesenswert?

Wenn Du Probleme in der ISR hast, dann solltest Du uns den Code schon 
mal zeigen, sonst wird es schwer mit Raten.

Welches Problem hast Du genau? Löst der Watchdog aus?


avrGerd

von H. G. (ledi)


Lesenswert?

Bis auf den Watchdog, funktioniert alles wunderbar.

Meine ISR:
1
ISR(INT0_vect)
2
{
3
    MCUCR  &= ~(1<<SE);      // Sleep disable
4
    ADCSRA   |= 1<<ADEN;        // ADC aktivieren
5
    wdt_enable(WDTO_4S);      // Enable watch-dog-timer 4 seconds
6
  
7
    char ADC_Wert, cube_address;  
8
9
    ADCSRA |= (1<<ADSC);            // Start ADC-Converter
10
      while (ADCSRA & (1<<ADSC));    // wait for ADC-Conversion
11
    
12
    //ADC_Wert = ADCH;        // ADCH = ADLAR High-Byte Register f. linksbündig
13
                    // wenn nur 8 Bit benötigt werden
14
    ADC_Wert = ADC;  
15
....
16
....
17
....

von Peter D. (peda)


Lesenswert?

Heimo G. schrieb:
> ....
> ....
> ....

Ohne Worte.


Peter

von avrGerd (Gast)


Lesenswert?

Tja, er mag halt keine Hilfe ...

avrGerd

von Uwe (Gast)


Lesenswert?

WOFÜR benutzt du denn den Watchdog ?!?!!

von H. G. (ledi)


Lesenswert?

Hier die gesamte ISR:
1
ISR(INT0_vect)
2
{
3
    wdt_enable(WDTO_4S);      // Enable watch-dog-timer 4 seconds
4
    MCUCR  &= ~(1<<SE);      // Sleep disable
5
    ADCSRA   |= 1<<ADEN;        // ADC aktivieren
6
    
7
    char ADC_Wert, cube_address;  
8
9
    ADCSRA |= (1<<ADSC);            // Start ADC-Converter
10
      while (ADCSRA & (1<<ADSC));    // wait for ADC-Conversion
11
    
12
    //ADC_Wert = ADCH;        // ADCH = ADLAR High-Byte Register f. linksbündig
13
                    // wenn nur 8 Bit benötigt werden
14
    ADC_Wert = ADC;  
15
16
    //Taste = checkbutton(ADC_Wert);// Übergibt ADCL an checkbutton
17
    checkbutton(ADC_Wert);      // Übergibt ADCL an checkbutton
18
19
    _delay_ms(40);
20
21
22
    // Routine um Bit 6 (RX-FIFO Int.-Flag) im Statusregister zu löschen
23
    Payload(0x07, 0x00);      // Read Status Register
24
    if (0x40 & USIDR)        // if Bit6 = 1
25
    {
26
      Payload(0x27, 0x40);    // Write Data --> clear bit 6 (data ready RX FIFO interrupt)
27
    }
28
29
    // Routine um Bit 4 (Max. number of TX-Retransmitts Int.-Flag) im Statusregister zu löschen
30
    Payload(0x07, 0x00);      // Read Status Register
31
    if (0x10 & USIDR)        // if Bit4 = 1 (max. number of retransmission interrupt)
32
    {
33
      Payload(0x27, 0x10);    // Write Data --> clear bit 4 (max. RT interrupt)
34
    }
35
36
    Payload(0x07, 0x00);      // Read Status Reg.
37
    
38
    if (0x20 & USIDR)        // If ACK received
39
    {
40
      Payload(0x27, 0x20);    // Clear ACK (Bit 5)
41
      
42
      // if button 11 pressed long and write_counter < 128 write new cube address  
43
      if ((address_request == 1) && (write_counter < 128))  
44
      {
45
        //PORTA |= (1<<PA7);  // LED ON
46
        //PORTA |= (1<<PA2);  // Oscilloscope test point --> Start Rx-mode
47
48
        switch_to_Rx_mode();
49
50
        _delay_ms(40);
51
52
        CS_low();
53
        SPI_transfer(0x61);                    // Command read FIFO payload
54
        SPI_transfer(0x00);                    // 1. dummybyte
55
        cube_address = USIDR;                  // Read 1. byte
56
        lsb_address = cube_address;
57
        eeprom_write_byte(EEPROM_write_address, cube_address);  // Write cube address low byte into EEPROM
58
        EEPROM_write_address ++;
59
60
        SPI_transfer(0x00);                    // 2. dummybyte
61
        CS_high();
62
        cube_address = USIDR;                  // Read 2. byte
63
        eeprom_write_byte(EEPROM_write_address, cube_address);  // Write cube address high byte into EEPROM
64
        EEPROM_write_address ++;
65
66
        eeprom_write_byte(EEPROM_write_address, 0x00);      // Write 0x00 as last byte into EEPROM
67
68
        Payload(0xE2, 0x00);                  // clear RX-FIFO
69
        
70
        //PORTA &= !(1<<PA2);  // Oscilloscope test point --> Finish Rx-mode
71
72
        switch_to_Tx_mode();
73
74
        address_request = 0;
75
76
        if ((lsb_address != 0x00) && (cube_address != 0x00))
77
        {
78
          PORTA &= ~(1<<PA7);  _delay_ms(300);    // LED off
79
          PORTA |= (1<<PA7);  _delay_ms(100);    // LED on
80
          PORTA &= ~(1<<PA7);  _delay_ms(300);    // LED off
81
          PORTA |= (1<<PA7);  _delay_ms(100);    // LED on
82
          PORTA &= ~(1<<PA7);  _delay_ms(300);    // LED off
83
          PORTA |= (1<<PA7);  _delay_ms(100);    // LED on
84
          PORTA &= ~(1<<PA7);  _delay_ms(300);    // LED off
85
          PORTA |= (1<<PA7);  _delay_ms(100);    // LED on
86
          PORTA &= ~(1<<PA7);  _delay_ms(300);    // LED off
87
          PORTA |= (1<<PA7);  _delay_ms(100);    // LED on
88
          PORTA &= ~(1<<PA7);            // LED off
89
        }
90
      }
91
      
92
      /*if button 11 pressed long (read new cube address) and EEPROM write address
93
       is not the last EEPROM write address than read the new cube address*/
94
      
95
      if ((address_request == 2) && (EEPROM_read_value != 0x00))
96
      {
97
        Cube_high_byte   = eeprom_read_byte(EEPROM_read_address);  // Read value from EEPROM @ address 0x00
98
        EEPROM_read_address ++;
99
        Cube_low_byte   = eeprom_read_byte(EEPROM_read_address);  // Read value from EEPROM @ address 0x01
100
        EEPROM_read_address ++;
101
102
        EEPROM_read_value = eeprom_read_byte(EEPROM_read_address);  // Prüfe auf value 0x00
103
104
        change_TX_address(Cube_high_byte, Cube_low_byte);
105
106
        change_RX0_address(Cube_high_byte, Cube_low_byte);
107
108
        address_request = 0;
109
110
        PORTA &= ~(1<<PA7);  _delay_ms(100);    // LED off
111
        PORTA |= (1<<PA7);  _delay_ms(100);    // LED on
112
        PORTA &= ~(1<<PA7);  _delay_ms(100);    // LED off
113
        PORTA |= (1<<PA7);  _delay_ms(100);    // LED on
114
        PORTA &= ~(1<<PA7);  _delay_ms(100);    // LED off
115
        PORTA |= (1<<PA7);  _delay_ms(100);    // LED on
116
        PORTA &= ~(1<<PA7);  _delay_ms(100);    // LED off
117
        PORTA |= (1<<PA7);  _delay_ms(100);    // LED on
118
        PORTA &= ~(1<<PA7);  _delay_ms(100);    // LED off
119
        PORTA |= (1<<PA7);  _delay_ms(100);    // LED on
120
        PORTA &= ~(1<<PA7);            // LED off
121
      }
122
123
124
      if ((address_request == 2) && (EEPROM_read_value == 0x00))
125
      {
126
        EEPROM_read_address = 0;        // Set read address to 0x00
127
        EEPROM_read_value = 0xFF;        // Set read value to default value
128
        address_request = 0;
129
130
        change_TX_address  (0x36, 0x00);    // Set TX address to default value
131
        change_RX0_address  (0x36, 0x00);    // Set RX address to default value
132
133
        PORTA &= ~(1<<PA7);  _delay_ms(500);    // LED off
134
        PORTA |= (1<<PA7);  _delay_ms(500);    // LED on
135
        PORTA &= ~(1<<PA7);  _delay_ms(500);    // LED off
136
        PORTA |= (1<<PA7);  _delay_ms(500);    // LED on
137
        PORTA &= ~(1<<PA7);            // LED off
138
      }
139
    }
140
}

von H. G. (ledi)


Lesenswert?

Ich habe eine Fernbedienung, mit welcher ich RGB-Leds ansteuere. Für den 
Fall, das sich die Fernbedienung aufhängt, soll sich diese durch einen 
Reset neu starten.

von Peter D. (peda)


Lesenswert?

Geh vor an die Tafel und schreibe 100-mal:
"Ich darf in Interrupts _delay_ms() nicht verwenden !!!"


Peter

von spess53 (Gast)


Lesenswert?

Hi

>Geh vor an die Tafel und schreibe 100-mal:
>"Ich darf in Interrupts _delay_ms() nicht verwenden !!!"

100-mal ist zu wenig.

MfG Spess

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Peter Dannegger schrieb:
> Geh vor an die Tafel und schreibe 100-mal:
> "Ich darf in Interrupts _delay_ms() nicht verwenden !!!"

Das EEPROM beschreiben ist auch suboptimal. Ich habe das Gefühl, dass 
einiges aus der ISR in die Hauptroutine verlegt werden könnte...
Offenbar ist dem TO nicht ganz bekannt, wofür ISRs da sind.

von H. G. (ledi)


Lesenswert?

OK!
Welches Problem entsteht dadurch?

von Peter D. (peda)


Lesenswert?

Heimo G. schrieb:
> Ich habe eine Fernbedienung, mit welcher ich RGB-Leds ansteuere. Für den
> Fall, das sich die Fernbedienung aufhängt, soll sich diese durch einen
> Reset neu starten.

Warum soll sie sich denn aufhängen?
Doch nur durch einen Programmfehler.

Versuche mal die obige 3 Schritt Methode.
Du hast nämlich schon eine super Race-Condition drinn durch das alles 
gleichzeitig machen wollen:


Heimo G. schrieb:
> wdt_disable();

Heimo G. schrieb:
> ISR(INT0_vect)
> {
>     wdt_enable(WDTO_4S);      // Enable watch-dog-timer 4 seconds

Heimo G. schrieb:
> sleep_mode();



Peter

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.