.
Tiny 2313 bzw. 4313 und WD
Habe vor Jahren dieses kleine Assemberle gemacht und in BASCOM
eingebunden.
Zweck ist es den AVR alle 8 Sekunden aufzuwecken, kurz was machen zu
lassen, um ihn dann wieder schlafen zu legen.
------------------------------
$asm
push r24
LDI R24, $57 ' WD auf 8 Sekunden setzen
STS 65 , r24
LDI R24, $31
STS 65, r24
LDS R24, 65 ' WD starten
ORI R24,$08
STS 65 , r24
pop r24
$end Asm
---------------------------------
Jetzt will ich es auf ein oder zwei Sekunden umstellen, dumm nur das ich
nicht mehr nachvollziehen kann was ich damals gemacht habe.
Zuerst wird das Register R24 mit einer Konstanten geladen ($57) (was
bedeutet das "$" Zeichen? Hex-Zahl?
R24 wird dann ins SRAM (65) gebracht.
Dann das selbe nochmal, wieder (diesmal mit $31) auf ebenfalls SRAM (65)
geschrieben.
Wird denn da das (65) nicht einfach überschrieben?
Dann wird (65) in R24 geladen, Bit3 gesetzt, und wieder
zurückgeschrieben.
Ist das so richtig oder liege ich da total daneben?
Kurt
Kurt schrieb:> Kurt
Bindl?
Das kann man in Bascom auch machen - ohne Assembler-Routine.
Lothar schrieb:> Das wäre es wenn er statt LDI R24, $57 für Register und Adresse> aussagefähige Aliasnamen verwendet hätte.
Das hat die Vorlage vermutlich nicht hergegeben :-)
die 65 dezimal sind in Hex 0x45 oder $45 in der obigen Schreibweise.
Das ist laut Datenblatt http://www.atmel.com/images/doc8246.pdfhttps://www.microchip.com/wwwproducts/en/ATtiny2313#documents
das "WDTCSR – Watchdog Timer Control and Status Register"
Auf Seite 45 des PDF beschrieben. Anscheinend muss man zum Einstellen
zweimal innerhalb einer kurzen Zeit das Register beschreiben.
"Within the next four clock cycles, write a logic 0 to WDE. This
disables the Watchdog"
daher vermutlich auch eine Assemblerroutine, sonst dauert es zu lange.
Lothar schrieb:> A. schrieb:>> Assembler ist besser lesbar als C>> Das wäre es wenn er statt LDI R24, $57 für Register und Adresse> aussagefähige Aliasnamen verwendet hätte.
Vermutlich ist es jedoch ein Inline-Assembler, der die dafür notwendigen
Include-Dateien nicht hat.
Irgendwie sieht das Beispiel aber seltsam aus, Kurt. Schau dir mal bitte
die Beschreibung zum Register WDTCSR im Datenblatt an, damit du
verstehst, was da getan wird. WDTCSR wird zuerst auf 0x57 ($57)
gesetzt, das beschreibt die Bits WDIE, WDCE sowie setzt den Timeout-Wert
auf 7 (= 2 s). Der Timeout-Wert hier wird jedoch ignoriert, da das
WDCE-Bit zuvor noch nicht gesetzt war.
Danach wird das Register auf 0x31 ($31) gesetzt, dabei wird das zuvor
gesetzte WDIE wieder gelöscht, WDCE bleibt gesetzt, der Timeout wird
jetzt auf 9 gesetzt (= 8 s).
In einem dritten Schritt wird übermäßig verklausuliert in diesem
Register nun das WDE-Bit gesetzt und damit der Watchdog freigeschaltet.
Das hätte man erstens im Prinzip auch schon im vorhergehenden Schritt
erledigen können, zweitens ist ja die Zahl, die sich in diesem Register
befindet, sowas von bekannt, dass man sie nicht extra aus diesem
rücklesen müsste.
Das Ganze ist also äquivalent zu:
1
$asm
2
push r24
3
4
LDI R24, $79 ' WD auf 8 Sekunden setzen und starten
5
STS 65, r24
6
STS 65, r24
7
8
pop r24
9
10
$end Asm
Für deine 2 Sekunden müsstest du den Timer auf 7 setzen:
1
$asm
2
push r24
3
4
LDI R24, $57 ' WD auf 2 Sekunden setzen und starten
5
STS 65, r24
6
STS 65, r24
7
8
pop r24
9
10
$end Asm
Edit: WDTCSR liegt in dem Bereich, der auch für IN/OUT zugreifbar ist,
man könnte also auch kürzer und schneller schreiben:
1
$asm
2
push r24
3
4
LDI R24, $57 ' WD auf 2 Sekunden setzen und starten
Dieter F. schrieb:> = kopiert ?
eine externe Quelle die
>> .equ WDTCR = 0x21;dez: 33>> out WDTCR, r24;
als
> STS 65 , r24; doppelte Befehlslänge;
programmiert, dürfte sich wohl kaum finden lassen.
==> mit sehr großer Wahrscheinlichkeit nicht kopiert (oder eine sehr
spezielle Kopierquelle)
Dirk schrieb:> programmiert, dürfte sich wohl kaum finden lassen.> ==> mit sehr großer Wahrscheinlichkeit nicht kopiert (oder eine sehr> spezielle Kopierquelle)
Es gibt auch andere AVR's ... und kopieren heisst nicht verstehen.
Dirk schrieb:> eine externe Quelle die>>> .equ WDTCR = 0x21;dez: 33>>> out WDTCR, r24;> als>> STS 65 , r24; doppelte Befehlslänge;> programmiert, dürfte sich wohl kaum finden lassen
Wie erklärst Du dann
Kurt schrieb:> (was> bedeutet das "$" Zeichen? Hex-Zahl?
Dieter F. schrieb:> Dirk schrieb:>> programmiert, dürfte sich wohl kaum finden lassen.>> ==> mit sehr großer Wahrscheinlichkeit nicht kopiert (oder eine sehr>> spezielle Kopierquelle)>> Es gibt auch andere AVR's ... und kopieren heisst nicht verstehen.
das heißt du kennst Quellen die
>> out io_adresse,register
als
> sts io_adresse+$20, register; memory mapped IO, gefühlt als normaler Speicher
programmieren würden.
Dein Hinweis dass es "auch" andere AVR gibt, während Dieter nicht die
allen AVR gemeinsame doppelte Adressierungsmöglichkeit versteht, die im
speziellen Fall sehr bequem zum Unverständnis genutzt werden kann,
deutet auf eine starke Ähnlichkeit von Diether und Kurt hin. Vielleicht
war deswegen der Kopierverdacht für dich so naheliegend.
Auch in C oder Basscom ließe
MemoryMapped(port_a)=0
MemoryMapped(port_a)=20
bequem als
>Wird denn da das 'Ram'(Port) nicht einfach überschrieben?
hinterfragen. Das hat nichts mit der Programmiersprache zu tun, sondern
mit der Unkenntnis, dass bei ALLENAVR (auch den von Diether F. zur
Hilfe benötigten "anderen" AVR) IO_Adressen keine ram_Adressen sind.
Dirk schrieb:> während Dieter nicht die> allen AVR gemeinsame doppelte Adressierungsmöglichkeit versteht, die im> speziellen Fall sehr bequem zum Unverständnis genutzt werden kann,
Blubb :-)
Du kannst mich auch gerne mit "th" oder "xx" schreiben ...
Dieter F. schrieb:> Dirk schrieb:>> während Dieter nicht die>> allen AVR gemeinsame doppelte Adressierungsmöglichkeit versteht, die im>> speziellen Fall sehr bequem zum Unverständnis genutzt werden kann,>> Blubb :-)>> Du kannst mich auch gerne mit "th" oder "xx" schreiben ...
das ist verständlich wenn du "Blubb " mit Zeichenergänzung verstehst.
"Blubb :-)" oder eine Ergänzung "Es gibt */auch/* andere AVR's ..." in
der der Herausgeber erklärt dass er das Wort "auch" nicht versteht (oder
den zitierten Text nicht lesen konnte) sind sicherlich auch spezielle
Fälle um ein Unverständnis zu schildern.
Wenn Diexxer nur Blubb und "es gibt andere AVR" versteht, dann bleibt
eine Kopie ohne plausible Quelle natürlich für den Betroffenen die
einzig plausible Antwort.
Dirk schrieb:> Wenn Diexxer nur Blubb und "es gibt andere AVR" versteht, dann bleibt> eine Kopie ohne plausible Quelle natürlich für den Betroffenen die> einzig plausible Antwort.
Ja - was auch immer Du damit meinst :-)
Jörg W. schrieb:> Vermutlich ist es jedoch ein Inline-Assembler, der die dafür notwendigen> Include-Dateien nicht hat
Dann kann man immer noch #define machen oder halt kommentieren.
Lothar schrieb:> Dann kann man immer noch #define machen oder halt kommentieren.
#define in Bascom?
Kommentieren: ja.
(Davon abgesehen, dass die Behauptung im Raum steht, dass Bascom das
auch anders könnte. Kann ich nicht beurteilen, könnte Kurt ja selbst
recherchieren.)
Jörg W. schrieb:> Könntet ihr euer Geplänkel bitte woanders austragen? Danke. Es stört> hier.
die einfachere Schreibweise
>> .equ WDTCR = 0x21;dez: 33>> out WDTCR, r24;
als
> STS 65 , r24; doppelte Befehlslänge;
dürfte dem Verständnis eher förderlich sein. Wenn der mutmaßlich
kopiebedürftige Dieter K. darauf 'antwortet' "Wie erklärst Du dann..",
dann ergibt das scheinbares Geplänkel.
Warum "Dieter F."(Schreibweise ohne th aus der Überschrift seiner
Ausgaben) nur "Blubb" und regelmäßiges ":-)" Verständnis ausgibt und
noch nicht auf Texte antworten kann ist seine Sache.
Die andere (auch verbreitetere) Schreibweise für die exakt gleiche
Programmwirkung
>> .equ WDTCR = 0x21;dez: 33>> out WDTCR, r24;
sollte eigentlich nicht stören.
Jörg W. schrieb:> Könntet ihr euer Geplänkel bitte woanders austragen? Danke. Es stört> hier.
Ist das ein Forum? Nicht nur für Moderatoren?
Dirk schrieb:> Dieter K.Dirk schrieb:> Dieter F.Dirk schrieb:> Schreibweise ohne th aus der Überschrift seiner> Ausgaben
Das was Kurt da geschrieben hat ist schlicht und ergreifend kopiert -
ohne den Sinn zu hinterfragen. Natürlich kann man es anders machen.
Sogar in Bascom. Und jetzt werde ich Jörg auch nicht weiter stören.
Hi,
da ich gerade auch mit dem Watchdog zu tun hatte,
gibt es zwei Dinge, die man hier vorausschicken möchte:
Wenn der Watchdog einmal gesetzt wird, dann kann über die
wdr Anweisung im Programm nur resettet werden, wenn das Programm bis zum
Erreichen der nächsten wdr-Anweisung mehr Zeit braucht, als etwa 2
Sekunden.
Mehr ist nicht drin. Also 8 Sekunden Timeout Intervall, das glaub ich so
erst einmal nicht. Müsste ich erst selber ausprobieren.
Dann Fall zwei:
soll mitten im Programm noch einmal etwas am Watchdog geändert werden,
geht das nur, wenn die sog. "atomic action" ausgeführt wird.
Das heißt, alle Interrupts vorher sperren "cli", dann innerhalb von
5 Taktzyklen diese Aktion ausführen, sonst wird nichts geändert. Dann
wieder Interrupts enablen mit sei (Angabe fehlt im Tutorial hier. Sollte
aber wohl noch rein. Änderungsvorschlag, Euer Ehren.)
Das hat @Christoph oben ja schon gesagt.
Christoph K. schrieb:> das "WDTCSR – Watchdog Timer Control and Status Register"> Auf Seite 45 des PDF beschrieben. Anscheinend muss man zum Einstellen> zweimal innerhalb einer kurzen Zeit das Register beschreiben.> "Within the next four clock cycles, write a logic 0 to WDE.
Jetzt spinnt aber gerade der ATTiny4313 manchmal, obwohl man
programmtechnisch alles richtig gemacht hat. Dem Phänomen muß ich noch
nachspüren.
Jetzt habe ich mir einmal die Einträge im Register WDTCR auf den Output
gelegt, um zu schauen, was da wirklich reingeschrieben wird.
Das sind dann die Angaben =decxx im ASM File oben.
ciao
gustav
Karl B. schrieb:> Also 8 Sekunden Timeout Intervall, das glaub ich so erst einmal nicht.
Die älteren AVRs konnten in der Tat nur maximal 2 s als Timeout, aber
das ist später mal „aufgebohrt“ worden bis 8 s.
Kurt benutzt den übrigens offensichtlich nicht im Reset-Modus, sondern
im Interrupt-Modus. Habe ich für den gleichen Zweck wie er auch schon
genommen, man muss dann nur sicherstellen, dass innerhalb des nächsten
Intervalls auch tatsächlich der Interrupt bearbeitet wird. Mit Ablauf
eines zweiten Timeouts gibt's ansonsten doch noch einen Reset.
Jörg W. schrieb:> Vermutlich ist es jedoch ein Inline-Assembler, der die dafür notwendigen> Include-Dateien nicht hat.
Falsch vermutet. Da ist der TE selbst schuld, wenn er nicht die
Möglichkeiten des Assemblers kennt oder nutzt. Jedes AVR-Datenblatt hat
ein paar Assembler-Beispiele, übersetzt sieht das in Bascom nicht viel
anders als im Datenblatt aus:
Jörg W. schrieb:> Für deine 2 Sekunden müsstest du den Timer auf 7 setzen:$asm> push r24>> LDI R24, $57 ' WD auf 2 Sekunden setzen und starten> STS 65, r24> STS 65, r24>> pop r24>> $end Asm
Bei mir ist das nicht gelaufen.
Wenn ich es so aufsetze dann geht's.
------------------------------------------------------------
' bxx0xx111 WD Teiler Festlegung auf 256K cycles (2 sek)
' bxxx1xxxx Watchdog Change Enable
' bx1xxxxxx Watchdog Enable/eingeschaltet (wird erst auf 1 dann auf
0 geschaltet)
1
$asm
2
3
push r24
4
LDI R24, 01010111b '($57) WD = 2 sec)
5
STS 65, r24
6
LDI R24, 00110111b '($37)
7
STS 65, r24
8
LDI R24, 00111111b '($3F)
9
STS 65, r24
10
pop r24
11
12
$end Asm
---------------------------------------------------------------
Kurt
MWS schrieb:>> Davon abgesehen, dass die Behauptung im Raum steht, dass Bascom das>> auch anders könnte.>> Config Watchdog = 2048
Das benutzt den Watchdog dann auch im Interruptmodus? Darum ging's
ja wohl hier vor allem, das Dingens soll ja nicht mit einem Reset
aus dem Schlaf gerissen werden.
Ansonsten sieht aber die Bascom-mäßige Assemblersyntax allemal
besser lesbar aus als das bloße Hinschreiben von ein paar Zahlen.
Kurt schrieb:> Wenn ich es so aufsetze dann geht's.
Dann hast du nun zumindest einen gangbaren Weg.
Das Ersetzen von STS durch OUT sollte jedoch allemal funktionieren
(dann allerdings Adresse 33 statt 65).
Ich würde mir an deiner Stelle auf jeden Fall nochmal MWS' Variante
ansehen.
Jörg W. schrieb:> MWS schrieb:>>> Davon abgesehen, dass die Behauptung im Raum steht, dass Bascom das>>> auch anders könnte.>>>> Config Watchdog = 2048>> Das benutzt den Watchdog dann auch im Interruptmodus? Darum ging's> ja wohl hier vor allem, das Dingens soll ja nicht mit einem Reset> aus dem Schlaf gerissen werden.
Er soll schon aus dem Schlaf gerissen werden (sorry das hatte ich nicht
erwähnt).
Aufwachen, einen Zählerkontakt usw. abfragen, ev. Zählerstand erhöhen
schlafen.
Nach X Zyklen dann den Zählerstand abschicken.
Ich muss Strom sparen (Batteriebetrieb), darum das komplette
Ausschalten.
Kurt
Kurt schrieb:> Er soll schon aus dem Schlaf gerissen werden (sorry das hatte ich nicht> erwähnt).
Yep, doch aber nicht mit einem Reset, sondern mit einem Interrupt –
zumindest deute ich dein gesetztes WDIE-Bit so (und so hätte und habe
ich das auch selbst gemacht).
Jörg W. schrieb:> Kurt schrieb:>> Wenn ich es so aufsetze dann geht's.>> Dann hast du nun zumindest einen gangbaren Weg.
Ja, und darum möchte ich mich hier bei dir und all denen bedanken die
mitgeholfen haben das ich das 'ausreichend' verstanden habe.
>> Das Ersetzen von STS durch OUT sollte jedoch allemal funktionieren> (dann allerdings Adresse 33 statt 65).
OK
>> Ich würde mir an deiner Stelle auf jeden Fall nochmal MWS' Variante> ansehen.
Da müsste ich mich selber erst einführen.
Vor vielen Jahren habe ich mal Z80 Assembler gemacht, und da ist die
direkte Art der Befehlsbenennung halt hängen geblieben.
Ich mache ja nur sehhhhr selten was in Maschinensprache, das bisserl
Basic das ich kann reicht meistens aus um dem AVR usw. das mitzuteilen
was er zu machen hat.
Kurt
Jörg W. schrieb:> Kurt schrieb:>> Er soll schon aus dem Schlaf gerissen werden (sorry das hatte ich nicht>> erwähnt).>> Yep, doch aber nicht mit einem Reset, sondern mit einem Interrupt –> zumindest deute ich dein gesetztes WDIE-Bit so (und so hätte und habe> ich das auch selbst gemacht).
So lege ich ihn nieder:
---------------------------
Powerdown ' Abschalten und auf WD warten
Mcucr = &B01110000 ' Power Doun vorbereiten
Waitms 20
sleep
-------------------------------
Kann sein das das doppelt gemobbelt ist.
Der Reset geht deswegen weil das RAM nicht überschrieben wird, somit der
Zählerstand erhalten bleibt.
$noramclear
Kurt
.
Noch eins:
SRAM => Register, direkt LDS r1,k65535
Heisst das, dass das Zielregister 16 Bit hat?
Oder was steckt dahinter das hier ein Word geschrieben werden kann.
Kurt
Kurt schrieb:> SRAM => Register, direkt LDS r1,k65535>> Heisst das, dass das Zielregister 16 Bit hat?
Nein, das Zielregister ist ja r1, das hat nur 8 Bit. Rechts steht
dagegen eine Adresse (von der die Daten im RAM gelesen werden
sollen), und die hat 16 Bit.
Jörg W. schrieb:> Kurt schrieb:>>> SRAM => Register, direkt LDS r1,k65535>>>> Heisst das, dass das Zielregister 16 Bit hat?>> Nein, das Zielregister ist ja r1, das hat nur 8 Bit. Rechts steht> dagegen eine Adresse (von der die Daten im RAM gelesen werden> sollen), und die hat 16 Bit.
Ach so!!, ich hatte das für eine Konstante gehalten.
Kurt
Kurt schrieb:> Ach so!!, ich hatte das für eine Konstante gehalten.
Ist es auch, aber eben eine konstante (also zur Compilezeit bekannte)
Adresse, typisch also der Speicherplatz, der für eine Variable belegt
worden ist.
Jörg W. schrieb:> Das benutzt den Watchdog dann auch im Interruptmodus?
Nein, da müsste man noch nachhelfen.
Das Datenblatt bezieht sich mit der "timed-sequence" ausschließlich auf
Änderungen des WD-Prescalers und Ausschalten des Watchdogs.
> The sequence for clearing WDE and changing time-out configuration> is as follows:> 1. In the same operation, write a logic one to the Watchdog change> enable bit (WDCE) and WDE. A logic one must be written to WDE> regardless of the previous value of the WDE bit.> 2. Within the next four clock cycles, write the WDE and Watchdog> prescaler bits (WDP) as desired, but with the WDCE bit cleared.> This must be done in one operation
Auf WDIE wird kein Bezug genommen, was bedeuten könnte, dass dieses Bit
ohne getimte Sequenz zu ändern wäre. Sollte diese Annahme richtig sein,
so würde:
1
Config Watchdog = 2048
2
Start Watchdog
3
Set WDTCSR.WDIE
den Watchdog in den "Interrupt and System Reset Mode" versetzen, welcher
im Vergleich zum reinen WDInt-Mode sicherer wäre. Vielleicht möchte
jemand testen?