Forum: Mikrocontroller und Digitale Elektronik Problem Start PIC16F876A


von Christian M. (Gast)


Angehängte Dateien:

Lesenswert?

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

von Michael .. (gismi)


Lesenswert?

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)

von Michael .. (gismi)


Lesenswert?

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

von Christian M. (Gast)


Lesenswert?

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

von Michael .. (gismi)


Lesenswert?

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)

von Thomas E. (picalic)


Lesenswert?

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....)

von Christian M. (Gast)


Lesenswert?

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

von X4U (Gast)


Lesenswert?

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.

von Mc M. (mcmix)


Lesenswert?

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.

von W.S. (Gast)


Lesenswert?

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.

von Christian M. (Gast)


Lesenswert?

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

von Christian M. (Gast)


Lesenswert?

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

von Thomas E. (picalic)


Lesenswert?

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

von Christian M. (Gast)


Lesenswert?

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

von Thomas E. (picalic)


Lesenswert?

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.

von Cyborg (Gast)


Lesenswert?

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.

von Christian M. (Gast)


Lesenswert?

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

von TK (Gast)


Lesenswert?

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

von Thomas E. (picalic)


Lesenswert?

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
Noch kein Account? Hier anmelden.