Forum: Mikrocontroller und Digitale Elektronik PIC18 / Reset führt manchmal zum Absturz


von Atter S. (attersee)


Angehängte Dateien:

Lesenswert?

Privates Projekt mit PIC18F4550, PASM, LCD, Keyboard, I2C Uhr / RAM, 
mehrere I2C IO-Expander.  Interrupt OFF, WDT noch nicht aktiviert (mache 
ich erst ganz am Ende), etwa 4000 LOC, insgesamt 5400 Zeilen mit 
Kommentaren.

Das Programm ist fast fertig und läuft in allen Tests stabil. Nur, - so 
etwa jedes 10. Mal läuft das Programm nach dem Laden mit PICkit 3 nicht 
von selbst los. Zieht man kurz den Netzstecker, so startet das frisch 
geladene Programm zuverlässig.

Dachte ich, das Laden funktioniert halt nicht immer, - bringe eine 
Reset-Taste an. Ich verwende die externe Reset-Schaltung gemäß 
Datenblatt Seite 43 (siehe Beilage). Zunächst machte ich einen 
Flüchtigkeitsfehler und verband die Taste mit MCLR\ und VSS. Das darf 
natürlich nicht sein, weil ja PICkit 3 den MCLR\ Pin ansteuert. Dennoch 
benutzte ich die Taste anfänglich und musste feststellen, dass nach 
einem Programmieraufhänger auch die Taste nichts nützt. Ich sehe ein 
kurzes Blinken bei der LCD Beleuchtung (diese wird in der Setup Routine 
aktiviert) und dann hängt die Sache. Befreiung wiederum durch Power 
OFF/ON. Drücke ich nun bei laufendem Programm die Reset Taste – was ich 
ja wohl darf – so löst etwa jeder 6. Drücker einen Absturz (und nicht 
einen Neustart) aus.

Dann änderte ich die Schaltung, indem ich das ‚obere‘ Ende der Taste 
über 270 Ohm mit dem Knotenpunkt R/C verband. Nun bringt bereits jede 2. 
Tastenbetätigung den Prozessor zum Absturz.

Habe ich die Schaltung ungünstigt dimensioniert?  An die Beschreibung 
habe ich mich jedenfalls gehalten, - nur der Spielraum ist halt ziemlich 
groß.
Eigentlich habe ich die Taste eingefügt, um den Prozessor aus einem 
Absturz zu befreien. Noch nie hatte ich ein Problem mit einer 
Reset-Taste.

Ich hoffe, es hilft mir jemand aus der Gosse. Danke.

Grüße, attersee

von Holger W. (holgerw)


Lesenswert?

Ohne weiter Informationen wird es schwierig, ich würde zuerst auf 
Spannungsversorgung tippen, 100nF nah genug dran, Quarzbeschaltung ok, 
bricht die Spannung zusammen wenn du das LCD Backlight ansteuerst.
Main aufräumen, schrittweise Funktionen wieder hinzufügen, Ausgaben 
triggern (LED) damit man weis wie weit er kommt.
Wenn du es so wie bisher provozieren kannst geht es ja noch.
Ich hab übrigends noch nie einen Reset Taster gebraucht, ich schalte den 
immer aus.
Habe auch lang laufende Anwendungen (Wecker, Temperaturregelung usw) und 
zum Glück noch keine derartigen Probleme gehabt.

Holger

von Atter S. (attersee)


Lesenswert?

Holger,

Danke für die Unterstützung. Das Programm ist leider viel zu 
umfangreich, um den Code ins Forum zu stellen. Doch oft sind es ja die 
aus der Erfahrung stammenden Anregungen einer dritten Person, die einem 
den nächsten Schups geben.

Ich hatte vergessen, zu erwähnen, dass ich mir die Spannung bereits 
angeschaut hatte. Ganz glatt, auch bei den Schaltvorgängen. Jegliche 
Last (LCD Backlight, Relais-Treiber, etc.) versorge ich außerdem über 
einen eigenen Spannungsregler.

