Forum: Mikrocontroller und Digitale Elektronik Watchdog PIC16


von Peters (Gast)


Lesenswert?

Hallo,

folgendes Problem:

Ich Habe einen PIC16F690, in den Konfigurationsbit ist der Watchdog 
disabled, damit ich ihn mit dem SWDTEN bit ein- und ausschalten kann. 
Dies funktioniert auch. Nun möchte ich nach einem Neustart des 
Controllers erfahren wodurch der Reset Ausgelöst wurde. Hierzu steht das 
TO Flag im Statusregister bereit, jedoch ist das Statusregister nach 
jedem Neustart, egal ob Reset, MCLR oder WDT Reset 0x18 also TO = 1 und 
PD = 1.

Muss ich irgendwo das TO bit "freischalten" und durch wen wird dieses TO 
bit im Statusregister überhaupt gelöscht?

In meinem Quelltext siehts ca. so aus:

SWDTEN = 1;
get_Messwert();
asm("clrwdt");
get_Messwert();
asm("clrwdt");
get_Messwert();
asm("clrwdt");
SWDTEN = 0;

Der WDTPS ist auf 1001b eingestellt, ergibt ca 530ms.

Für Hile wäre ich dankbar.

von Εrnst B. (ernst)


Lesenswert?

Wahrscheinlich setzt der vom Compiler generierte Startup-Code das 
Register zurück, bevor du überhaupt aus dem C-Code drankommst.

Lass dir mal ein ASM-File generieren, und schau darin nach, was der 
Controller direkt nach dem Reset-Vector macht.

von Severino R. (severino)


Lesenswert?

Und wo in Deinem Code sollte ein WDT ausgelöst werden?

von Peters (Gast)


Lesenswert?

@severino

wenn die get_Messwert Funktion nicht mehr zurückkehrt bzw. länger als 
die 530ms benötigt, denn dann ist etwas faul.

von Peters (Gast)


Lesenswert?

Hallo Ernst,

Ich nutze den PICC von Htsoft. Leider kann ich keine assembler option 
finden, die mir ein komplettes ASM File generiert. Es ist zwar 
(angeblich) möglich mit dem subbefehl +keep die startup.as nach dem 
linken zu behalten, doch dies war bei mir nicht möglich....

Meine Fehlerbeschreibung/Vorgehensweise sieht nun folgendermaßen aus:

Ich habe das powerup.as file zu meinem Projekt hinzugefügt, in dem kann 
man die ersten Prozessorzyklen nach dem Reset für eigenen Code nutzen. 
Dies sieht auch alles vollständig aus, heiß ein neues psec wird erzeugt 
und powerup genannt. Ich habe mir nun gedacht dort könnte ich sowas wie:

movf Status, W
movlw _ResetStatus

eingeben, und in meinem Hauptprogramm dann einfach den _ResetStatus 
auslesen und weiterverarbeiten. Leider Funktioniert das auch nicht, un 
der _ResetStatus enthält immer 0. Im Disasembly ist der oben genannte 
ASM-Code folgendermaßen übersetzt:

movf 0x3,0  -> das ist korrekt
movlw 0     -> das macht mich stutzig

den dort sollte doch eigentlich die Adresse meiner _ResetStatus 
Variablen stehen? Die adresse des _ResetStatus ist im Mapfile mit rbss_0 
0020 angegeben.

Ich weiß jetzt auch nicht weiter, die Assembler optionen -clear oder 
-init haben auch nichts geändert, obwohl sie das Löschen der Variablen 
beim Reset  verhindern sollen.

Es gibt noch die Option +resetbits, dort soll der STATUS status in einer 
variablen __timeout gespeichert werden.... Ich find keine???

Irgendwelche PICC oder PIC Profis die mir tips geben könnten...

Entwicklungsumgebeung ist MPLAB IDE 8.0 und PICC Compiler

grüße

von Bernd R. (Firma: Promaxx.net) (bigwumpus)


Lesenswert?

Wenn Du den CLRWDT-Befehl ausführst, bevor Du TO abfragst, ist TO=1!

Sieh Dir den Code an!

von Peters (Gast)


Lesenswert?

@ Bernd

Nach einem WDT Reset wird das TO Bit im Statusregister von der HW 
gelöscht. Nach jedem anderen Reset wird das TO bit gesetzt, oder bleibt 
unverändert. Wird nun also der Watchdog nicht rechtzeitig retriggert, da 
die Funktion nicht zurückkehrt, Resetet er den uC -> TO = 0. Ich frage 
logischerweise das T0 bit nach dem entry in die Mainschleife ab, da dies 
der erste Punkt ist an dem der PC vorbeiläuft. Ich sehe jetzt nicht was 
du meinst mit: "sieh dir den Code an!"

Der Watchdog läuft nur während der oben angegebenen Funktion also 
zwischen SWDTEN = 1 und SWDTEN = 0. Deshalb muss ich CLRWDT auch 
nirgends sonst im Programm verwenden, daher sollte das einzige CLRWDT in 
eben dieser Funktion enthalten sein.

von Severino R. (severino)


Lesenswert?

Peters wrote:

> movf Status, W
> movlw _ResetStatus
>
Was willst Du damit erreichen?
Du schreibst den Inhalt von Status nach W, anschliessend schreibst Du 
den Wert (nicht Inhalt der Speicherstelle) _ResetStatus nach W.

von Peters (Gast)


Lesenswert?

Hallo Severino,

uups, tippfehler:

Ich möchte den Inhalt des STATUS Registers in eine globale Variable 
schreiben.
Es muss natürlich heißen (so stehts auch in meinem Code)

movf STATUS, W
movwf _ResetStatus

Das ist so richtig, oder?


(Ich glaub ich muss erst mal ein paar Bier auf dem Maifest pfetzen)

von Peters (Gast)


Lesenswert?

Hallo,

folgendes löste das Problem:

1. anstelle der pic.h muss htc.h included werden.

2. den Linker mit der Option "--runtime=+resetbits" aufrufen.

Dann steht eine (bit) Variable __timeout zur Verfügung, auf die man eine 
Abfrage starten kann.

Funktioniert wunderbar, und ist in wenigen sekunden eingebunden :|

Gruß

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.