Hallo an alle, ich beschäftige mich seit kurzem mit uC und Asm. Nach anfänglichen Problemen habe ich jetzt endlich mein LCD zum Laufen gebracht und nun macht's richtig Spass weiter zu experimentieren (wird zur Sucht). Aus dem Tutorial habe ich nun die Uhr mit CTC-Modus programmiert und funzt toll:-) Aber wenn man Erfolg hatte will man mehr, sprich Wochentag und Datum. Aber wie zählt man die Tage der verschiedenen Monate hoch (28/29/30/31Tage)? Für die Monate wollte ich auch gerne Jan, Feb, Mär, ... ausgeben und nicht die Monatszahl. Im Forum habe ich nichts gefunden, was mir weiterhilft, aber ich bin bestimmt nicht der erste, der sowas macht. Vielleicht kennt jemand einen Link? Oder eine grobe Vorgehenweise, wie ich es selbst programmieren kann. (Atmega8, Assembler) Danke schon mal Axel
>Aber wie zählt man die Tage der verschiedenen Monate hoch >(28/29/30/31Tage)? Du erstellst eine Tabelle mit 12 Einträgen, wo Du die Anzahl der Tage der 12 Monate reinschreibst. >Für die Monate wollte ich auch gerne Jan, Feb, Mär, >... ausgeben und nicht die Monatszahl. Du erstellst eine weitere Tabelle mit 12 Einträgen, wo Du die Namenskürzel der 12 Monate reinschreibst.
Hallo an alle, über Tabellen habe ich im Tutorial nichts gefunden. Weis jemand, wo etwas über die Anwendung von Tabellen (Asm) beschrieben steht? Danke
es gibt da zwei nette Algorithmen. der eine berechnet den ersten Mittwoch(?) des Jahres und der zweite berechnet ob das entsprechende Jahr ein Schaltjahr ist. (kommt alles von der Gaussschen Osterformel?)
Axel Hüser wrote: > Hallo an alle, > > über Tabellen habe ich im Tutorial nichts gefunden. Weis jemand, wo > etwas über die Anwendung von Tabellen (Asm) beschrieben steht? > Hier http://www.mikrocontroller.net/articles/AVR-Tutorial:_7-Segment-Anzeige findet sich was über Tabellen. In diesem Beispiel gibt es eine Tabelle, in der das auf die Anzeige auszugebende Bitmuster enthält, wenn die auszugebende Ziffer bekannt ist. Damit kannst du schon mal die Tageszahl pro Monat lösen, mit Ausnahme des Februars. Der erforert (wenn man es richtig macht) eine Verrechnung der Jahreszahl. Lass die erst mal beiseite und konzentriere dich auf die restlichen Monate und nimm den Februar mit 28 Tagen an (bleibt natürlich nicht so. Irgendwann must du dich den Schaltjahren stellen. Muss aber nicht gleich sein).
Ich presentiere: Mein Wecker mit zwei Weckzeiten, LC-Display (16x2), SSRelay als "Weckgerätschalter" an Port D.3, ein-tasten-bedinung (low-aktiv an Port D.4), Uhrzeit mit Wochentag und Datum. Belegt den Speicher eines AT-Mega8 nur zu 50%. http://www.monarch.de/svn/work/wecker/ Vieleicht kannst du ja die ein oder andere Codezeile verwenden....
Hier mal mein schlecht Dokumentierter Code $regfile = "m8def.dat" $crystal = 16000000 Config Timer1 = Timer , Prescale = 256 On Timer1 Timer_irq Const Timervorgabe = 3036 Dim Year As Integer 'jahr Dim Month As Byte 'monat Dim Dayofmonth As Byte 'tag Dim Timerbit As Bit 'if this bit is set then count another second Dim H As Integer 'hilfsvariable Dim Sj As Bit 'schaltjahrbit Dim Tz As Byte 'tagesziffer Dim Mz As Byte 'monatsziffer Dim Jz As Byte 'jahresziffer Dim Jhz As Byte 'jahrhunderziffer Dim Wt As Byte 'wochentag:0=so, 1=mo etc Dim Hr As Byte Dim Minu As Byte Dim Seco As Byte Dim Jahrstring As String * 5 Dim Jzh1 As Byte 'hilfbyte1 ( letzten beiden stellen) Dim Jzh2 As Byte 'hifsbyte2 Dim Jzh3 As Byte 'hilfbyte3 Dim Jzh4 As Bit 'Startdatum Enable Timer1 Enable Interrupts Do If Timerbit = 1 Then Timerbit = 0 Seco = Seco + 1 If Seco = 60 Then Minu = Minu + 1 Seco = 0 End If If Minu = 60 Then Hr = Hr + 1 Minu = 0 End If If Hr = 24 Then Hr = 0 Dayofmonth = Dayofmonth + 1 End If 'Monatssprung für Februar kann erst nach Schaltjahr-check gemacht werden. If Month = 1 Or Month = 3 Or Month = 5 Or Month = 7 Or Month = 8 Or Month = 10 Then If Dayofmonth = 32 Then Month = Month + 1 Dayofmonth = 1 End If End If If Month = 4 Or Month = 6 Or Month = 9 Or Month = 11 Then If Dayofmonth = 31 Then Month = Month + 1 Dayofmonth = 1 End If End If If Month = 12 And Dayofmonth = 32 Then Month = 1 Dayofmonth = 1 Year = Year + 1 End If 'Schaltjahrerkennung Sj = 0 'erstmal gehen wir von einer 0 aus H = Year Mod 4 If H = 0 Then 'durch 4 teilbar? H = Year Mod 100 Sj = 1 'Ja dann schaltjahr End If 'durch 100 teilbar?? If H = 0 Then 'ja dann H = Year Mod 400 'durch 400 teilbar If H = 0 Then Sj = 1 Else 'ja dann schaltjahr Sj = 0 End If 'nein dann nicht End If If Sj = 1 Then Print " Schaltjahr "; If Sj = 0 Then Print "Kein Schaltjahr "; If Month = 2 And Sj = 1 And Dayofmonth = 30 Then Month = Month + 1 Dayofmonth = 1 End If If Month = 2 And Sj = 0 And Dayofmonth = 29 Then Month = Month + 1 Dayofmonth = 1 End If ' Wochentag berechnen Tz = Dayofmonth Mod 7 'Monatsziffer If Month = 1 Then Mz = 0 If Month = 2 Then Mz = 3 If Month = 3 Then Mz = 3 If Month = 4 Then Mz = 6 If Month = 5 Then Mz = 1 If Month = 6 Then Mz = 4 If Month = 7 Then Mz = 6 If Month = 8 Then Mz = 2 If Month = 9 Then Mz = 5 If Month = 10 Then Mz = 0 If Month = 11 Then Mz = 3 If Month = 12 Then Mz = 5 'Jahresziffer Jahrstring = Str(year) Jahrstring = Right(jahrstring , 2) Jzh1 = Val(jahrstring) Jzh2 = Jzh1 Mod 12 Jzh3 = Jzh2 \ 4 Jz = Jzh1 \ 12 Jz = Jz + Jzh2 Jz = Jz + Jzh3 Jz = Jz Mod 7 'jahrhunderziffer Jahrstring = Str(year) Jahrstring = Left(jahrstring , 2) Jzh1 = Val(jahrstring) Jzh1 = Jzh1 + 4 Jzh4 = 0 Do If Jzh1 = 19 Then Jhz = 0 Jzh4 = 1 End If If Jzh1 = 18 Then Jhz = 2 Jzh4 = 1 End If If Jzh1 = 17 Then Jhz = 4 Jzh4 = 1 End If If Jzh1 = 16 Then Jhz = 6 Jzh4 = 1 End If Jzh1 = Jzh1 - 4 Loop Until Jzh4 = 1 Wt = Tz + Mz Wt = Wt + Jz Wt = Wt + Jhz Wt = Wt Mod 7 If Month < 3 And Sj = 1 Then If Wt = 0 Then Wt = 6 If Wt = 1 Then Wt = 0 If Wt = 2 Then Wt = 1 If Wt = 3 Then Wt = 2 If Wt = 4 Then Wt = 3 If Wt = 5 Then Wt = 4 If Wt = 6 Then Wt = 5 End If If Wt = 0 Then Print "So "; If Wt = 1 Then Print "Mo "; If Wt = 2 Then Print "Di "; If Wt = 3 Then Print "Mi "; If Wt = 4 Then Print "Do "; If Wt = 5 Then Print "Fr "; If Wt = 6 Then Print "Sa "; Print "der " ; Dayofmonth ; "." ; Month ; "." ; Year ; " - " ; Hr ; ":" ; Minu ; ":" ; Seco End If ' timerbit Loop 'hauptschleife Timer_irq: Timer1 = Timervorgabe Timerbit = 1 Return
>Damit kannst du schon mal die Tageszahl pro Monat lösen, mit >Ausnahme des Februars. Der erforert (wenn man es richtig macht) >eine Verrechnung der Jahreszahl. Das ist nun wirklich nicht wild - man erstellt einfach eine zweispaltige Tabelle. In der ersten Spalte stehen die Anzahl der Tage in jedem Monat für die normalen Jahre, in der zweiten dasselbe für die Schaltjahre: AnzahlTageImMonat: .DB 31, 31 ; Januar .DB 28, 29 ; Februar .DB 31, 31 ; ... .DB 30, 30 .DB 31, 31 .DB 30, 30 .DB 31, 31 .DB 31, 31 .DB 30, 30 .DB 31, 31 .DB 30, 30 .DB 31, 31 ; Dezember In der nächsten Zeit (bis zum Jahr 2099) ist ein Jahr genau dann ein Schaltjahr, wenn die Jahreszahl durch 4 teilbar ist. Das kann man in einem Programm leicht überprüfen (Bits Nr. 0 und 1 der Jahreszahl beide = 0)
Danke erstmal für Eure Beiträge. Ich werde mich mal mit dem Syntax und Tabellen befassen und melde mich sicherlich nochmal, wie es geklappt hat, oder weitere Fragen ;-) VG Axel
Hallo, ich hab jetzt noch'ne Frage zu den Tabellen. Aber zuerst mein Code zur Ausgabe am LCD: Ausgabe: (8+8 LCD) ; Ausgabe ab 1.Stelle im LCD ; HIER DEN MONATSNAMEN IM ldi ZL, LOW(MonthName *2) ; LCD AUSGEBEN ldi ZH, HIGH(MonthName *2) rcall lcd_flash_string ldi temp1 , $A8 rcall lcd_command ; Ausgabe ab 9.Stelle im LCD mov temp1, Stunden ; Stunden ausgeben rcall lcd_number ldi temp1, ':' ; ':' ausgeben rcall lcd_data mov temp1, Minuten ; Minuten ausgeben rcall lcd_number ldi temp1, ':' ; ':' ausgeben rcall lcd_data mov temp1, Sekunden ; Sekunden ausgeben rcall lcd_number ldi temp1 , $80 rcall lcd_command end_isr: reti .include "C:\Dokumente und Einstellungen\GDWAZH\Eigene Dateien\Projekte\lcd-routines.asm" MonthName: .db "Jan",0,0 .db "Feb",0,0 .db "Mär",0,0 .db "Apr",0,0 .db "Mai",0,0 .db "Jun",0,0 .db "Jul",0,0 .db "Aug",0,0 .db "Sep",0,0 .db "Okt",0,0 .db "Nov",0,0 .db "Dez",0,0 Wie kann ich jetzt auf eine einzelne Zeile von MonthName zugreifen? Wenn ich nun 'Nov' ausgeben möchte, so ist das das 11.Element der Tabelle. Aber wie übergeben?
Und schau Dir mal Deinen Build-Output an, der hat bestimmt 'ne Menge Warnungen. Doppelklick auf die Warnung zeigt Dir den Fehler... ...
Im Anhang findest Du eine Routine, die indizierten Text aus Tabelle ausgenen kann. Eine zugehörige Tabelle könnte so aussehen:
1 | mt: ;Indexliste Menütexte |
2 | .dw mt0,mt1,mt2,mt3 |
3 | .dw mt4,mt5,mtr,mtr |
4 | .dw mtr,mtr,mt10,mt11 |
5 | .dw mt12,mt13,mt14,mt15 |
6 | |
7 | mt0: .db 4, "Pos.Show Rpt. Home Up 1 Up 10 ",13 |
8 | .db " Delete Show-Nr Repeat ",13 |
9 | .db " End Down 1 Down 10",13 |
10 | .db " Abbruch Del.all Start ",1,0 |
11 | |
12 | mt1: .db 9,16,"1 Dimmwerte laden ",9,56 |
13 | .db "Speicherplatz-Nr ",9,96 |
14 | .db "(00-63):",1,0 |
15 | |
16 | mt2: .db 9,16,"2 Dimmwerte speichern ",9,56 |
17 | .db "Speicherplatz-Nr ",9,96 |
18 | .db "(00-63):",1,0 |
19 | |
20 | mt3: .db 9,16,"3 Auswahl PWM-Kanal ",9,56 |
21 | .db "Kanal-Nr ",9,96 |
22 | .db "(00-15):",1,0 |
23 | |
24 | mt4: .db 9,16,"4 Dimmwert Kanal ",13,9,56 |
25 | .db "einstellen ",9,96 |
26 | .db "(00-99):",1,0 |
27 | |
28 | mt5: .db 9,16,"5 Dimmtempo beim Wechsel",9,56 |
29 | .db "der Dimmwerte ",9,96 |
30 | .db "(00-99):",1,0 |
31 | |
32 | mt10: .db 9,56,"16-Kanal-Lichtsteuerung ",9,96 |
33 | .db " (c) www.hanneslux.de ",1,0 |
34 | |
35 | mt11: .db 9,16,"1 Laden 2 Saven ",9,56 |
36 | .db "3 PWM-Kanal 4 Dimmwert ",9,96 |
37 | .db "5 Dimmtempo, statisch ",9,136 |
38 | .db "0 Dynam. Lichtsteuerung ",1,0 |
39 | |
40 | mt12: .db 9,16,"5 Lichtshow zur Liste ",9,56 |
41 | .db "hinzufuegen ",9,96 |
42 | .db "(00-99):",1,0 |
43 | |
44 | mt13: .db 9,16,"7 Anzahl Wiederholungen ",9,56 |
45 | .db "der Lichtshow ",9,96 |
46 | .db "(00-99):",1,0 |
47 | |
48 | mt14: |
49 | |
50 | mt15: |
51 | |
52 | mtr: .db 9,16,"Reserviert fuer ",9,56 |
53 | .db "spaetere Erweiterungen..",0,0 |
Es handelt sich hier zwar nicht um Wochentage oder Monatsnamen, sondern um Menüpunkte, das Prinzip ist aber dasselbe. ...
Hi!
>Wenn ich nun 'Nov' ausgeben möchte, so ist das das 11.Element der Tabelle.
nein, Eine Monatsangabe hat doch bei dir 5 Byte oder? Also 10 "deiner"
Elemente willst du überspringen-> 10 x 5 Byte = 50 Byte, also
ldi ZL, LOW(MonthName *2) ; LCD AUSGEBEN
ldi ZH, HIGH(MonthName *2)
ldi temp1,50
clr temp2
add ZL,temp1
adc ZH,temp2
:
:
sollte Nov ausgeben.
Viel Erfolg, Uwe
Axel Hüser wrote: > Hallo Hannes, > > keine Fehler, keine Warnungen Dann hast Du in den Einstellungen die Warnungen deaktiviert... Bei Tabellen (Listen) mit einfachen nullterminierten Texten ist das kein Problem, der Assembler hängt halt noch ein Nullbyte an, aber man sollte sich trotzdem angewöhnen, die Anzahl der Bytes in einem .db-Eintrag geradzahlig zu galten. Das ist in Deinem Code definitiv nicht so: .db "Jan",0,0 ; 5 Bytes, ist nicht geradzahlig... .db "Feb",0,0 .db "Mär",0,0 Uwe wrote: >> Wenn ich nun 'Nov' ausgeben möchte, so ist das das 11.Element der >> Tabelle. > nein, Eine Monatsangabe hat doch bei dir 5 Byte oder? Also 10 "deiner" > Elemente willst du überspringen-> 10 x 5 Byte = 50 Byte, also > ldi ZL, LOW(MonthName *2) ; LCD AUSGEBEN > ldi ZH, HIGH(MonthName *2) > ldi temp1,50 > clr temp2 > add ZL,temp1 > adc ZH,temp2 > : > : > sollte Nov ausgeben. Das wird so einfach nicht gehen, denn es gibt keie .db-Zeile mit 5 Bytes. Der Assembler hängt da ein 6. Byte an, damit die Anzahl der Bytes wieder geradzeilig wird, der Flash ist nämlich wordadressiert, jede Zelle fasst zwei Bytes. Daher ist es besser, eine Indexliste zu führen und eine Ausgaberoutine zu schreiben, die mit Indexliste (die die eigentlichen Adressen der Texte enthält, die auch noch unterschiedlich lang sein dürfen) arbeitet, siehe mein Beispiel. Abgesehen davon nützt diese Routine sowiso nichts, da der Monat nicht als Konstante vorliegt, sondern als Variable. > ldi temp1,50 > clr temp2 funktioniert da nicht... ...
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.