. 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
Und da sagen manche hier allen ernstes, Assembler ist besser lesbar als C.... Kopfschüttel...
A. schrieb: > Und da sagen manche hier allen ernstes, Assembler ist besser lesbar als > C.... Kopfschüttel... Ist Kopfschüttel ein Kumpel von dir?
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. So sollte ein Timer in ASM aussehen: https://www.riscosopen.org/viewer/view/mixed/RiscOS/Sources/HAL/BCM2835/s/Timers?rev=1.3;content-type=text%2Fplain
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.pdf https://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 |
5 | OUT 33, r24 |
6 | OUT 33, r24 |
7 | |
8 | pop r24 |
9 | |
10 | $end Asm |
Christoph K. schrieb: > die 65 dezimal sind in Hex 0x45 oder $45 in der obigen Schreibweise. Nö, 0x41. :) Passt aber, das ist WDTCSR.
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)
Beitrag #5339696 wurde von einem Moderator gelöscht.
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 ALLEN AVR (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.
Beitrag #5340047 wurde von einem Moderator gelöscht.
Beitrag #5340057 wurde von einem Moderator gelöscht.
Beitrag #5340068 wurde von einem Moderator gelöscht.
Beitrag #5340084 wurde von einem Moderator gelöscht.
Beitrag #5340147 wurde von einem Moderator gelöscht.
Beitrag #5340163 wurde von einem Moderator gelöscht.
Beitrag #5340208 wurde von einem Moderator gelöscht.
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:
1 | WDT_Prescaler_Change: |
2 | !CLI |
3 | !WDR |
4 | !IN r16, WDTCSR |
5 | !ORI r16, 2^WDCE + 2^WDE |
6 | !OUT WDTCSR , r16 |
7 | !LDI r16, 2^WDE + 2^WDP2 + 2^WDP1 + 2^WDP0 ' 2 Sek. |
8 | '!LDI r16, 2^WDE + 2^WDP3 + 2^WDP0 ' 8 Sek. |
9 | !out WDTCSR, r16 |
10 | !SEI |
11 | !RET |
Jörg W. schrieb: > Davon abgesehen, dass die Behauptung im Raum steht, dass Bascom das > auch anders könnte.
1 | Config Watchdog = 2048 |
Jörg W. schrieb: > #define in Bascom? Nennt sich "Const"
Beitrag #5340270 wurde von einem Moderator gelöscht.
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?
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.