Aber mit der Aufräumerei bin ich wesentlich weiter gekommen. Ich habe 
aus der Hauptprogrammschleife alles ausgeblendet, was mit I2C zu tun hat 
und siehe da, die Reset Taste führt jedes Mal zu einem sauberen 
Neustart. Es scheint ein I2C Problem vorzuliegen.

Meine Überlegungen – ins Grobe gesprochen – sind …
a) Beim Laden des Programms trifft der PICkit 3 manchmal mitten in eine 
I2C Kommunikation hinein, wobei sich der Controller dann aus mir nicht 
bekannten Gründen aufhängt.
b) Wenn ich die Reset Taste gedrückt habe, überraschte ich das System 
auch manchmal in einer I2C Kommunikation, - und das scheint eine 
Schwachstelle zu sein.

Ich habe bei den I2C Komponenten (1 x PCF8583, 3 x MCP23008) die Reset 
Eingänge einfach ignoriert, denn bei Power Up machen die ohnedies ein 
Reset. Möglicherweise müsste man mit einem Reset des Prozessors auch die 
Peripherie rücksetzen.

Möglicherweise sind aber auch meine I2C Routinen nicht ausreichend 
störungsresistent. Ich benutze die PIC18 Routinen aus Günter Schmitt, 
PIC-Microcontroller, Oldenburg 2010.

So werde ich mir diese Ecke einmal genauer ansehen, bin aber natürlich 
für weitere Anregungen sehr dankbar.

Grüße, attersee

von Holger W. (holgerw)


Lesenswert?

Verwendest du die I2C Bibliotheken oder eigene Routinen ?
Bei den Bibliotheken ist mir aufgefallen, dass dort Deadlocks auftreten 
können, z.b. wird mit while(xyz) auf einen Pinzustand gewartet und wenn 
der nicht kommt ewig.
Ich hab eigen Routinen die nach einem Timeout abbrechen.

Holger

PS: das mit den Bibliotheken hab ich jetzt erst später gelesen...

von Atter S. (attersee)


Lesenswert?

Holger, die erwähnten ‚eigenen‘ Routinen enthalten keine 
Fehlerbehandlung. Deadlocks sind somit vorprogrammiert. Da werde ich 
wohl ansetzen müssen. So Ich schaue mich gerade nach Optionen um. 
Entweder ich finde einen Weg, die verwendeten Routinen zu ergänzen oder 
ich brauche andere Routinen. Lösungsansätze bzw. Quellen sind sehr 
willkommen. Danke. Grüße, attersee

von Holger W. (holgerw)


Lesenswert?

Ich hab z.b. sowas im Einsatz:
1
unsigned char timeout=0;
2
    //StopI2C();                     // STOP
3
    SSPCON2_PEN = 1;
4
    while (SSPCON2_PEN) // stop condition beendet ?
5
    {
6
        timeout++;
7
        if (!timeout) return -9;
8
        delay_us(200);
9
    }
man muss dann nur sinnvoll drauf reagieren.

Holger

von Atter S. (attersee)


Lesenswert?

Holger, wohl ist C für mich eine Fremdsprache, doch der Sinn der paar 
Zeilen ist klar. Ich schaue mich gerade um, wie man das im Assembler 
löst. Erst mal herzlichen Dank. Ich werde berichten. Grüße, attersee

von Peter D. (peda)


Lesenswert?

Atter See schrieb:
> Es scheint ein I2C Problem vorzuliegen.

I2C ist bekannt dafür, daß es sich verklemmen kann. Warum die Entwickler 
des HW-I2C keine Fehlererkennung einbauen, weiß der Teufel.

In Single-Master Anwendungen lassen ich daher das HW-I2C links liegen 
und mache I2C in SW. Dann weiß man jederzeit, wo sich das I2C befindet 
und kann es leicht resetten.


Peter

von Atter S. (attersee)


