Forum: Projekte & Code Rheinturmuhr mit AVR 90S2313


von Thomas Klapper (Gast)



Lesenswert?

Ich (Assembler Anfänger, komme eigentlich aus der
Industrieautomatisierung)
habe als mein erstes Projekt die Düsseldorfer Rheinturmuhr auf dem
Atmel AT90S2313 programmiert.
Das Ergebniss gibt es hier:
http://www.thomasklapper.de/rheinturmuhr.html

Wer Interresse hat mir ein wenig unter die Arme zu greifen, ich bin um
jede Hilfe dankbar. Besonders die Genauigkeit macht mir noch Sorgen.
Geplant ist, wenn ich das irgendwann mal hinbekomme, die Uhr über DCF
zu stellen. Aber das ist noch ein weiter Weg.

Bis dahin,

von crazy horse (Gast)


Lesenswert?

erstmal Kompliment, wenn das wirklich dein 1.eigenes Programm ist.
Der 1.Blick bei Anfängerprogrammen führt mich immer zum SP und zu den
Interupts. Ersteres gut gemacht (=nicht vergessen), die Timer-ISR nicht
so ganz.
Grober Schnitzer - du hast vergessen das SREG zu sichern.
2 prinzipielle Möglichkeiten: ein Register nur dafür reservieren
.def sreg_bak R1

in sreg_bak, sreg
.
.
out sreg, sreg_bak
reti

oder auf dem stack
push r16
in r16, sreg
push r16

Die 1.Variante ist schneller, blockiert aber ein Register.

Dann sollte man eigentlich nicht ohne triftigen Grund von der ISR aus
weitere Unterprogramme aufrufen. Grund: Interupts sollte man kurz
halten (andere Ints sind während dieser Zeit blockiert), ausserdem
steigt die stackbelastung, man weiss ja nicht, wann der Timer
zuschlägt, das Programm kann gerade schon tief im stack stecken
(mehrere calls/rekursion), dann noch die Rückkehradresse und die
Sicherungen in der ISR. Ein stack-Überlauf bringt ganz komische
Effekte, an denen man sich einen Wolf sucht - läuft
stunden/tage/wochenlang, aber dann passiert es immer wieder mal. Ist in
deinem Programm beides kein Problem, aber man muss es sich ja nicht erst
angewöhnen.

Der bessere Weg: ein Bit setzen, welches anzeigt, dass der
Timerinterupt da war und dieses im Hauptprogramm abfragen und ggf. eine
Aktion auslösen und dieses wieder löschen.

Thema Genauigkeit: mit 4MHz und Vorteiler 1024 hast du schon einen
systematischen Fehler drin  (den man zwar ausgleichen könnte durch
zyklische Änderungen des reload-Wertes, aber das muss ja nicht sein).
Dein Timer wird mit 256µs getaktet, *122 reload-Wert *32 =0,999424s,
klingt genau, macht aber pro Tag fast eine Minute aus.
Besser wäre beispielsweise ein Vorteiler 64, reload -250,
Softwarezähler 250. Macht dann 16µs Takt *250 *250= 1s.
Quarzabweichungen wirst du trotzdem noch haben, aber dazu kannst du
später noch mal fragen.

von crazy horse (Gast)


Lesenswert?

noch was vergessen: einfacher wird der Teilerkram mit dem Timer1
(16bit), dann am besten den OCR-Int nutzen.

von Thomas Klapper (Gast)


Lesenswert?

Hallo Crazy Horse,
erst einmal vielen Dank für die Tipps.
Ja, das ist wirklich mein erstes Assemblerpogramm.
Ich habe mit dem AVR Ende letzten Jahres angefangen und die
Rheinturmuhr war sozusagen mein erstes Etappenziel. Bis dahin habe ich
nur kleine Codeschnippsel ausprobiert und mit ein paar Bauteilen herum
gespielt, I2C, LCD, Schrittmotoren. Nur um wieder einen kleinen
Einstieg in die Elektronik zu bekommen. Ich habe fast 10 Jahre lang
Industriesteuerungen   programmiert (SPS) nun hat sich mein berufliches
Aufgabengebiet geändert und ich komme auch Entzug, ich muss halt was zum
austüfteln haben. Daher mein Interesse für die AVR.
Soviel zu mir.

Nun aber zum Programm:
Das mit dem Timer 1 habe ich gestern auch herausgefunden, einfach bis
40000 zählen lassen, sind dann 10ms. Ich werde das bei gelegenheit
einpflegen.
Die Interrupt bearbeitung werde ich versuchen umzumodeln, wenn ich Zeit
finde.
Auch die SREG Sicherung wird noch eingebunden.

Ich denke wir sollten in Kontakt bleiben.

Thomas

von Peter D. (peda)


Lesenswert?

Bezüglich exakter Zeitbasis und DCF77 gibts hier schon einige
Beispiele:

http://www.mikrocontroller.net/forum/read-4-57760.html#new

http://www.mikrocontroller.net/forum/read-4-57760.html#new


Peter

von Thomas Klapper (Gast)


Angehängte Dateien:

Lesenswert?

So,
nun mit angepasster Interruptbearbeitung und Timer1 Taktung.
Mal schauen, wie genau sie nun läuft.

Danke  "crazy horse"

von crazy horse (Gast)


Lesenswert?

noch ein paar kleine Verbesserungen/Ideen.
1. Da du nur den Sekundentakt brauchst, könntest du den direkt mit
demTimer1 erzeugen (Vorteiler 64 =Takt 16µs, OCR 62500), der
Software-Zähler könnte entfallen. Da das INT-Programm dann eigentlich
gar nichts mehr macht, könntest du sogar noch weiter gehen und dieses
entfallen lassen. Dein Sekunden-bit ist dann TIFR.OCF1A. Ist es
gesetzt, ist eine Sekunde um, per Software löschen durch Schreiben
einer 1.
2. die eigentlich Uhr: das geht zwar so, wird auch oft so gemacht. Ich
persönlich bevorzuge aber einen reinen Sekundenzähler. Dekodiert wird
erst bei der Ausgabe, intern rechnest du nur mit Sekunden.
3. deine vielen Vergleiche und und davon abhängiges Laden mit
Konstanten: oft geht sowas einfacher, schneller, kürzer und
übersichtlicher mit Tabellen im Flash und dem LPM-Befehl.

Alles nichts Ernstes , aber falls du Lust hast, kannst du das ja mal
probieren. Das ideale Programm ist kurz, schnell und übersichtlich. Z.T
widerspricht sich das zwar, aber verschleudern muss man Ressourcen ja
nicht. Du wirst in deinem weiteren Programmierleben an Grenzen stossen
(Laufzeit, Programmspeichergrösse, RAM-Grösse). Insofern macht sich
eine von Anfang an konsequente Arbeitsweise irgendwann bezahlt.

Viel Erfolg weiterhin.

von Peter Dannegger (Gast)


Lesenswert?

@crazy horse

"Ich persönlich bevorzuge aber einen reinen Sekundenzähler. Dekodiert
wird erst bei der Ausgabe"


Ich denke mal, daß sowas für einen Anfänger etwas zu komplex ist. Auch
sollte man dann besser in C programmieren. Hier ist ja schonmal eine
entsprechende Routine:

http://www.mikrocontroller.net/forum/read-4-140631.html#new


Peter

von crazy horse (Gast)


Lesenswert?

zu komplex? Weiss nicht, er hats doch bis jetzt ziemlich gut gemacht.
32bit-Divisionsroutinen gibts auch fertig. Er braucht ja auch keine
Kalenderfunktion, sondern nur 24h.

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.