Hi Ich würde gerne meinen Prozessor auf einen Tastendruck neustarten, damit die Werte aus dem EEPROM neu gelesen werden, Variablen wieder auf den Initialisierungswert am Anfang gesetzt werden usw. Gelesen habe ich, dass das mit dem Watchdog geht - aber den wollte ich eigentlich nicht nehmen. Habe Angst, dass ich dann unkontrollierte/ungewollte Resets hinzubekomme. asm volatile ("RJMP 0") tut auch nix. Gibt es noch eine Möglichkeit ohne externe Beschaltung? Ciao Tobias
Auf Tastendruck schaltest du den Watchdog ein, fertig. Warum sollte da was ungewollt kommen?
Wer sagt denn, daß Du den EEPROM nur nach nem Reset lesen darfst und die Variablen nur nach einem Reset schreiben ??? Du darfst das alles immer und zu jeder Zeit machen. Ein Reset mag ich nicht, da dann alle Port kurz auf hochohmig gehen. Peter
nein, lesen und schreiben darf ich immer. aber die komplette Initialisierung aufs neue würde ich mir sparen. Halt ein Knopfdruck, Neustart und alles ist wieder, als hätte ich gerade erst den Strom angeschlossen. Wie rücksetzen auf Werkszustand. Auf Tastendruck erst den Watchdog einschalten, so einfach und doch effektiv, das hätte was. Habe die ganze Zeit gedacht, ich müsste den Watchdog einschalten, immer schön resetten und für einen gewollten Reset dann einfach mal den Reset des Watchdog "vergessen" - aber auf deine einfache Idee bin ich nicht gekommen! :-) Manchmal steht man einfach auf dem Schlauch... Danke! Ciao Tobias
>>Es soll Leute geben, die den Reset-Taster am Resetpin anschließen. Zitat von mir: >>>"Gibt es noch eine Möglichkeit ohne externe Beschaltung?" Ich habe eine Art Tastatur und ein Display und man soll quasi einen Menüpunkt auswählen können, der den Neustar bewirkt.
1 | #include <avr/wdt.h> //Watchdog |
2 | |
3 | strcpy(ausgabetext,"Neustart?"); |
4 | lcd_ausgabe(1,ausgabetext); |
5 | if (bit_is_clear(PINB,PB2)) |
6 | {
|
7 | loop_until_bit_is_set(PINB,PB2); |
8 | wdt_enable(WDTO_15MS); |
9 | while(1); |
10 | }
|
tut bereits Wunderbar seinen Dienst.
strcpy(ausgabetext,"Neustart?"); ist aufgrund einer noch folgenden
Funktion nötig.
>Wie wäre es denn mit einem Jump zum Resetvektor ?
asm volatile ("RJMP 0")
Tut leider rein gar nix... Aber ich kann kein Assembler, ist der denn
überhaupt richtig?
Ciao Tobias
Ein RJMP 0, resetted die internen Register nicht. Weshalb sollte es? Zudem sollte die Schaltung so gebaut sein, dass die Pins tristate sein koennen, ohne das unkontrollierte oder schaedliche Zustaende eintreten. Dies, da es immer einen Zeitpunkt ohne Programm gibt. zB auch waehrend der Programmentwicklung. B.
RJMP 0 sollte bei jedem guten Programm funktionieren ... (und C-Compiler sollten ja eigentlich guten code produzieren) Denn jedes Register sollte mit einem Wert geladen werden bevor es benutzt wird. Du kannst natürlich auch am start des controllers alle register auf 0 setzen (mit Pointer und SRAM zugriff)
>auch am start des controllers alle register auf 0 setzen
Vorsicht: Nicht für alle Register ist der Wert nach einem Hardwarereset,
d.h. der Soll-Startwert, identisch mit dem Wert 0!
Ein RJMP 0 wird da natürlich nicht gehen. Das R steht ja für "Relativ". Die 0 bezeichnen den Offset zur momentanen Position im Programm. Ein RJMP 0 ist daher kein Sprung zur absoluten Adresse 0, sondern ein Sprung .... zur Anweisung nach dem RJMP 0. Wenn schon, dann muss das ein normaler JMP sein und kein relativer.
Hi, wobei WinAVR20060421 aus "RJMP 0" alles mögliche macht, nur keinen Sprung auf den nächsten Befehl :) Bsp
1 | #include <avr/io.h> |
2 | #include <avr/interrupt.h> |
3 | |
4 | |
5 | ISR(TIMER0_COMP_vect) |
6 | {
|
7 | }
|
8 | |
9 | |
10 | ISR(TIMER0_OVF_vect) |
11 | {
|
12 | }
|
13 | |
14 | |
15 | int main(void) |
16 | {
|
17 | asm volatile ("RJMP 0"::); |
18 | while(1); |
19 | }
|
wird zu
1 | @00000047: __vector_19 |
2 | ---- rjmp_tst.c ----------------------------------------------------------------------------------- |
3 | 6: { |
4 | +00000047: 921F PUSH R1 Push register on stack |
5 | +00000048: 920F PUSH R0 Push register on stack |
6 | +00000049: B60F IN R0,0x3F In from I/O location |
7 | +0000004A: 920F PUSH R0 Push register on stack |
8 | +0000004B: 2411 CLR R1 Clear Register |
9 | +0000004C: 900F POP R0 Pop register from stack |
10 | +0000004D: BE0F OUT 0x3F,R0 Out to I/O location |
11 | +0000004E: 900F POP R0 Pop register from stack |
12 | +0000004F: 901F POP R1 Pop register from stack |
13 | +00000050: 9518 RETI Interrupt return |
14 | @00000051: __vector_9 |
15 | 11: { |
16 | +00000051: 921F PUSH R1 Push register on stack |
17 | +00000052: 920F PUSH R0 Push register on stack |
18 | +00000053: B60F IN R0,0x3F In from I/O location |
19 | +00000054: 920F PUSH R0 Push register on stack |
20 | +00000055: 2411 CLR R1 Clear Register |
21 | +00000056: 900F POP R0 Pop register from stack |
22 | +00000057: BE0F OUT 0x3F,R0 Out to I/O location |
23 | +00000058: 900F POP R0 Pop register from stack |
24 | +00000059: 901F POP R1 Pop register from stack |
25 | +0000005A: 9518 RETI Interrupt return |
26 | @0000005B: main |
27 | 16: { |
28 | +0000005B: E5CF LDI R28,0x5F Load immediate |
29 | +0000005C: E0D4 LDI R29,0x04 Load immediate |
30 | +0000005D: BFDE OUT 0x3E,R29 Out to I/O location |
31 | +0000005E: BFCD OUT 0x3D,R28 Out to I/O location |
32 | 17: asm volatile ("RJMP 0"::); |
33 | +0000005F: CFE7 RJMP PC-0x0018 Relative jump |
34 | 18: while(1); |
35 | +00000060: CFFF RJMP PC-0x0000 Relative jump |
Wie man sieht geht der Sprung zur Adresse von 'TIMER0_COMP_vect'! Wenn ich die Interuptroutinen auskommentiere springt er übrigens auf den Anfang von main. CU Frank
Hi, nach einigen weiteren Tests ist klar was passiert. Bei "RJMP 0" springt er immer auf den ersten generierten Code der aktuellen 'Compilation Unit' (sprich dem C-File in dem der RJMP steht). Kann man sicher ganz witzige Programme mit schreiben, ist aber wohl meist nicht das was will. CU Frank BTW: WinAVR20070122 scheints übrigens genauso zu machen
FBI wrote: > nach einigen weiteren Tests ist klar was passiert. Bei "RJMP 0" springt > er immer auf den ersten generierten Code der aktuellen 'Compilation > Unit' (sprich dem C-File in dem der RJMP steht). > Kann man sicher ganz witzige Programme mit schreiben, ist aber wohl > meist nicht das was will. Ja, dieser Bug ist eigentlich schon lange bekannt. 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.