Lesenswert?

Nur ein Zwischenbericht. Zur Erinnerung: SW läuft bei allen Tests 
klaglos, nur manchmal Absturz beim Programmieren (PICkit3). Auch Reset 
Taste kann zum Absturz führen.

@ Holger / habe Timeout Routine in ASM (mit Timer) gemacht. 
Funktioniert, - doch selbst ein Restart erweckt die I2C Hardware nicht 
mehr zum Leben. Habe herausgefunden, dass sie einfach festgefahren ist. 
Man bringt keinen Impuls mehr heraus. Weg vorerst verlassen und 
‘bit-banged Routinen‘ gesucht.

@ Peter / Danke für den Beitrag. Wollte nicht bei null beginnen und habe 
nach Sid Katzen, The Essential PIC18 Microcontroller, Springer 2010 
gegriffen, seine bit-banged Routinen übernommen und bin (fast) 
verzweifelt. Der Code protzt nur so von schwersten Fehlern. Der ist nie 
gelaufen. Da findet sich rlncf, wenn er Daten nach C schicken will, oder 
er versucht, SDA über TRIS anstatt PORT einzulesen. Ich habe es dann als 
Sport verstanden, die Routinen zum Laufen zu bringen. Sie laufen, doch 
leider noch nicht stabil. Nach einigen Minuten bleibt ein ACK aus. Muss 
es erst mit dem Scope einfangen.

@ Forum:
Sollte jemand eine ‚reparierte‘ Version der Sid Katzen Routinen haben, 
wäre es schön, wenn er / sie sich meldet. Etwas Zeit investiere ich 
noch, bevor ich auf eine andere Quelle zugreife.

Faktum ist aber, dass es beim Programmieren keinen Absturz mehr gibt und 
dass ein HW Reset immer funktioniert.

Grüße, Johann

von Atter S. (attersee)


Lesenswert?

Alles läuft. Bin zunächst an den Routinen von Sid Katzen fast 
verzweifelt. Ich dachte, alle Fehler behoben zu haben und die 
Applikation lief mit den Routinen trotzdem nicht stabil. Nach einigen 
Sekunden bis Minuten traten sonderbare Effekte auf. Ich nahm an, dass 
falsche Daten gelesen werden würden. Am DSO schaute alles ganz normal 
aus. Triggern des Fehlers gelang mir vorerst nicht.

In Wut und Verzweiflung stieg ich auf die von Microchip in AN979 
publizierten bit-banged Routinen um. Die sind für 4 MHz geschrieben, ich 
aber takte mit 24 MHz. Nachdem ich das Timing maßgeschneidert hatte, 
lief die Applikation wiederum nicht stabil.

Schließlich debuggte ich mich in die Tiefe der Applikation und fand, 
dass ich einen ‚Würfel‘ eingebaut hatte. Ich hatte bei numerischen 
Algorithmen an einer Stelle vergessen, das Carry Flag zu setzen. Dieses 
wurde von den I2C Routinen der ersten Generation (Benutzung der I2C 
Hardware) aus irgendwelchen Gründen immer gesetzt und der Algorithmus 
funktionierte. Als ich die I2C Routinen gegen die beiden bit-banged 
Varianten austauschte, verschwand offensichtlich diese ‚Setzautomatik‘ 
und der Algorithmus begann Fehler zu produzieren.

Nun kann ich zwischen zwei Varianten von funktionierenden bit-banged I2C 
Routinen wählen. Ich habe mich für Microchip entschieden.

Die ganze Übung habe ich gemacht, weil ja der MC beim Programmieren mit 
dem PICkit 3 (unter Verwendung der prozessorinternen I2C Hardware) 
gelegentlich so fatal abgestürzt ist, dass ihn auch ein HW Reset nicht 
mehr befreien konnte. Das ist nun Geschichte.

Danke nochmals an Holger und Peter für das Mitdenken und die Hilfe.
Grüße,

Johann

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.