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?
Watchdog-Timer aktivieren, und den µC in eine Endlosschleife schicken.
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.
Evtl. musst du noch ein USB Device disconnect und reconnect auslösen. Evtl. das Disconnect sogar noch, bevor der WD zuschlägt.
Draco schrieb: > while(1) > { > } Wenn er da ankommt, wird der Watchdog nie wieder resetet und der uC wird immer wieder durch den Watchdog resetet.
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. Das ist sicher das was du willst, aber ist es das auch beim ersten mal?
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?!
1234567890 schrieb: > Das ist sicher das was du willst, aber ist es das auch beim ersten mal? Beim normalen durchlauf, wird diese schleife ignoriert, da ja die Variable vorher in der if Abfrage nicht wahr ist.
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 | }
|
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.