Atmega32u4 per Software reseten

Gast #4666883
Lesenswert?
• ▲
▼
Ich habe hier einen Atmega32u4, auf dem ein USB HID läuft. Nun habe ich 
ein Programm geschrieben welches neue Werte vom PC zum µC lädt und im 
EEPROM ablegt, der µC muss sich nun mit dem PC neu verbinden, sodass die 
Werte dann auch neu im System übernehmen werden. Momentan ziehe ich nun 
immer das Kabel und stecke es neu an.

Schöner wäre es natürlich das der µc den Reset selber durchführen kann, 
sodass ich auf der einen Seite die mechanische Belastung an der USB 
Buchse reduzieren kann, und es ist natürlich auch komfortabler.

Jemand einen kleinen Tipp im Ärmel?
Gast #4666906
Lesenswert?
• ▲
▼
Also ich habe nun den Reset mit dem Watchdog Timer ausgeführt. Der Reset 
funktioniert auch erstmal wunderbar. Aaaber

1
int main(void)
2
{ 
3
  wdt_reset();
4
  wdt_disable();
5

6
  uint8_t Ep2_temp[2] = {0,0};
7

8
  McStart();
9
    usb_init_device();    // Unterprogramm der USB-Bibliothek
10
    DracoRc_Setup();
11
    DracoRc_ChannelReset();
12
  McReady();
13
  
14
  wdt_enable(500);
15
  wdt_reset();
16

17
  sei();
18

19
  while (1)
20
  {
21
    Delay_MS(1);
22
    
23
    DracoRc_CalcMiddle();    
24
    Ep1_cnt = NumChannelOutPuts+2;  
25
    
26
    for(uint8_t i=0; i<NumChannelOutPuts;i++)
27
    {
28
       Ep1_buf[i]= ChannelPerc[i];
29
    }
30

31
    // Check USB Input Buffer
32
    if(Ep2_flag == 1)
33
    {
34
       if(Ep2_buf[0] == 0x86)
35
     Ep2_temp[1] = 0x01;
36
       else if (Ep2_buf[0] == 0x87)
37
     Ep2_temp[1] = 0x02;
38
      
39
       Ep2_flag = 0;
40
     }
41

42
     //Watchdog reset
43
     if(Ep2_temp[1] == 2)
44
     {
45
  while(1)
46
  {
47
  }
48
     }
49

50
    wdt_reset();
51
    Ep1_buf[4] = Ep2_temp[1];
52
    Ep1_buf[5] = NumChannelOutPuts;
53
    Ep1_flag = 1;
54
  }
55
}

Der Reset wird wie erwartet ausgeführt, jedoch kommt der µC nicht mehr 
korrekt zurück aus dem Reset. An PortB0 ist eine LED angeschlossen, 
diese blinkt nun, warum auch immer. Es hat den Anschein das er es 
nichtmal schafft mehr in die Main zurückzuspringen. Ein Bootloader ist 
AFAIK nicht auf dem µC, zumindest dürfte er ja mit einem normalen Chip 
Erase überschrieben wurden sein.
Gast #4666933
Lesenswert?
• ▲
▼
1234567890 schrieb:
> Draco schrieb:
>> while(1)
>>   {
>>   }
>
> Wenn er da ankommt, wird der Watchdog nie wieder resetet und der uC wird
> immer wieder durch den Watchdog resetet.

Da stehe ich gerade auf dem Schlauch. Er soll ja durch diese Schleife in 
den Reset kommen, diese Schleife ist ja eine Ebene über der Main 
Schleife.


Mal aufgedröselt:
1
int main(void)
2
{ 
3
  //..
4

5
  while (1) //Hauptschleife
6
  {
7
  //...
8

9
     //Watchdog reset
10
     if(Ep2_temp[1] == 2)
11
     {
12
       while(1) //WD Schleife
13
      {
14
      }
15
     }
16

17
    wdt_reset();
18
    //.....
19
  }
20
}

kommt doch nur dort an, wenn die Variable den Wert hat. Springt der 
Watchdog automatisch wieder an ihren Urpsrungsvector?!
Gast #4667149
Lesenswert?
• ▲
▼
Ich habe es nun hinbekommen:

1
int main(void)
2
{ 
3

4
  cli();
5
  uint8_t temp = MCUCR;
6
  MCUCR = temp | (1<<IVCE);
7
  MCUCR = temp & ~(1<<IVSEL);
8
  sei();
9

10
  wdt_disable();
11
  MCUSR = 0;
12
  wdt_reset();
13
  //..
14

15

16

17
  while (1) //Hauptschleife
18
  {
19
  //...
20

21
     //Watchdog reset
22
     if(Ep2_temp[1] == 2)
23
     {
24
        uint8_t temp = MCUCR;                 // Get MCUCR
25
        MCUCR = temp | (1<<IVCE);     // Enable change of Interrupt Vectors
26
        MCUCR = temp | (1<<IVSEL);    // Move interrupts to Boot Flash section
27

28
        while(1) //WD Schleife
29
        {
30
        }
31
     }
32

33
    wdt_reset();
34
    //.....
35
  }
36
}

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