mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Uhr mit Wochentag und Datum


Autor: Axel H. (mf-futzi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: AVRFan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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.

Autor: Axel H. (mf-futzi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo an alle,

über Tabellen habe ich im Tutorial nichts gefunden. Weis jemand, wo 
etwas über die Anwendung von Tabellen (Asm) beschrieben steht?

Danke

Autor: Berti (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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-Tutori...
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).

Autor: Niels Hüsken (monarch35)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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....

Autor: Sebastian Heyn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: AVRFan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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)

Autor: Axel H. (mf-futzi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Axel H. (mf-futzi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: AVRFan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schau Dir mal den Befehl "lpm" an.

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und schau Dir mal Deinen Build-Output an, der hat bestimmt 'ne Menge 
Warnungen. Doppelklick auf die Warnung zeigt Dir den Fehler...

...

Autor: Hannes Lux (hannes)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Im Anhang findest Du eine Routine, die indizierten Text aus Tabelle 
ausgenen kann. Eine zugehörige Tabelle könnte so aussehen:
mt:                         ;Indexliste Menütexte
.dw mt0,mt1,mt2,mt3
.dw mt4,mt5,mtr,mtr
.dw mtr,mtr,mt10,mt11
.dw mt12,mt13,mt14,mt15

mt0:    .db 4,   "Pos.Show Rpt.   Home    Up 1    Up 10 ",13
        .db      "                Delete  Show-Nr Repeat ",13
        .db      "                End     Down 1  Down 10",13
        .db      "                Abbruch Del.all Start ",1,0

mt1:    .db 9,16,"1 Dimmwerte laden       ",9,56
        .db      "Speicherplatz-Nr        ",9,96
        .db      "(00-63):",1,0

mt2:    .db 9,16,"2 Dimmwerte speichern   ",9,56
        .db      "Speicherplatz-Nr        ",9,96
        .db      "(00-63):",1,0

mt3:    .db 9,16,"3 Auswahl PWM-Kanal     ",9,56
        .db      "Kanal-Nr                ",9,96
        .db      "(00-15):",1,0

mt4:    .db 9,16,"4 Dimmwert Kanal ",13,9,56
        .db      "einstellen              ",9,96
        .db      "(00-99):",1,0

mt5:    .db 9,16,"5 Dimmtempo beim Wechsel",9,56
        .db      "der Dimmwerte           ",9,96
        .db      "(00-99):",1,0

mt10:   .db 9,56,"16-Kanal-Lichtsteuerung ",9,96
        .db      " (c)  www.hanneslux.de  ",1,0

mt11:   .db 9,16,"1 Laden     2 Saven     ",9,56
        .db      "3 PWM-Kanal 4 Dimmwert  ",9,96
        .db      "5 Dimmtempo, statisch   ",9,136
        .db      "0 Dynam. Lichtsteuerung ",1,0

mt12:   .db 9,16,"5 Lichtshow zur Liste   ",9,56
        .db      "hinzufuegen             ",9,96
        .db      "(00-99):",1,0

mt13:   .db 9,16,"7 Anzahl Wiederholungen ",9,56
        .db      "der Lichtshow           ",9,96
        .db      "(00-99):",1,0

mt14:

mt15:

mtr:    .db 9,16,"Reserviert fuer         ",9,56
        .db      "spaetere Erweiterungen..",0,0

Es handelt sich hier zwar nicht um Wochentage oder Monatsnamen, sondern 
um Menüpunkte, das Prinzip ist aber dasselbe.

...

Autor: Uwe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Axel H. (mf-futzi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Hannes,

keine Fehler, keine Warnungen

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.