Forum: Projekte & Code Berechnung Wochentag, Kalenderwoche etc. in AVR-ASM!


von Andi (Gast)


Angehängte Dateien:

Lesenswert?

Hi!

Im Anhang die Datei "DateFunctions.asm" zum berechnen von Wochentag,
Kalenderwoche und Datum zur Umstellung auf Sommer- oder Winterzeit im
März und Oktober.
Eigentlich erkärt sich der Code von selbst und ich spare mir hier große
Erkärungen dazu.
Das einzige, was man mit nen CALL oder RCALL aufrufen muß, ist die
Routine "SetWDCWSW". Die rechnet mit Hilfe der anderen Funktionen
dann alles durch (Wochentag, Kalenderwoche, Datun für Sommer- und
Winterzeitumstellung).
In dem Datum-Arry im SRAM müßt Ihr zum probieren oder mit eurem
Datum-Programm passende Daten in "Datum", "Monat" und "Jahr"
einsetzen, kann natürlich auch direkt von eurem Datum-Programm
benutzt/verwaltet werden.
Man kann auch für die Prüfung ob der Februar 28 oder 29 Tage hat die
Funktion "TestSJ" ("Test SchalJahr") verwenden.
Ist das Carry-Bit nach dieser Funktion gesetzt, hat der Februar im
eingestellten Jahr unter "Jahr" 29 Tage, ansonsten 28.
Das Carry-Bit kann man dann einfach zur Addition verwenden wie es in
der Funktion "DayOfYear" bereits gemacht wird.
Z. B.:
 ldi r16,28        ;28 Tage für Februar setzen
 rcall TestSJ      ;Auf Schaltjahr testen
 adc r16,null      ;0 + Schaltjahr (Carry) addieren.

Inspiriert wurde ich dazu von
http://home.nordwest.net/hgm/kalender/kal-6.htm
Da das alles in C ist habe ich das kurzerhand, lang hats gedauert, in
ASM für Atmel-AVR umgewandelt.

MfG
Andi

von Andi (Gast)


Angehängte Dateien:

Lesenswert?

Ach ja, ganz vergessen!

Die Auswertung des ermittelten Wochentages in WTag:

 0 = Montag
 3 = Donnerstag
 6 = Sonntag

Dazu kann man zur Anzeige des Wochentages folgendes machen:

 lds zl,DateArray+WTag   ;Nummer des Wochentages lesen
 add zl,zl               ;Wochentag mal 4 Zeichen
 add zl,zl
 clr zh
 subi zl,low(-TextWT*2)
 sbci zh,high(-TextWT*2)
 rcall Print ;oder wie auch immer eure Stringausgabe heißt.
 ...

TextWT:
 .db "Mo.",0;(oder irgend ein anderes "Ende-Signal")
 .db "Di.",0
 .db "Mi.",0
 .db "Do.",0
 .db "Fr.",0
 .db "Sa.",0
 .db "So.",0

MfG
Andi

PS: Habe im Code die Bezeichnung "Uhr" geändert in "DateArray" da
ich es hier ohne Uhrzeit-Variablen rein gestellt habe.
Also hier den Code runterladen und nicht oben.

von Andi (Gast)


Lesenswert?

Noch was zur Gültigkeitsdauer der Berechnungen!
Die Funktionen berechnen einen gültigen Wochentag ab dem Jahr 1582 im
Oktober da dort zur Korrektur einfach 10 Tage weggelassen wurden.
Die Dauer der Gültigkeit geht theoretisch bis zum Jahr 65535 (max.
möglicher 16 Bit-Wert für das Jahr).
Aber theoretisch oder evtl. auch praktisch gibt es in 3333 Jahren nach
1582, also ab dem Jahr 4915, wieder eine kleine Korrektur um einen Tag
da auch der Gregorianische Kalender mit der jetzigen Schaltjahrregel
nicht 1000-Prozentig genau ist.
Aber genauer als 99,99% gehts wohl nicht.
Aber das interresiert uns glaube ich noch nicht.

MfG
Andi

von Andi (Gast)


Angehängte Dateien:

Lesenswert?

Ups, dachte eigentlich, ich hätte alle Makrobefehle in reale Befehle
geändert damit das für euch passt.
Für die, die es schon irgendwo eingebaut haben, ändern in der Funktion
"TestSJ" den Befehl "ldiw DV16uL,DV16uH, 100" in

 ldi DV16uL,100
 ldi DV16uH,0

Ansonsten hier im Anhang jetzt komplett ohne Makrobefehle.
Wer die Routinen in einen Tiny ohne "movw" einsetzen möchte, ändert
Befehle wie "movw DD16uL,JahrL" in

 mov DD16uL,JahrL
 mov DD16uH,JahrH

MfG
Andi

von Andi (Gast)


Angehängte Dateien:

Lesenswert?

Hi!

Habe die Funktion "DayOfYear" optimiert.

Anfangs wollte ich die nur um ein paar Befehle kürzen, hatte es auch
dann so umgeformt, das sie mit 3 Befehlen weniger auskam.
Dann ging es mir doch mehr um Geschwindigkeit und da kam das im Anhang
heraus.

In der neuen Version sind die low-Bytes der Tagesnummern für den 31.1,
28.2 ... bis hin zum 31.11 in einer Tabelle und nicht mehr die Tage
eines jeden Monats.
Anhand des Monats wird ein Tabelleneintrag ausgewählt, das Register
DOYL (Day of Year low) entsprechend gesetzt, Schaltjahr, wenn vorhanden
aufaddiert, ab dem Monat 10 das hi-Byte, DOYH, um 1 erhöht und
schließlich das Datum addiert.
Und das ganze passiert, abgesehen von "TestSJ", in 13 oder 15 Takte.

Also, wer möchte, kann die alte Funktion "DayOfYear" mit der im
Anhang ersetzen, ist auch um 3 Words kürzer und wesentlich flotter.

MfG
Andi

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.