Hi,
Lösungsansatz ebenfalls per PN, und wir denken das Gleiche, uwegw... ;D
ich werd mal versuchen, in gebrochenem ASM zusammenzustückeln...
VLG...
Druckbare Version
Hi,
Lösungsansatz ebenfalls per PN, und wir denken das Gleiche, uwegw... ;D
ich werd mal versuchen, in gebrochenem ASM zusammenzustückeln...
VLG...
Für die abgekündigten AVRs hab ichs noch nicht durchgeschaut, da müsste ich mir erst alle Datenblätter saugen (und das bei 56k).Zitat:
Zitat von uwegw
Mit den aktuellen AVRs geht's aber.
*Birne-rauch*
Mit einem AT90S8515 hab ich ne Lösung mit 14 Bytes Code (7 kurze Instruktionen). Zumindest nach dem Datenblatt sollte es gehen.
Hi
Also hier meine lösung, hierbei gilt:
I've just checked it correctly, not tried it.
-> ich glaube auch nicht, dass der Code funzt... :D
Naja. Wie gesagt, das setzen der IOs als output gilt nicht als Code... :DCode:
.include "m16def.inc"
;system-deklaration (gehört nicht zum Code.... :D)
ldi R17 , 0b111111
out DDRb , R17
out PORTb , R17
;hier beginnt der Code
sbis portb , 0 ;... ... ... portb.1 invertieren... umständlich
sbi portb , 0
sbic portb , 0
cbi portb , 0
ldi R16 , 0b00011110 ; Watchdog-Controllregister laden
out WDTCR , R16
ldi R16 , 0b00000000 ;Sleepmode setzen, sucht euch einen raus
out MCUCR , R16
sleep ;schlafen
Ohne das ist der code 9 zeilen lang, mit 12 (eig. 11) und ergibt 12 Bytes.
-> ich bin überzeugter Basic-Progger, der warscheinlcih bald auf C umsteigt, und in ASM bin ich nicht so gut (miserabel)... ;D
VLG Tobi
@tobimic, nö, das funzt net. Die LED wird immer leuchten.
Das Problem bei der Sache ist ja, dass man irgendwie ein Bit über den Reset hinaus retten muss, um zu wissen, wo man weiterblinken muss...
Die Register werden plattgemacht und das EEPROM würde das nicht lange mitmachen...
Code:
...dachte ich zumindestens bis jetzt immer, dass ein Reset die Register killt!
Informationen dazu waren nicht wirklich zu finden, aber Versuch macht klug:
.INCLUDE "8515def.inc" ;Prozessordefinition laden
;Register zum Speichern des alten Zustandes
.DEF altwert= R17
.cseg
.org $0000
;Watchdog einstellen und starten
ldi r16, 0b00001110 ;nach 1 sec Reset
out WDTCR, r16
;Alten Wert invertiern und ausgeben
COM altwert
OUT DDRb, altwert
OUT PORTb, altwert
loop:
rjmp loop
Funktioniert und macht nur 6 Words...
[EDIT: erst hatte ich ne Version mit Speicherung im SRAM hochgeladen, aber es scheint ja auch mit nem Register zu gehen...]
Wo wird denn der Port auf OUT geschaltet?
Ok, so blinkt die LED, wenn man sie gegen GND hängt. Sie wird dann über den PullUp versorgt. Für superhelle LEDs recht das.
Ich hab grad ne bessere Version nachgeschoben ... andere Methode aufgrund von neuen experimentalen Erkentnissen, jetzt mit 6 Words... inklusive Port als Ausgang einstellen...
(den einen Befehl gegenüber deiner Vorgabe von 7 spart man, wenn man mit dem Programm sofort an .ORG =$0000 beginnt und nicht erst noch nen Sprung einbaut, der sonst wegen Interruptvektoren nötig wäre)
Jepp, fast so hatte ich es auch gelöst, nur daß bei mir nix ausser einem Port-Pin wackelt:
Code:
; Hier für AT90S8515, AT90S1200, ...
/*
Die Register (GPRs) werden durch einen RESET nicht zurückgesetzt, sondern behalten ihre Inhalte!
Wirklich schwer wird es, wenn man mit VCC runter geht, weil sich dann die WDT-Zeiten ändern. Mit 0.19s (VCC=3V) käme man auf 5% Fehler, aber den Vergleich auf 5 (bzw. modulo 5) hab ich nicht in weniger als 10 Instruktionen geschafft.
Noch nicht... ;-)
*/
#include <avr/io.h>
#define _IO(x) _SFR_IO_ADDR(x)
.text
; #1: PortB.2 als Ausgang
sbi _IO (DDRB), 2
; #2-#4: Toggle PortB.2
inc r0
sbrs r0, 1
sbi _IO (PORTB), 2
; #5-#6: WatchDog auf 0.49 Sekunden scharf machen (genauer als 0.97s)
ldi r16, (1 << WDE) | (1 << WDP2) | (1 << WDP0)
out _IO (WDTCR), r1
; #7: Warten, bis es wieder los geht (WatchDog-Reset)
0:
rjmp 0b
Hier ist noch meiner Version mit Watchdog von gestern Abend.
Ich war mir zuerst nicht sicher ob ihr auch den Watchdog gelten läst, immerhin ist der doch recht ungenau (bei mir über 4 sek. in der Minute).
Leider blinkt die LED nicht, sondern wird immer kurz gepulst (man sieht es aber) und der Komplette Flash wird durchlaufen...
5 Maschienenbefehle:
Beim genauerem betrachten ist der Code aber absuluter Quatsch, die LED wird in wirklichkeit andauernd gepulst (allerdings zu schnell fürs menschliche Auge) da der Code mehrmals durchlaufen wird, nur wenn der Watchdog einsprignt ist die Pause ein wenig länger und man sieht jede sekunde ein kurzes flashen...Code:
.include "m16def.inc"
ldi r16, (1<<wde|1<<WDP2|1<<WDP1)
out WDTCR, r16
sbi ddrB, 2
com r20
out PortB, r20
Besser und nur eine Zeile länger, ist es den Controller einfach zu beschäftigen wie man es ja auch normalerweise macht #-o
Code:
.include "m16def.inc"
ldi r16, (1<<wde|1<<WDP2|1<<WDP0)
out WDTCR, r16
sbi ddrB, 2
com r20
out PortB, r20
ende:
rjmp ende
Aber das ist dann ja schon die Lösung von uwegw.
Ich fand das Rätsel auf jeden Fall sehr gut, sollten wir mit einer anderen (komplexeren?) Aufgabe wiederholen.
Gruß,
Mehto
Freut mich, wenn das Knobeln Spaß gemacht hat :-)
Als erstes hat uwegw die 10 Instruktionen unterschritten.
@Mehto: Kannst ja was überlegen. Jedoch find ich für solche Knobeleien gerade einfache Aufgaben interessant, da gibt es schon trickreiche Lösungsansätze und Ideen genug. Und zu oft sollte ein Themenbereich auch nicht beackert werden, find ich...