Hallo Forumisten, seit einiger Zeit treibt mich ein Problem fast zum Wahnsinn. Es handelt sich um eine Tochteruhrsteuerung mit einem PIC16F876A mit 4MHz. Schema und Layout beiliegend. Problembeschreibung: Ich kann nicht mehr genau sagen, ab wann (gefühlsmässig seit Anfang) der PIC nur sporadisch das Programm startet, oder nach kürzester Zeit abbricht (einige Sekunden). Vereinzelt lief er stundenlang ohne Probleme. Zuerst hatte ich den Quarz in Verdacht. Aus stromspargründen verwende ich einen 4Mhz-Quarz im XT-Mode. Aber der HS-Mode brachte keine Aenderung. Auch Wechseln brachte nichts. Im Oszillogramm schwingt er schön in beiden Modi. Gemessen an OSC2/Pin 10 mit 10:1 Tastkopf (siehe Bilder). Ich nehme an, der kleinen Pegel ist normal im XT-Modus? Kanal 2 zeigt die Versorgungsspannung 5V im AC-Modus. Ein wenig Rauschen. Langsam kommt der Verdacht auf, es liegt an der Software. Ist sie doch komplex, mit 2 Interrupt-Quellen (einmal Timer0 jede ms, und einmal USART-Empfang). So habe ich ein Testprogramm mit dem nötigsten gemacht. Das läuft sauber an, immer! Die LEDs blinken abwechselnd. ABER: Meistens kommt LED1 zuerst (wie es sollte) und 200ms lang(!) und manchmal kommt ZUERST LED2 (im richtigen Takt)! Screenshot von LA leigt bei. Beide Programme sind angehängt. Geschrieben in "mikroBasic for PIC" von mikroE. Ich habe schon viele Projekte damit gemacht, auch mit dem PIC16F876A, immer ging alles wunderbar. Nur einmal hatte in einen PIC, der zog -MCLR intern mit ca. 0mA5 runter. Der hat dann dauernd geresettet... Kann mal jemand drüberschauen, oder einen Denkanstoss geben. Warscheinlich habe ich mich irgendwie verrannt... Danke und einen schönen Tag, Feiertag (Vereinigung moldau und Walachei) Gruss Chregu
Ich habe es mal kurz überflogen: Du solltest auf keinen Fall im Interrupt + im main-Loop auf die selbe Variable zugreifen, solange die Interrupts aktiv sind. (zB puls)
Christian M. schrieb: > ABER: Meistens > kommt LED1 zuerst (wie es sollte) und 200ms lang(!) und manchmal kommt > ZUERST LED2 (im richtigen Takt)! Screenshot von LA leigt bei. schreib mal folgendes vor die while
1 | LED1 = 0 |
2 | LED2 = 0 |
Michael .. schrieb: > auf keinen Fall im Interrupt + im main-Loop auf die selbe > Variable zugreifen, solange die Interrupts aktiv sind. Kann jetzt grad nicht nachvollziehen, warum nicht. Und wie löse ich sonst so ein Problem? Flag setzen und abfragen geschieht ja IMMER sequentiell. Michael .. schrieb: > schreib mal folgendes vor die while > LED1 = 0 > LED2 = 0 Ja logisch, danke! Zuerst kommt ein Delay, und vorher hat der Ausgang noch irgendeinen Wert von vorher... Gruss Chregu
Christian M. schrieb: > Kann jetzt grad nicht nachvollziehen, warum nicht. Und wie löse ich > sonst so ein Problem? Flag setzen und abfragen geschieht ja IMMER > sequentiell. Weil durch solche effekte können Programme sich sehr unberechenbar verhalten. zB nach wenigen Sekunden oder nach Tagen. https://www.mikrocontroller.net/articles/Interrupt#Atomarer_Datenzugriff einfachste möglichkeit das zu beheben ist, im main-loop jeweils vor dem Zugriff auf die Variable, die Interupts zu deaktivieren. (INTCON -> GIE)
Servus Chregu, die Unsicherheit beim Start des Testprogramms kommt mir so vor, als ob der Prozessor nicht zuverlässig resettet wird. Du solltest die Brown-Out Detection aktivieren (hast Du? Sorry kann das Config-Word gerade nicht selbst auseinanderklamüsern....)
Thomas E. schrieb: > Unsicherheit beim Start des Testprogramms Das hat sich ja weiter oben schon erledigt. Thomas E. schrieb: > Du solltest die Brown-Out > Detection aktivieren Ist Enabled! :-)) Gruss Chregu
Christian M. schrieb: > Beide Programme sind angehängt. Also wenn Prog 2 nicht läuft würde ich bei der Hardware bleiben. Bei dem LA-schrieb würde ich auf Spannungversorgung tippen. Also z.B. IC1 raus und über den ICSP versorgen.
Hast du mal versucht, testweise das Messen der Spannung wegzulassen. Sobald sie deinen vorgegebenen Wert unterschreitet, sendet das Hauptprogrammm nur noch Messwerte. Und wenn dann puls auf 0 heruntergezählt wurde, passiert beim timer nichts mehr.
Christian M. schrieb: > Langsam kommt der Verdacht auf, es liegt an der Software. Hast du den Watchdog in Benutzung? Wie hast du den Prescaler in Benutzung? Also für den Timer oder den WD? Ich habe diese PIC's bislang ausschließlich in Assembler programmiert und hatte damit noch nie Probleme. Auch die Stack-Tiefe hat bei mir bislang problemlos ausgereicht. Aber zu Micro-Basic kann ich dir nix sagen - außer daß du mal guckst, wie dort der Stack tatsächlich benutzt wird. W.S.
W.S. schrieb: > Hast du den Watchdog in Benutzung? Nein, der käme erst am Schluss, wenn alles läuft. W.S. schrieb: > Wie hast du den Prescaler in Benutzung? Prescaler 1:4 für Timer0 W.S. schrieb: > hatte damit noch nie Probleme Hatte ich auch noch nie. Eigentlich nimmt einem der Compiler die ganzen Bank-Umschaltungen, Stack usw. Probleme ab. Lief immer alles perfekt! Bugs waren immer ganz dumme, selbstgemachte, die man schon lange hätte sehen sollen :-)) Wilhelm S. schrieb: > Hast du mal versucht, testweise das Messen der Spannung wegzulassen. Ja, habe das Unterprogramm commented, und den Aufruf gesperrt. Auch das Unterprogramm "schreiben". X4U schrieb: > Also wenn Prog 2 nicht läuft würde ich bei der Hardware bleiben. Läuft perfekt! Das Problem besteht immer noch. Eingekreist dass das Programm manchmal kaum bis zur Initialisierung kommt (mit blinkenden LEDs festgestellt) wo noch kein Interrupt freigegeben ist. Manchmal läuft es 2...3 Durchgänge in der Hauptschleife, manchmal 10...20 Mal. Vor dem Zugriff auf Variablen, die auch in der Int vorkommen, habe ich jetzt den Int gesperrt. Alle Variablen werden am Anfang der main: gelöscht/auf Null gesetzt, damit keine Effekte von einem vorherigen Start reinspielen (sollten). Ich weiss nicht mehr weiter. Mach wieder ein zwei Tage Pause, das hilft manchmal. Zu lange nicht, sonst ist man wieder draussen... Gruss Chregu
Es war ein Stack-Overflow!!! Der Interrupt braucht schon vier Ebenen, und wenn das zusammenkommt mit dem Hauptprogramm, wo es über vier Ebenen sind, crasht's! Mein Workaround war jetzt die ganze Hauptschleife in einen Rattenschwanz absolut ohne Funktionen und Prozeduren zu pferchen. Alternativ könnte man einen 18F nehmen. Danke an alle! Gruss Chregu
Servus Chregu, kenne mich zwar mit mikroBasic nicht aus, aber wenn ich mir die ISR anschaue, sieht die für mich ziemlich flach aus - keinerlei Unterprogramm-Aufrufe oder komplexe Funktionen. Wenn mikroBasic da 4 Stacklevel draus macht, würde das mein Vertrauen in dieses Werkzeug nicht gerade stärken... Gruß Thomas
Hallo Thomas, tut mir leid, ich habe vergessen zu Erwähnen, dass ich das ganze Programm in den Oshonsoft-Compiler transferiert habe. Dabei hatte ich ähnliche Probleme, bis ich mit dem LA das Problem eingekreist habe. Die Stacktiefe hat sich in der Simulation gezeigt, wobei das Projekt sehr schwierig zu simulieren ist. Ich hatte da schon die volle Stacktiefe von 8 Ebenen ausgenutzt, und es war noch ohne Unterfunktionen in Funktionen. Ich werde auf jeden Fall in Zukunft gröbere PICs benutzen, obwohl ich eigentlich immer das einfachstmögliche einzusetzen versuche. Ich mag keinen Overhead von irgendwelchen Klickibunti, die dann 90% der Resourcen verbrauchen. Auf jeden Fall läuft jetzt die Uhr! Steuerung noch in ein schönes Gehäuse und an die Wand damit! :-)) Gruss Chregu
Christian M. schrieb: > Alternativ könnte man einen 18F nehmen. Eine Alternative wären evtl. die Enhanced Midrange Typen (12F1xxx, 16F1xxx). Pinkompatibel zu den alten Midrange Typen, aber u.a. 16 Level Stack.
Die Sparschaltung der Spannungsversorgung ist aber auch nicht aktueller Stand der Technik, so der Eindruck, auch wenns funktioniert. Wenn die Siebelkos schleichend schlapp machen, wird es sich zeigen ob da nicht am falschen Ende gespart wurde.
Thomas E. schrieb: > Wenn mikroBasic da 4 > Stacklevel draus macht, würde das mein Vertrauen in dieses Werkzeug > nicht gerade stärken... mikroBasic macht die ISR direkt bei 0x0004, Oshonsoft macht im ASM:
1 | ORG 0x0004 |
2 | CALL L0003 |
3 | RETFIE |
und im L0003 (nach END) dann viele CALLs! Wie tief die jetzt verschachtelt sind, habe ich nicht mehr verfolgt. Gruss Chregu
Hallo Christian, kannst Du dem Tool nicht sagen, dass es anstatt des CALLs ein GOTO einfügen soll, und das RETFIE dann dort hinlegt? Somit spart man sich eine Stackebene. Ich glaube auch, die CALLs nach dem END sind hier nicht mehr wichtig, da das wahrscheinlich die OPCODES für 0x3FFF sind (also eine leere Speicherstelle repräsentieren) Gruß TK
Christian M. schrieb: > mikroBasic macht die ISR direkt bei 0x0004, Oshonsoft macht im ASM: Ist schon heftig, bei einer Maschine mit winzigem Hardware-Stack diesen auch noch mit überflüssigen calls zu vergeuden! Die wollen ja auch Geld sehen für ihre Software, da kann man nichtmal entschuldigend sagen "was nix kosten, taugt auch nix" oder "einem geschenkten Gaul usw..." Wie gesagt, ich würde wohl einfach einen pinkompatiblem Enhanced-Midrange PIC nehmen, in der Hoffnung, daß Oshonsoft die Stackvergeudung nicht abhängig von verfügbaren Stacklevels betreibt.
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.