Forum: Mikrocontroller und Digitale Elektronik WD-Reset und Reset Pin erzeugen nicht das selbe wie Power off


von langstrumpf (Gast)


Lesenswert?

Guten Abend,
ich habe ein für mich unerklärbares Phänomen.
Ich habe einen AT90Can128 auf dem ich einen CanopenStack laufen habe.
Nun wenn ich ein Reset Node empfange und mittels Endlosschleife den WD 
zubeißen lassen will dann Startet der MC nicht mehr.Das selbe wenn ich 
den Reset Pin auf Gnd ziehe startet der Mc auch nicht mehr. Wenn ich die 
Versorgung Toggle dann funktioniert alles wieder bestens.
Ich habe aber absolut keinen Plan wie ich hinter den Fehler steigen 
kann.
Der Debugger funktioniert nicht in diesem Zustand.
Was habt ihr für Ideen?

Danke für die Hilfe

von c-hater (Gast)


Lesenswert?

langstrumpf schrieb:

> Ich habe aber absolut keinen Plan wie ich hinter den Fehler steigen
> kann.

Dann mach' dir einen.

Der fängt damit an, dass du dir über die Unterschiede zwischen einem 
powercycle und einem reset klar wirst. Denn nach den Gesetzen der Logik 
muss irgendwie aus diesen Unterschieden letzlich das Problem 
resultieren...

von Einer K. (Gast)


Lesenswert?

langstrumpf schrieb:
> Nun wenn ich ein Reset Node empfange und mittels Endlosschleife den WD
> zubeißen lassen will dann Startet der MC nicht mehr.Das selbe wenn ich
> den Reset Pin auf Gnd ziehe startet der Mc auch nicht mehr. Wenn ich die
> Versorgung Toggle dann funktioniert alles wieder bestens.

Mein Glaskugel sagt:
Du hast vergessen, als allererstes in deinem Programm den WDT 
abzuschalten.
Denn der wird NICHT automatisch beim normalen Reset abgeschaltet.

von langstrumpf (Gast)


Lesenswert?

c-hater schrieb:
> Der fängt damit an, dass du dir über die Unterschiede zwischen einem
> powercycle und einem reset klar wirst. Denn nach den Gesetzen der Logik
> muss irgendwie aus diesen Unterschieden letzlich das Problem
> resultieren...

Danke für die Hilfe.
Ich war bis Heute der Meinung das Reset und powercycle das selbe 
bewirkt.
Wo können die Unterschiede sein?
Wie kann ich sowas debuggen?

Lg

von Stefan F. (Gast)


Lesenswert?

langstrumpf schrieb:
> Wo können die Unterschiede sein?

Hat Arduino Fanboy geschrieben.

Wenn da noch andere aktive Komponenten in deiner Schaltung sind, kann es 
auch an denen liegen. Oder auch am Programm, dass bei Start vielleicht 
auf eine bestimmte Signalkombination wartet.

> Wie kann ich sowas debuggen?

Hängt vom Code und der Schaltung ab.

