Problem mit dem Watchdog beim ATtiny44

OP #2273668
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!
OP #2273738
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
....
OP #2273869
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
}
#2274146
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

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