von langstrumpf (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Mein Glaskugel sagt:
> Du hast vergessen, als allererstes in deinem Programm den WDT
> abzuschalten.
> Denn der wird NICHT automatisch beim normalen Reset abgeschaltet.

Guten Abend.
Wie meinst du das? Bleibt der WD aktiv nach zubeißen?
Muss ich also den WD al erstes ausschalten vor der Initialisierung der 
Hardware?
Danke für die Hilfe

von Einer K. (Gast)


Lesenswert?

langstrumpf schrieb:
> Wie meinst du das? Bleibt der WD aktiv nach zubeißen?
> Muss ich also den WD al erstes ausschalten vor der Initialisierung der
> Hardware?

Natürlich!
Der Vorteiler des WDT wird gelöscht, auf kleinsten Wert.
Und du kommst mit aktiven WDT aus dem Reset.

Und ja, der bleibt aktiv.

Ja, das tut er.

von Stefan F. (Gast)


Lesenswert?

langstrumpf schrieb:
> Bleibt der WD aktiv nach zubeißen?

Ja, das steht so im Datenblatt.

> Muss ich also den WD al erstes ausschalten vor der
>  Initialisierung der Hardware?

Ja und auch das steht im Datenblatt.

Warum benutzt due Funktionseinheiten, bevor du ihre Dokumentation 
gelesen hast?

> Wie kann ich sowas debuggen?

Hast du überhaupt einen Debugger? Kannst du damit umgehen? Wenn nicht, 
besorge einen und über an einem funktionierenden Objekt.

von c-hater (Gast)


Lesenswert?

langstrumpf schrieb:

> Ich war bis Heute der Meinung das Reset und powercycle das selbe
> bewirkt.

Nö. Wie du ganz praktisch ja sehen kannst...

> Wie kann ich sowas debuggen?

Durch DB-Lesen und Denken.

Aber der Fanboy hat dir immerhin schon einen möglichen Tip gegeben. Es 
gibt aber noch mehr Unterschiede zwischen den beiden Situationen.

von langstrumpf (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> langstrumpf schrieb:
>> Wie meinst du das? Bleibt der WD aktiv nach zubeißen?
>> Muss ich also den WD al erstes ausschalten vor der Initialisierung der
>> Hardware?
>
> Natürlich!
> Der Vorteiler des WDT wird gelöscht, auf kleinsten Wert.
> Und du kommst mit aktiven WDT aus dem Reset.
>
> Und ja, der bleibt aktiv.
>
> Ja, das tut er.

Danke für die Hilfe!
Habe das Datenblatt was den WD angeht nicht gelesen.
Hatte nur den Artikel 
https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_Watchdog 
gelesen.
Ist aber keine Entschuldigung.
Danke für die Hilfe

von Stefan F. (Gast)


Lesenswert?

langstrumpf schrieb:
> Hatte nur den Artikel
> https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_Watchdog
> gelesen.

Und da steht klipp und klar:

"Bei neueren AVR-Typen bleibt der Watchdog auch nach einem Reset durch 
den Watchdog aktiviert. Wenn ein Programm nach dem Neustart bis zur 
erstmaligen Rückstellung des Watchdogs länger braucht, als die im 
Watchdog eingestellte Zeit, sollte man den Watchdog explizit möglichst 
früh deaktivieren. Ansonsten resetet der Watchdog den Controller 
immerfort von Neuem. Die frühe Deaktivierung sollte durch eine Funktion 
erfolgen, die noch vor allen anderen Operationen (insbesondere vor dem 
mglw. länger andauernden internen Initialisierungen vor dem Sprung zu 
main()) ausgeführt wird. "

Noch Fragen?

Immer schön bis zum Ende lesen! Das gilt ganz besonders für 
Datenblätter, denn oben kommt die Werbung, dann die schöne heile Welt 
und erst zum Schluss die hässliche Wahrheit.

von langstrumpf (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Noch Fragen?
>
> Immer schön bis zum Ende lesen! Das gilt ganz besonders für
> Datenblätter, denn oben kommt die Werbung, dann die schöne heile Welt
> und erst zum Schluss die hässliche Wahrheit.

Oh Gott erwischt:-D

Diese Analyse der Datenblätter muss ich mir merken!
Vielen Dank!!!

von Peter D. (peda)


Lesenswert?

Gerne setzt man den Watschdog so früh wie möglich (z.B. in .init1) auf 
2s, das sollte für den Init-Kram reichen, bis man in die Mainlooop 
kommt.
2s ist auch eine schöne Zeit, um zu bemerken, daß der Watchdog 
zugeschlagen hat. Bei nur 15ms legt man sich oft die Karten, warum das 
Programm verrückte Sachen macht.
Man kann auch den Resetgrund auslesen und anzeigen, welche Quelle den 
Reset ausgelöst hat. Insbesondere, wenn kein Flag gesetzt ist, d.h. das 
Programm durch zerstörte Pointer über 0x0000 gelaufen ist, sollte man 
das anzeigen.
Es sollen schon Leute wochenlang solche Fehler gesucht haben.

Will man den Watchdog benutzen, sollte man ihn immer per Fusebit 
enablen. Ein schlafender Watchdog (disabled) bietet keine zusätzliche 
Sicherheit.

: Bearbeitet durch User
von langstrumpf (Gast)


Lesenswert?

Ich muss leider noch mal Eure Hilfe in Anspruch nehem.
Die Funktion wdt_disable(); Funktioniert bei mir und meinem At90 Can128 
nicht.
Ich im Datenblatt steht
1
/* Write logical one to WDCE and WDE */
2
  WDTCR = (1<<WDCE) | (1<<WDE);
3
  /* Turn off WDT */
4
  WDTCR = 0x00;

Aber auch diese Funktion lässt das Programm nicht starten wenn der WD 
einmal zugebissen hat.
Was mache ich falsch? Was Überlese ich?
Die Fuse des WD ist aus.

von Stefan F. (Gast)


Lesenswert?

Hast du davo irgendeine Initialisierung die lange dauert? Vielleicht 
auch in einer init-Sektion anstall in main()?

von langstrumpf (Gast)


Angehängte Dateien:

Lesenswert?

Stefan ⛄ F. schrieb:
> Hast du davo irgendeine Initialisierung die lange dauert? Vielleicht
> auch in einer init-Sektion anstall in main()?

Hallo und Danke für die Hilfe.
Nein eigendlich mache ich das als erstes.

Habe mal zwei Bilder angehängt

von Einer K. (Gast)


Lesenswert?

langstrumpf schrieb:
> Nein eigendlich mache ich das als erstes.

Also nicht als erstes!

Lesestoff: AVR .init section

Dort!


Auch ist das Timing wichtig.
Das kann schon mal ins Auge gehen, je nach Optimierungsstufe.
evtl ist das Makro wdt_disable() besser geeignet, als das händisch zu 
tun.

von HildeK (Gast)


Lesenswert?

langstrumpf schrieb:
> Habe mal zwei Bilder angehängt

Ich habe in altem Code dieses hier gefunden:
1
WDTCR |= (1<<WDCE) | (1<<WDE);  // timed Sequence
2
WDTCR &= ~(1<<WDE);        // oder auch WDTCR = 0;

von Stefan F. (Gast)


Lesenswert?

Meinst du nicht, dass es langsam mal Zeit, wird, den ganzen Quelltext zu 
zeigen, anstatt immer nur um den Stein der Weisen zu diskutieren und 
unzureichende Fotos zu machen?

von langstrumpf (Gast)


Angehängte Dateien:

Lesenswert?

Stefan ⛄ F. schrieb:
> Meinst du nicht, dass es langsam mal Zeit, wird, den ganzen Quelltext zu
> zeigen, anstatt immer nur um den Stein der Weisen zu diskutieren und
> unzureichende Fotos zu machen?

Kann ich nicht da der Can Stack Kommerziell ist und ich diesen nicht 
veröffentlichen darf.

1
uint8_t mischer_state=0;
2
uint16_t time_Umwaelzen=0,time_Move_Mischer=0,dummy;
3
uint8_t sollmin=35,sollmax=38,_regler=0,_regler_max=0;
4
uint16_t umaeltz_zeit=480,regelintervall_zeit=180;
5
uint16_t closetime=3500,opentime=3000,closetime_fast=7000,opentime_fast=6000;
6
uint8_t i2c_input,output=0;
7
uint8_t paul=200;
8
volatile uint8_t backup_mcusr;
9
10
/* local defined variables*/
11
void code_init0(void) __attribute__ ((naked, used, section (".init3")));
12
13
/* !!! never call this function !!! */
14
void code_init0 (void)
15
{
16
  WDTCR = (1<<WDCE) | (1<<WDE);
17
  /* Turn off WDT */
18
  WDTCR = 0x00;
19
  backup_mcusr = MCUSR;
20
}
21
22
23
24
int main(void)
25
{
26
  /* Write logical one to WDCE and WDE */
27
  
28
    //wdt_disable();
29
  PORTA = 0xff;
30
  DDRB = 0xff;
31
  DDRC =0xff;
32
  DDRE |= (1<<Out_Runled)|(1<<Out_Sitz_senken)|(1<<DiagEnable_Steckdose_X5);
33
  //PORTE |=(1<<Status_Sitz_heben)|(1<<Status_Sitz_senken)|(1<<End_Sitz_unten)|(1<<D_PLUS);
34
  PORTG |=(1<<INPUT_10)|(1<<INPUT_11)|(1<<INPUT_12);
35
  PORTF |=(1<<INPUT_1);


ISt das so richtig?

Danke für die Hilfe

von Stefan F. (Gast)


Lesenswert?

langstrumpf schrieb:
> ISt das so richtig?

Das ergibt sich aus dem Assembler Listing. Warum benutzt du immer noch 
nicht das Makro aus der avr-libc?

Bei deinem C Code weisst du nie, was der Compiler daraus macht, 
insbesondere und ob er das geforderte Timing einhält. Das Makro sieht 
nicht zum Spaß ganz anders aus: 
https://www.nongnu.org/avr-libc/user-manual/group__avr__watchdog.html

von W.S. (Gast)


Lesenswert?

langstrumpf schrieb:
> Ich war bis Heute der Meinung das Reset und powercycle das selbe
> bewirkt.
> Wo können die Unterschiede sein?
> Wie kann ich sowas debuggen?

1. Es ist eben nicht dasselbe. Das hättest du im Manual nachlesen 
können.
2. Die Unterschiede bestehen darin, daß der generelle Zustand des Chips 
nach verschiedenene Arten des Resets eben unteschiedlich ist.
3. garnicht.

Bei einigen Chips (z.B. manchen Kinetis) besteht der einzige Weg, 
überhaupt bis zu main() zu kommen darin, den WD als allererstes 
auszuschalten.

Mein Reden seit ewig ist deshalb, immer beim Anlauf des µC davon 
auszugehen, daß man alles und jedes selbst aufsetzen soll - ohne davon 
auszugehen, daß irgend ein Register einen Resetwert enthält.

W.S.

von Stefan F. (Gast)


Lesenswert?

W.S. schrieb:
> immer beim Anlauf des µC davon
> auszugehen, daß man alles und jedes selbst aufsetzen soll - ohne davon
> auszugehen, daß irgend ein Register einen Resetwert enthält.

Anstatt von irgend etwas auszugehen, orientiere ich mich am Datenblatt 
bzw. Referenzhandbuch. Darin sind die Zustände nach dem Reset (bzw. den 
unterschiedlichen Reset-Varianten falls vorhanden) unmissverständlich 
beschrieben.

von W.S. (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Anstatt von irgend etwas auszugehen

Da sprichst du mir zwar aus der Seele, aber die Realität sieht genau 
anders herum aus. Da wird das Manual als viel zu lästig angesehen, 
irgendwelche Vorkennnisse werden ebenfalls als überflüssig (und zu 
schwer zu erlernen) erachtet und man will sofort!!!!! mit seinem XYZ 
zum Mond fliegen, ohne jemals das Laufen (geschweige denn das Fliegen) 
erlernt zu haben.

Was darf man da noch erwarten?

W.S.

von Stefan F. (Gast)


Lesenswert?

Wenn alle andere Idioten sind, sollte man mal darüber nachdenken, wer 
hier der Geisterfahrer ist.

Ehrlich Mann, halte dich doch mal mit solchen Worten zurück! Du kennst 
die Leute nicht. Hast du nur zwei Schubladen (Ich und die doofen), oder 
welches Bild willst du nach außen abgeben?

von langstrumpf (Gast)


Lesenswert?

Hallo
1
/* local defined variables*/
2
void code_init0(void) __attribute__ ((naked, used, section (".init0")));
3
4
/* !!! never call this function !!! */
5
void code_init0 (void)
6
{
7
  wdt_disable();
8
}
9
10
11
12
int main(void)
13
{
14
  /* Write logical one to WDCE and WDE */
15
  
16
    //wdt_disable();
17
  PORTA = 0xff;
18
  DDRB = 0xff;
19
  DDRC =0xff;
20
  DDRE |= (1<<Out_Runled)|(1<<Out_Sitz_senken)|(1<<DiagEnable_Steckdose_X5);
21
  //PORTE |=(1<<Status_Sitz_heben)|(1<<Status_Sitz_senken)|(1<<End_Sitz_unten)|(1<<D_PLUS);
22
  PORTG |=(1<<INPUT_10)|(1<<INPUT_11)|(1<<INPUT_12);
23
  PORTF |=(1<<INPUT_1);
24
  // Timer0 config
25
  OCR0A = (uint8_t

Ist es so korrekt wie ich es mit der init section mache ?

Warum Funktioniert es nicht so wie es im Datenblatt steht?


Das Ergebnis ist das selbe.

Danke für die Hilfe

von Stefan F. (Gast)


Lesenswert?

langstrumpf schrieb:
> Ist es so korrekt wie ich es mit der init section mache ?

Du hast es immer noch nicht so gemacht, wie in der Doku der avr-libc 
beschrieben. Ist das denn so schwer, die paar Zeilen code zu kopieren?

So gehört das!:
1
uint8_t mcusr_mirror __attribute__ ((section (".noinit")));
2
void get_mcusr(void) \
3
  __attribute__((naked)) \
4
  __attribute__((section(".init3")));
5
void get_mcusr(void)
6
{
7
  mcusr_mirror = MCUSR;
8
  MCUSR = 0;
9
  wdt_disable();
10
}

Oder so, wenn du die Reset-Quelle weiterhin nicht auswerten willst (aber 
genau das wolltest du doch):
1
void was_auch_immer(void) \
2
  __attribute__((naked)) \
3
  __attribute__((section(".init3")));
4
void was_auch_immer(void)
5
{
6
  MCUSR = 0;
7
  wdt_disable();
8
}

langstrumpf schrieb:
> Warum Funktioniert es nicht so wie es im Datenblatt steht?

Das ergibt sich aus dem Assembler-Listung, das du immer noch nicht
gezeigt hast. Du sollst vergleichen, was der C-Compiler aus dem
Quelltext gemacht hat, mit dem was im Datenblatt steht.

Beitrag #6198101 wurde von einem Moderator gelöscht.
von langstrumpf (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Du hast es immer noch nicht so gemacht, wie in der Doku der avr-libc
> beschrieben. Ist das denn so schwer, die paar Zeilen code zu kopieren?

Ja leider weiß ich nicht wie ich den Code in meinen Code einbauen muss.
Bitte erkläre es mir.
1
uint8_t mcusr_mirror __attribute__ ((section (".noinit")));
2
void get_mcusr(void) \
3
__attribute__((naked)) \
4
__attribute__((section(".init3")));
5
6
7
int main(void)
8
{
9
  
10
  void get_mcusr(void)
11
  {
12
    mcusr_mirror = MCUSR;
13
    MCUSR = 0;
14
    wdt_disable();
15
  }
16
  
17
    //wdt_disable();
18
  PORTA = 0xff;
19
  DDRB = 0xff;

Ist die Position des Macros an der richtigen stelle

Ich hatte Dir das ASM File im Beitrag 
Beitrag "Re: WD-Reset und Reset Pin erzeugen nicht das selbe wie Power off"
angehängt und ich war der Überzeugung das es so wie im Datenblatt 
aussieht.



Danke für deine Hilfe und Geduld

von Stefan F. (Gast)


Lesenswert?

Einfach rein kopieren, nicht einbauen. Funktionen in der init Sektion 
werden automatisch vor main() ausgeführt.

> Ist die Position des Macros an der richtigen stelle.

nein

Du sollst das so machen:
1
#include <stdint.h>
2
#include <avr/wdt.h>
3
4
uint8_t mcusr_mirror __attribute__ ((section (".noinit")));
5
void get_mcusr(void) \
6
  __attribute__((naked)) \
7
  __attribute__((section(".init3")));
8
9
void get_mcusr(void)
10
{
11
  mcusr_mirror = MCUSR;
12
  MCUSR = 0;
13
  wdt_disable();
14
}
15
16
int main(void)
17
{
18
   ....
19
}

von Stefan F. (Gast)


Lesenswert?

langstrumpf schrieb:
> Ich hatte Dir das ASM File im Beitrag
> Beitrag "Re: WD-Reset und Reset Pin erzeugen nicht das selbe wie Power
> off" angehängt und ich war der Überzeugung das es so wie im Datenblatt
> aussieht.

Erstens entspricht das nicht dem aktuelle Stand deines Codes. Zweitens 
sieht es ganz anders aus, als im Datenblatt beschrieben. Ich zitiere 
auch das mal für dich:
1
WDT_off:
2
    ; Write logical one to WDCE and WDE
3
    ldi   r16,   (1<<WDCE)|(1<<WDE)
4
    sts   WDTCR,   r16
5
6
    ; Turn off WDT
7
    ldi   r16,   (0<<WDE)
8
    sts   WDTCR,   r16
9
10
    ret
1
void WDT_off(void){
2
    /* Write logical one to WDCE and WDE */
3
    WDTCR = (1<<WDCE) | (1<<WDE);
4
5
    /* Turn off WDT */
6
    WDTCR = 0x00;
7
}

In deinem C Quelltext (und dem daraus resultierenden Assembler Listing) 
steht aber:
1
WDTCR=x00;

Siehst du nicht, dass da eine komplette Zeile fehlt?

Außerdem gibt es einen Unterschied zwischen den Sektionen init0 und 
init3. Siehe 
https://www.nongnu.org/avr-libc/user-manual/mem_sections.html

Init 0, 1 und 2, da ist der Stackpointer noch nicht initialisiert. Du 
darfst zudem nur die Sektionen nutzen, die als "User definable." 
gekennzeichnet sind.

Das hat schon seinen Grund, dass die Beispiele init3 benutzen.

von Stefan F. (Gast)


Lesenswert?

Mal eine ganz andere Frage: Warum benutzt du den Watchdog?

Normalerweise laufen Mikrocontroller jahrelang fehlerfrei ohne Watchdog. 
Du machst Dir mit dem Ding das Leben nur unnötig schwer, weil er (wie du 
siehst) eine Dinge verkompliziert und zudem gravierende Programmfehler 
kaschiert, die man lieber korrigieren sollte.

Du willst doch auch nicht deinen PC jeden Tag rebooten müssen (weil die 
Softwarehersteller schlampig arbeiten), wie zu Windows 95 Zeiten.

von langstrumpf (Gast)


Lesenswert?

Hier ist irgendwie der Wurm drin.
Im Anhang das Asm.
Ich habe es so gemacht wie du es geschrieben hast aber das Ergebnis ist 
immer noch das selbe.

Stefan ⛄ F. schrieb:
> Mal eine ganz andere Frage: Warum benutzt du den Watchdog?
>
> Normalerweise laufen Mikrocontroller jahrelang fehlerfrei ohne Watchdog.
> Du machst Dir mit dem Ding das Leben nur unnötig schwer, weil er (wie du
> siehst) eine Dinge verkompliziert und zudem gravierende Programmfehler
> kaschiert, die man lieber korrigieren sollte.

Der code funktioniert ja auch gut.
Es ist nur so das der Canmaster in der Lage sein will einen Reset der 
Slaves auszuführen.
Dazu habe ich den WD gebraucht. Und deshalb ärgere ich mich mit 
selbigen.

Danke für deine Hilfe

von Stefan F. (Gast)


Lesenswert?

langstrumpf schrieb:
> Im Anhang das Asm.

Ich sehe keinen Anhang. Den C-Quelltext solltest du auch zeigen, wenn du 
über konkreteres als heiße Luft diskutieren möchtest.

von Stefan F. (Gast)


Lesenswert?

langstrumpf schrieb:
> Es ist nur so das der Canmaster in der Lage sein will einen Reset der
> Slaves auszuführen. Dazu habe ich den WD gebraucht.

Klingt für mich nach einem schweren Designfehler. Der Watchdog ist für 
etwas anderes vorgesehen.

von langstrumpf (Gast)


Angehängte Dateien:

Lesenswert?

Sorry

Hier die Dateien

von Stefan F. (Gast)


Lesenswert?

Bitte nicht schon wieder Screenshots! Die zeigen doch wieder nur einen 
kleinen Ausschnitt!

Sieht gut aus. Funktioniert es denn jetzt?

Wenn nicht, bist du ganz sicher, dass dein Problem überhaupt vom 
Watchdog kommt? Wenn du unsicher bist, dann aktiviere ihn mal zur Probe 
nicht.

von langstrumpf (Gast)


Angehängte Dateien:

Lesenswert?

Stefan ⛄ F. schrieb:
> Bitte nicht schon wieder Screenshots!

Also Hier der Code
1
uint8_t mcusr_mirror __attribute__ ((section (".noinit")));
2
void get_mcusr(void) \
3
  __attribute__((naked)) \
4
  __attribute__((section(".init3")));
5
6
void get_mcusr(void)
7
{
8
  mcusr_mirror = MCUSR;
9
  MCUSR = 0;
10
  wdt_disable();
11
}
12
13
14
int main(void)
15
{
16
  
17
  
18
  PORTA = 0xff;
19
  DDRB = 0xff;
20
  DDRC =0xff;
21
  DDRE |= (1<<Out_Runled)|(1<<Out_Sitz_senken)|(1<<DiagEnable_Steckdose_X5);
22
  //PORTE |=(1<<Status_Sitz_heben)|(1<<Status_Sitz_senken)|(1<<End_Sitz_unten)|(1<<D_PLUS);
23
  PORTG |=(1<<INPUT_10)|(1<<INPUT_11)|(1<<INPUT_12);
24
  PORTF |=(1<<INPUT_1);
25
  // Timer0 config

von langstrumpf (Gast)


Lesenswert?

Es funktioniert nicht.
Wenn ich die Endlosschleife für mein Softreset entferne dann 
funktioniert der Sprung in die Funktion des Softreset und das Programm 
läuft weiter.
Wie sonst kann man bei Avr einen Soft Reset erzeugen?

Lg

von langstrumpf (Gast)


Lesenswert?

1
if ((execute==CO_TRUE)&&(newState==CO_NMT_STATE_RESET_NODE))
2
  {
3
    while(1)
4
    {
5
      if (get_edge(newState == CO_NMT_STATE_RESET_NODE)==RISE)
6
      {
7
        printf("reset in 2s\r\n");
8
      }
9
    }
10
  }

Hier wird im der NMT Auswertung der Reset erzeugt

von Stefan F. (Gast)


Lesenswert?

langstrumpf schrieb:
> Wie sonst kann man bei Avr einen Soft Reset erzeugen?

Jetzt kommen wir zur eigentliche Frage. Heiliger Bimbam.

Der einfachste Weg ist: Verbinde den RESET Eingang mit einem I/O Pin und 
schalte diesen auf LOW.

Der elegante Weg geht über den Watchdog, aber das klappt bei Dir nicht. 
Also musst du jetzt heraus finden, warum es nicht klappt. Mit einem 
Debugger wird das vermutlich sehr viel schneller klappen, als mit 
diskutieren.

von (prx) A. K. (prx)


Lesenswert?

Stefan ⛄ F. schrieb:
>> Es ist nur so das der Canmaster in der Lage sein will einen Reset der
>> Slaves auszuführen. Dazu habe ich den WD gebraucht.
>
> Klingt für mich nach einem schweren Designfehler. Der Watchdog ist für
> etwas anderes vorgesehen.

Er ist zwar nicht eigens dafür vorgesehen. Aber es kann mitunter recht 
nützlich sein, wenn sich ein µC selbst zurücksetzen kann. Da ein AVR 
dafür keinen eigenen Befehl hat, spricht wenig dagegen, dafür den WDT zu 
verwenden.

von Jens G. (jensg)


Lesenswert?

mit einer solchen Funktion habe ich ein Reset ausgelöst.
1
void reboot() {
2
  MCUSR = 0;
3
  wdt_disable();
4
  wdt_enable(WDTO_15MS);
5
  while (1) {}
6
}

Sorry, ich habe es in der Umgebung von Arduino so gemacht.

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Jens G. schrieb:
> Sorry, ich habe es in der Umgebung von Arduino so gemacht.

Da kommt die nächste Salamischeibe. Das hättest du ganz am Anfang 
schreiben sollen! Arduino benutzt die Init Sektionen und die main() 
Funktion nämlich auf ihre spezielle Art. Da sind die konkreten Infos 
allerding nicht so leicht zu finden. Wie dem auch sei, bei Arduino ist 
es nicht vorgesehen, dass du als Anwendungsprogrammierer die init 
Sektionen benutzt.

Mein Tipp, um das Ganze abzukürzen: Verzichte darauf, den Watchdog zu 
deaktivieren.Lasse ihn immer laufen, aber mit einem wesentlich größeren 
Zeitfenster, z.B. 200ms. Dann hast du reichlich Zeit, ihn in deinem 
Programm regelmäßig zu resetten, so dass er neben deinem Anwendungsfall 
auch seiner Hauptaufgabe nachkommen kann (unbeabsichtigte Hänger zu 
erkennen).

von Jens G. (jensg)


Lesenswert?

Stefan ⛄ F. schrieb:
> Jens G. schrieb:
>> Sorry, ich habe es in der Umgebung von Arduino so gemacht.
> Dann hast du reichlich Zeit, ihn in deinem
> Programm regelmäßig zu resetten, so dass er neben deinem Anwendungsfall
> auch seiner Hauptaufgabe nachkommen kann (unbeabsichtigte Hänger zu
> erkennen).
Ich bin ein wenig ein "Dummy" auf diesem Gebiet - verwende den Watchdog 
eigentlich gar nicht. "Wie man ein Watchdog in Arduino regelmäßig 
resettet" ist mir völlig unbekannt. Das Stück Software, das ich 
vorgeschlagen habe. Macht das was soll -- den AVR rebooten - also ein 
Reset auslösen.

von Stefan F. (Gast)


Lesenswert?

Jens G. schrieb:
> Wie man ein Watchdog in Arduino regelmäßig
> resettet" ist mir völlig unbekannt

Dann lass die Finger vom Watchdog und benutze einen I/O Pin zum 
resetten.

von langstrumpf (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Jens G. schrieb:
>> Sorry, ich habe es in der Umgebung von Arduino so gemacht.
>
> Da kommt die nächste Salamischeibe. Das hättest du ganz am Anfang
> schreiben sollen! Arduino benutzt die Init Sektionen und die main()
> Funktion nämlich auf ihre spezielle Art. Da sind die konkreten Infos
> allerding nicht so leicht zu finden. Wie dem auch sei, bei Arduino ist
> es nicht vorgesehen, dass du als Anwendungsprogrammierer die init
> Sektionen benutzt.
>
> Mein Tipp, um das Ganze abzukürzen: Verzichte darauf, den Watchdog zu
> deaktivieren.Lasse ihn immer laufen, aber mit einem wesentlich größeren
> Zeitfenster, z.B. 200ms. Dann hast du reichlich Zeit, ihn in deinem
> Programm regelmäßig zu resetten, so dass er neben deinem Anwendungsfall
> auch seiner Hauptaufgabe nachkommen kann (unbeabsichtigte Hänger zu
> erkennen).

Ich verwende nicht Arduino.
Ich Verwende Gcc.
Ich habe in meinem Layout keinen Pin zum Reseten vorgesehn.

Stefan ⛄ F. schrieb:
> Mit einem
> Debugger wird das vermutlich sehr viel schneller klappen, als mit
> diskutieren.

Ich erkenne da nur das der Wd ein ist aber nicht wiso er sich nicht 
ausschalten lässt.
Was kann ich also mit dem Debugger konkret schauen was hilft?

Lg

von Jens G. (jensg)


Lesenswert?

Stefan ⛄ F. schrieb:
> Jens G. schrieb:
>> Wie man ein Watchdog in Arduino regelmäßig
>> resettet" ist mir völlig unbekannt
>
> Dann lass die Finger vom Watchdog und benutze einen I/O Pin zum
> resetten.
Ich hatte leider kein Pin mehr frei und hab es dann auf diese Weise 
gelöst.

von Jens G. (jensg)


Lesenswert?

langstrumpf schrieb:
> Ich verwende nicht Arduino.
> Ich Verwende Gcc.
> Ich habe in meinem Layout keinen Pin zum Reseten vorgesehn.
Es sollte auch ohne Arduino gehen.
https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_Watchdog

von Stefan F. (Gast)


Lesenswert?

Jens G. schrieb:
> Sorry, ich habe es in der Umgebung von Arduino so gemacht.

langstrumpf schrieb:
> Ich verwende nicht Arduino.

Wie ist das zu verstehen?

> Ich Verwende Gcc.

Das tut Arduino auch.

> Ich habe in meinem Layout keinen Pin zum Reseten vorgesehn.

Dann ändere das halt, oder lerne, deinen Watchdog zu debuggen. Meine 
Frage bezüglich des Debuggers hast du nicht beantwortet.

langstrumpf schrieb:
> Was kann ich also mit dem Debugger konkret schauen was hilft?

Du kannst nachschauen, ob der Code zum Ausschalten überhaupt ausgeführt 
wird und ob der WDT danach wirklich aus ist. Und wenn nicht, dann wirst 
du beim Durchsteppen schon sehen, woran es scheitert.

von Einer K. (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Wie dem auch sei, bei Arduino ist
> es nicht vorgesehen, dass du als Anwendungsprogrammierer die init
> Sektionen benutzt.
Was ist das denn für eine unsinnige Behauptung?

Stefan ⛄ F. schrieb:
> Arduino benutzt die Init Sektionen und die ...
> ... nämlich auf ihre spezielle Art.
Auch das ist falsch!

Die init Sections werden gar nirgendwo angefasst.
Im gesamten Arduino Core nicht.
Es wird die AVR-GCC Toolchain genutzt, und auch das dabei mit gelieferte 
Initverfahren.


Was soll das, solchen Blödsinn in die Welt zu setzen?
Bezahlt dich einer dafür?

von Stefan F. (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Bezahlt dich einer dafür?

Ja, ich werden von der Calliope GmbH dafür bezahlt, dich auf die Palme 
zu bringen. Ziel ist es, dich dazu zu bringen, Arduino zu verfluchen, 
damit du alle Arduino Jünger bekehrst und die Firma keine Konkurrenz 
mehr hat.

Aber um auf das technische Thema zurück zu kommen: Du hast sicher 
erkannt, was der TO falsch macht und kannst ihm zügig helfen...

mach mal.

von foobar (Gast)


Lesenswert?

Ein Hinweis, falls du den Arduino-Bootloader benutzt:

Die China-Arduinos haben häufig noch einen alten Bootloader, der den WDT 
nicht zurücksetzt.  Während er nun kurz wartet, ob evtl programmiert 
werden soll, schlägt der WDT wieder zu.  Der Effekt ist der von dir 
beschriebene.  Zu dem WDT-disable der Anwendung kommt er erst gar nicht.

von Einer K. (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Ja, ich werden von der Calliope GmbH dafür bezahlt ......
Da habe ich dich also bei einer dumm dreisten Arduino Bashing Lüge 
erwischt?
Oder hast du wirklich so wenig Ahnung von dem Zeugs, worüber du dauend 
herziehst?


Rückwärtsgang einlegen und Fehler eingestehen ist nicht drin?
Und damit auch keine Korrektur deines Verhaltens, für die Zukunft.
Richtig?



Stefan ⛄ F. schrieb:
> Aber um auf das technische Thema zurück zu kommen: Du hast sicher
> erkannt, was der TO falsch macht und kannst ihm zügig helfen...

Tja...
Habe gesagt, was ich weiß, und kann nicht testen, da der µC nicht vor 
mir liegt.

Kannste dir ein Beispiel dann nehmen.
Ich merke (hoffentlich meist) wenn ich von irgendwas KA habe und halte 
dann die Schnauze.

Wäre vielleicht auch mal was für dich.

foobar schrieb:
> Die China-Arduinos haben häufig noch einen alten Bootloader, der den WDT
> nicht zurücksetzt.
Durchaus möglich!
Wobei ich mir aber recht sicher bin, dass es keinen  AT90Can128 Arduino 
gibt.

von langstrumpf (Gast)


Lesenswert?

Ich habe nichts von einem Arduino gesagt:(

von Einer K. (Gast)


Lesenswert?

langstrumpf schrieb:
> Ich habe nichts von einem Arduino gesagt:(
Habe ich auch nichts von gehört....

Ist einfach nur eine Nebelkerze gewesen.
Und die Basher kommen dann sofort aus allen Ritzen.
Ist hier halt oft so.



Aber ...

Hast du denn einen Bootloader drauf?
Denn da kann der Hase im Pfeffer liegen.

von Stefan F. (Gast)


Lesenswert?

langstrumpf schrieb:
> Ich habe nichts von einem Arduino gesagt

Bist du nicht = Jens G?

Ich bin verwirrt.

von Einer K. (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Ich bin verwirrt.

In dem Punkt scheinst du recht zu haben.

von langstrumpf (Gast)


Lesenswert?

langstrumpf bin ich

von FabiWa (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Der einfachste Weg ist: Verbinde den RESET Eingang mit einem I/O Pin und
> schalte diesen auf LOW.

Ich habe mal gelernt, dass man das nicht tun sollte, da ein korrekter 
Reset dann nicht garantiert werden kann. Das Problem ist wohl, dass der 
RESET-Eingang dann unter Umständen nicht lang genug LOW ist.

Stattdessen sollte ein Reset-Generator verwendet werden, z.B. ein 
MAX701.

von langstrumpf (Gast)


Lesenswert?

Guten Morgen,
neuer Tag neues Glück;)
Können wir nochmal versuchen mein Problem zu lösen?

Also nochmal ein paar Fakten.
-At90Can128
-Keinen Arduino Bootloader oder etwas anderes von Arduino.
-Ich brauche den Watchdog für einen Softreset.
-Der Softreset funktioniert!
-Das Problem ist das nach dem auslösen des WD ich nicht in der lage bin 
den WD auszuschalten.
-Laut Beitrag "Re: WD-Reset und Reset Pin erzeugen nicht das selbe wie Power off" sieht das 
Assemblerfile gut aus.
-Also was kann ich nun tun das der Watchdog sich ausschalten lässt?
-Was kann ich noch Debuggen?

Danke für die Hilfe schönen gesunden Sonntag

von langstrumpf (Gast)


Angehängte Dateien:

Lesenswert?

Weitere erkenntnis.
Wenn ich die Optimierung aus schalte dann funktioniert das Ausschalten 
des WD.
Wenn ich Jedoch die Optimierung ganz normal auf Os schalte dann ist das 
Verhalten eine Endlosschleife die versucht den WD auszuschalten.

Im Anhang die zwei Bilder der ASM wobei "ich" keine Unterschiede sehe.

von Stefan F. (Gast)


Lesenswert?

FabiWa schrieb:
> Ich habe mal gelernt, dass man das nicht tun sollte, da ein korrekter
> Reset dann nicht garantiert werden kann. Das Problem ist wohl, dass der
> RESET-Eingang dann unter Umständen nicht lang genug LOW ist.

Ist mir noch  icht passiert, aber ja, klingt nachvollziehbar. Wobei ein 
kleiner Kondensator am Reset Pin (der ohnehin meist vorhanden ist) den 
Impuls ausreichend verlängern wird.

von Stefan F. (Gast)


Lesenswert?

langstrumpf schrieb:
> Was kann ich noch Debuggen?

Wie gesagt, prüfe ob der Code zum Ausschalten des Watchdogs überhaupt 
ausgeführt wird.

langstrumpf schrieb:
> Weitere erkenntnis.

Schon wieder Screenshots?!?! Bitte tue uns den Gefallen und benutze die 
Zwischenablage um Text zu posten.

von langstrumpf (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Wie gesagt, prüfe ob der Code zum Ausschalten des Watchdogs überhaupt
> ausgeführt wird.

Ja der Code wird ausgeführt. Ich kann durchsteppen mit dem Debugger

von Stefan F. (Gast)


Lesenswert?

langstrumpf schrieb:
> Ja der Code wird ausgeführt. Ich kann durchsteppen mit dem Debugger

Gezielte Suche bringt dich also nicht weiter. Das ist schade. Zeit für 
Plan B: Die Trial and Error Phase. Die beginnt mit der Annahme, dass die 
Fehlerursache irgendwo ganz woanders sein könnte.

Schreibe zur Gegenprobe mal ein minimales Programm, was in der Init 
Sektion zuerst eine LED einschaltet, dann den Watchdog deaktiviert, dann 
eine zweite LED einschaltet, dann in main() eine dritte LED einschaltet 
und dann den Reset auslöst. Der Watchdog soll dabei auf maximale Zeit 
(mindestens 200ms) konfiguriert sein, damit man was sehen kann. Dann 
schauen wir mal, welche LEDs wann angehen.

Außerdem hast du dann einen Quelltext, den du komplett vorzeigen kannst, 
dann hört die Raterei endlich auf.

Sollte das Problem mit so einem Minimalprogramm nicht nachvollziehbar 
sein, liegt die Problemursache sehr wahrscheinlich ganz woanders. Das 
kannst du weiter einkreisen, indem du Stückweise immer mehr von deinem 
großen Programm auskommentierst, bis der Fehler verschwindet.

von (prx) A. K. (prx)


Lesenswert?

Ist gesichert, dass der Watchdog auch wirklich die Ursache ist?

von Peter D. (peda)


Lesenswert?

langstrumpf schrieb:
> Wenn ich Jedoch die Optimierung ganz normal auf Os schalte dann ist das
> Verhalten eine Endlosschleife die versucht den WD auszuschalten.

Laß das asm Gefrickel, nimm wdt_disable() aus wdt.h.
Laß auch das mit der Init-Section, d.h. packe es an den Anfang des Main.

von Jens G. (jensg)


Lesenswert?

hier gibt es noch Informationen in deutsch:
https://www-user.tu-chemnitz.de/~heha/viewchm.php/hs/ATmegaX8.chm/11.htm

Wie auch immer, das Stück Software "reboot()" tut das was es sagt. Hat 
nichts damit zu tun ob man Arduino nutzt oder auch nicht. Ardino 
verwendet auch Routinen vom GCC.

von Stefan F. (Gast)


Lesenswert?

Jens G. schrieb:
> das Stück Software "reboot()" tut das was es sagt

Da liegt ja auch nicht das Problem, sondern beim Abschalten des Watchdog 
timers.

von OpenStack (Gast)


Lesenswert?

langstrumpf schrieb:
> Kann ich nicht da der Can Stack Kommerziell ist und ich diesen nicht
> veröffentlichen darf.

Doch, das darft du!

Du bist im uC-Net und fragst uns Experten. Quasi Kollegen. Du kannst ja 
später die Daten wieder löschen lassen. Ist so übrigens üblich 
vorzugehen.

von Einer K. (Gast)


Lesenswert?

langstrumpf schrieb:
> -Keinen Arduino Bootloader oder etwas anderes von Arduino.

Die Frage war:
OB du einen Bootloader verwendest!
Und nicht, welche Geschmacksrichtung er hat.

von langstrumpf (Gast)


Lesenswert?

Ich habe wie vorgeschlagen ein Minimalistisches Programm geschrieben.
Und Wie erwartet funktioniert es auch so wie es soll.

Wenn ich eine kleine State Maschine aus der Main auskommentiere dann 
funktioniert es auch in meinem Kompletten Programm.

Was im Himmels willen kann ein Switch Case Block  wo ein Paar Bits 
geschunkelt werden auf das WD ausschalten bewirken??

Peter D. schrieb:
> aß das asm Gefrickel, nimm wdt_disable() aus wdt.h.
> Laß auch das mit der Init-Section, d.h. packe es an den Anfang des Main.

Auch dein Vorschlag funktioniert wenn ich die oben genannte State 
Maschine aus kommentiere.

Versuche jetzt diese State Maschine weiter zu kürzen damit ich sie 
einstellen kann.

von Stefan F. (Gast)


Lesenswert?

langstrumpf schrieb:
> Was im Himmels willen kann ein Switch Case Block  wo ein Paar Bits
> geschunkelt werden auf das WD ausschalten bewirken??

Es könnte durchaus sein, dass die ganze Problematik mit dem Ausschalten 
des Watchdogs gar nichts zu tun hat.

von langstrumpf (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Es könnte durchaus sein, dass die ganze Problematik mit dem Ausschalten
> des Watchdogs gar nichts zu tun hat.

Wie meinst du das?

von Stefan F. (Gast)


Lesenswert?

langstrumpf schrieb:
> Stefan ⛄ F. schrieb:
>> Es könnte durchaus sein, dass die ganze Problematik mit dem Ausschalten
>> des Watchdogs gar nichts zu tun hat.
>
> Wie meinst du das?

Vielleicht hast du eine Race Condition. Irgend eine externe Bedingung, 
die dein Programmablauf beim Start verlangt, liegt vielleicht nicht 
rechtzeitig vor. Oder du initialisiert irgend etewas (z.B. ein Display) 
zu früh.

Ich hatte mal einen Laptop, der sich bei jedem Warmstart aufhängte, aber 
Kaltstarts gingen zu 100%.

Ohne deinen Schaltplan und Quelltext gesehen zu haben, kann man da nur 
alle möglichen Szenarien in eine wilde Vermutungs-Suppe werfen.

von langstrumpf (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Vielleicht hast du eine Race Condition. Irgend eine externe Bedingung,
> die dein Programmablauf beim Start verlangt, liegt vielleicht nicht
> rechtzeitig vor. Oder du initialisiert irgend etewas (z.B. ein Display)
> zu früh.
>
> Ich hatte mal einen Laptop, der sich bei jedem Warmstart aufhängte, aber
> Kaltstarts gingen zu 100%.
>
> Ohne deinen Schaltplan und Quelltext gesehen zu haben, kann man da nur
> alle möglichen Szenarien in eine wilde Vermutungs-Suppe werfen.

Jeder externe Reset (Resettaster) Jeder Power On geht gut! 100fach 
getestet.
Der Code der den Watchdog ausschaltet wird immer erreicht.
Das Ergebnis ist aber ein anderes wenn dieser Switch Case Block in der 
Mein Mit ausgeführt wird.

Irgend einen Einfluss müssen diese Zeilen haben.
Den selben Einfluss wie wenn ich die Optimierung ausschalte.
Was kann das sein?
Hat jemand Lust per Anydesk oder Teamviewer mit mit mir zu Debuggen?

von Stefan F. (Gast)


Lesenswert?

langstrumpf schrieb:
> Irgend einen Einfluss müssen diese Zeilen haben.

"Diese Zeilen" habe immer noch nicht sehen können, deswegen kann ich 
deine Frage immer noch nicht beantworten. Ich habe keine Lust mehr, das 
ist Zeitverschwendung ohne Aussicht auf Erfolg.

von langstrumpf (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> langstrumpf schrieb:
>> Irgend einen Einfluss müssen diese Zeilen haben.
>
> "Diese Zeilen" habe immer noch nicht sehen können, deswegen kann ich
> deine Frage immer noch nicht beantworten. Ich habe keine Lust mehr, das
> ist Zeitverschwendung ohne Aussicht auf Erfolg.
1
    switch(program_state)
2
    {
3
      default:
4
        if (enable_h)
5
        {
6
          output |= (1<<SITZ);
7
          time_prepare=umaeltz_zeit;
8
          program_state=INTERVALL;
9
          output &= ~(1<<OUT_FW);
10
          output &= ~(1<<OUT_RW);
11
        }
12
        else if (enable_high_h)
13
        {
14
          output |= (1<<SITZ);
15
          output &= ~(1<<OUT_FW);
16
          output |= (1<<OUT_RW);
17
        }
18
        else
19
        {
20
          output &= ~(1<<SITZ);
21
          output &= ~(1<<OUT_FW);
22
          output &= ~(1<<OUT_RW);
23
          time_prepare=0;
24
        }
25
        break;
26
      case CONTROLL:
27
        if (pos_Tab[POSITION] < sollmin)
28
        {
29
          temperatur_diff=sollmin-pos_Tab[POSITION];
30
          time_move=(temperatur_diff*700);
31
          if(time_move<1000) time_move=1000;
32
          if(time_move>10000) time_move=10000;
33
          output &= ~(1<<OUT_FW);
34
          output |= (1<<OUT_RW);
35
          program_state=MOTION;
36
        }
37
        else if (pos_Tab[POSITION] > sollmax)
38
        {
39
          temperatur_diff=pos_Tab[POSITION]-sollmax;
40
          time_move=(temperatur_diff*700);
41
          if(time_move<1000) time_move=1000;
42
          if(time_move>10000) time_move=10000;
43
          output &= ~(1<<OUT_RW);
44
          output |= (1<<OUT_FW);
45
          program_state=MOTION;
46
        }
47
        else 
48
        {
49
          program_state=INTERVALL;
50
          time_prepare=regelintervall_zeit;
51
        }
52
        break;
53
      case INTERVALL:
54
        if(time_prepare==0)
55
        {
56
          program_state=CONTROLL;
57
        }
58
        break;
59
      case MOTION:
60
        if(time_move==0)
61
        {
62
          output &= ~(1<<OUT_RW);
63
          output &= ~(1<<OUT_FW);
64
          time_prepare=regelintervall_zeit;
65
          program_state=INTERVALL;
66
        }
67
        break;
68
    }


Diese unscheinbaren Zeilen erzeugen das Problem

von langstrumpf (Gast)


Lesenswert?

Danke für die Geduld!

von Stefan F. (Gast)


Lesenswert?

langstrumpf schrieb:
> Diese unscheinbaren Zeilen erzeugen das Problem

Reduziere es auf noch weniger, bis du die schuldige Zeile gefunden hast.

von Maggi (Gast)


Lesenswert?

langstrumpf schrieb:
1
> default:
2
>         if (enable_h)
3
>         {
4
>           output |= (1<<SITZ);
5
>           time_prepare=umaeltz_zeit;
6
>           program_state=INTERVALL;
7
>           output &= ~(1<<OUT_FW);
8
>           output &= ~(1<<OUT_RW);
9
>         }
10
>         else if (enable_high_h)
11
>         {
12
>           output |= (1<<SITZ);
13
>           output &= ~(1<<OUT_FW);
14
>           output |= (1<<OUT_RW);
15
>         }
16
>         else
17
>         {
18
>           output &= ~(1<<SITZ);
19
>           output &= ~(1<<OUT_FW);
20
>           output &= ~(1<<OUT_RW);
21
>           time_prepare=0;
22
>         }
23
>         break;

Wie werden denn program_state, enable_h und enable_high_h initialisiert 
bzw. manipuliert? In einem Interrupt?

Denn wenn else-if oder else zutreffen, wird program_state nicht 
verändert. In den beiden Fällen könnte es also sein, dass Dein 
Controller in einer Schleife hängen bleibt.

Es sei denn, "enable_high" wird irgendwann wahr.

von langstrumpf (Gast)


Lesenswert?

Es ergibt keinen Sinn.
1
case CONTROLL:
2
        if (pos_Tab[POSITION] < sollmin)
3
        {
4
          temperatur_diff=sollmin-pos_Tab[POSITION];
5
          time_move=(temperatur_diff*700);
6
          if(time_move<1000) time_move=1000;
7
          if(time_move>10000) time_move=10000;
8
          PORTB &= ~(1<<1);
9
          PORTB |= (1<<0);
10
          program_state=MOTION;
11
        }
12
        else if (pos_Tab[POSITION] > sollmax)
13
        {
14
          //temperatur_diff=pos_Tab[POSITION]-sollmax;
15
          //time_move=(temperatur_diff*700);
16
          //if(time_move<1000) time_move=1000;
17
          //if(time_move>10000) time_move=10000;
18
          PORTB &= ~(1<<0);
19
          PORTB |= (1<<1);
20
          program_state=MOTION;
21
        }
22
        else 
23
        {
24
          program_state=INTERVALL;
25
          time_prepare=regelintervall_zeit;
26
        }
27
        break;

wenn diese Zeilen weg kommentiert sind dann geht es mit den Zeilen Geht 
es nicht.
Wie selben Zeilen wie etwas oberhalb.:(((

von OpenStack (Gast)


Lesenswert?

langstrumpf schrieb:
> Es ergibt keinen Sinn.
> case CONTROLL:
>         if (pos_Tab[POSITION] < sollmin)

> Wie selben Zeilen wie etwas oberhalb.:(((

Dann lade doch mal den kompletten sourcecode hoch. Du kannst ihn später 
ja wieder löschen

von Peter D. (peda)


Lesenswert?

1
int main(void)
2
{
3
  MCUSR = 0;
4
  wdt_disable();
5
  // usw.
6
}
Und Ruhe is.

von langstrumpf (Gast)


Lesenswert?

OpenStack schrieb:
> Dann lade doch mal den kompletten sourcecode hoch. Du kannst ihn später
> ja wieder löschen

Nein. Das kann ich nicht.
Ich lasse Dich per AnyDesk oder Teamviewer an den Sorce Code.

von langstrumpf (Gast)


Lesenswert?

Peter D. schrieb:
> int main(void)
> {
>   MCUSR = 0;
>   wdt_disable();
>   // usw.
> }
> Und Ruhe is.

Im Normalen Fall wäre das so aber bei mir spinnen ein paar Zeilen in der 
Mein die absolut nichts mit dem Rest zu tun haben.
Banale Bit Schupserei in der main machen das deaktivieren des WD 
unmöglich.

von OpenStack (Gast)


Lesenswert?

langstrumpf schrieb:
> OpenStack schrieb:
> Dann lade doch mal den kompletten sourcecode hoch. Du kannst ihn später
> ja wieder löschen
>
> Nein. Das kann ich nicht.
> Ich lasse Dich per AnyDesk oder Teamviewer an den Sorce Code.

Viel Erfolg bei der Suche

von Bauform B. (bauformb)


Lesenswert?

FabiWa schrieb:
> Stefan ⛄ F. schrieb:
>> Der einfachste Weg ist: Verbinde den RESET Eingang mit einem I/O Pin und
>> schalte diesen auf LOW.
>
> Ich habe mal gelernt, dass man das nicht tun sollte, da ein korrekter
> Reset dann nicht garantiert werden kann. Das Problem ist wohl, dass der
> RESET-Eingang dann unter Umständen nicht lang genug LOW ist.

Wobei "lang genug" sehr lang sein kann, wenn der uC mit sehr niedrigem 
Takt läuft:

Peter D. schrieb:
> Das dürfte mächtig in die Hose gehen.
> Das CPU-Reset wird erst mit der nächsten Taktflanke erzeugt, die Ports
> gehen aber asynchron in Tristate.

Man will keine Ports mit synchronem Reset, das passt schon. Ob es 
überhaupt eine CPU gibt, die komplett asynchron zurück gesetzt werden 
kann ist die Frage. Und wahrscheinlich ist es nirgends spezifiziert. Und 
selbst wenn, wäre es durch unterschiedliche Gatterlaufzeiten 
undefiniert. Also funktioniert der Trick nicht.

von Peter D. (peda)


Lesenswert?

langstrumpf schrieb:
> Banale Bit Schupserei in der main machen das deaktivieren des WD
> unmöglich.

Dann hast Du ein grundsätzlicheas Problem in der Programmablaufplanung.
Der Watchdog darf das Programm nicht beeinflussen. In der Regel 
entwickelt man ein Programm mit Watchdog disabled. Und erst, wenn alles 
einwandfrei läuft, wird der Watchdog hinzugefügt.

von langstrumpf (Gast)


Lesenswert?

Guten Morgen,
ich habe gestern Nacht ein neues Prokekt mit Atmel Studio erzeugt.
Alle Quellcodes rein kopiert und nur wie Peter D.  empfohlen hat
MCUSR = 0;
wdt_disable()
an den Anfang der main geklatscht.
Und oh Wunder alles geht so wie es gehen soll.
Hat hier jemand eine Erklärung was im anderen Projekt schief gegangen 
sein kann?
Danke allen die mir mit konstruktiven Ideen geholfen haben.

von langstrumpf (Gast)


Lesenswert?

Keiner eine Erklärung zu meinem letzten Beitrag?

von Einer K. (Gast)


Lesenswert?

Nöö....

von Stefan F. (Gast)


Lesenswert?

Zeige und die beiden kompletten Projekte, dann können wir sie 
vergleichen.

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.