So, da bin ich wieder mit noch dummeren Fragen!!!
Hab jetz versucht einen Timer einzubauen.
Und jetzt kommen die Fragen:
Sitz alles an der richtigen Stelle?
wo setz ich das sei(); richtig?
an der Stelle, an der ich den Prescaler setz muss ich da bei einem
Prescaler von 1024 auch die CS21 und CS20 "definieren oder setzten oder
wie man das nennt"?
und wenn ja wie?
Hab ich den Prescler und Preloader für 10ms im 16bit-timer?
Bitte jeden, der irgendwas dazu weiß zu antworten?
?
Welche der CS-Bits gesetzt werden müssen, um einen Prescaler von 1024
einzustellen, steht in einer Tabelle im Datenblatt. Abgesehen davon ist
TCCR1 ein 8-Bit-Register, und da passt die Zahl 1024 gar nicht rein,
erst recht nicht, wenn Du sie auch noch nach links schiebst! Schau Dir
mal den Artikel zur Bitmanipulation an.
Abgesehen steht der ganze Block mit den Initialisierungen im
Niemandsland, was nicht zulässig ist! Zuweisungen an Variablen (und dazu
zählen auch die I/O-Register) dürfen ausschließlich innerhalb von
Funktionen stehen. Einzige Ausnahme sind Initialisierungen von globalen
Variablen, die in der selben Zeile deklariert werden.
Das hier:
1
TCNT1=65379.75
ist, abgesehen von dem fehlenden Semikolon am Ende, Unsinn. TCNT1 kann
nur ganzzahlige Werte annehmen!
ist Quatsch.
Bitte lies Dir das AVR-GCC-Tutorialgründlich durch. Da sind noch
einige Dinge, die Du offensichtlich noch nicht wirklich verstanden hast.
Allerdings auch ein paar C-Grundlagen fehlen, also sollte auch ein
vernünftiges C-Buch her.
Muss ganz erlich gestehen ich blicks echt hinten und vorne nich, da habt
ihr schon recht!
Wenn ich mehr Zeit hätte, würd ich mich auch vorer intensiver damit
beschäftigen.
muss es "TCNT1 = (1<<CS22)&(1<<CS21)&(1<<CS20);" heißen?
Im Datenblatt steht für 1024 müssen alle drei "1" sein.
Ich les mal noch ein bisschen nach, is wohl besser.
Daniela wrote:
> da habt ihr schon recht!
^^^
"ihr"? Wer ist der andere?
> muss es "TCNT1 = (1<<CS22)&(1<<CS21)&(1<<CS20);" heißen?
Nicht "&"! Es muss "|" sein! Noch mal Bitmanipulation lesen...
> Im Datenblatt steht für 1024 müssen alle drei "1" sein.
Genau. Also hast Du zumindest die Tabelle schon mal gefunden. Weiter so!
Generell sind die AVR-Datenblätter eigentlich ziemlich übersichtlich,
und meist gibt es ebenso übersichtliche Tabellen, in denen die
Steuerbits stehen. Das meiste von den wirklich wichtigen Dingen kann man
jeweils aus dem Abschnitt "Register Description" entnehmen, indem man
einfach die dort beschriebenen Steuerregister der Reihe nach durchgeht
und aussortiert, welche Bits man überhaupt nicht braucht und welche
entsprechend gesetzt werden müssen.
> Ich les mal noch ein bisschen nach, is wohl besser.
Gut.
Nein, es sitzt leider gar nichts an der richtigen Stelle.
Noch mal zurück zu der ersten geänderten Version und dann die Änderungen
einbauen für den Timer1 und zwar aus dem Code vom Countdownzähler
(http://www.gjlay.de/pub/c-code/countdown.html). Dabei die
Moderinisierung von SIGNAL zu ISR aus der avr-libc berücksichtigen.
Die Idee von Georg ist:
Man gibt vor, wieviele IRQs pro Sekunde kommen sollen. Z.B. willkürlich
5000, um eine gute Zeitauflösung zu haben. So stellt man auch seinen
Timer1 ein. Die Einstellung ist von der Taktrate (F_CPU) abhängig. Mit
dem 16-Bit Timer und 5000 gewünschten IRQs/s kann man alle bei AVR
möglichen MHz Taktraten abdecken. Bei anderen Werten muss man
nachrechnen, ob man bei 16-Bit (OCR1A ) oder 8-Bit (interrupt_num_10ms)
Ganzzahlüberläufe bekommt.
Dann weiss man auch wieviele IRQs in 10ms kommen (1/100-stel vom 1s
Wert, hier 50). Man zählt die IRQs mit und wenn die Anzahl dem Wert bei
10ms entspricht, ruft man die Arbeitsfunktion auf, die alle 10ms laufen
muss.
Hätte man mehrere Arbeitsfunktionen, sollte man die etwas verteilen. Es
werden die nicht alle bei exakt bei dem "Uhrstand" 10ms, 20ms, 30ms
auferufen, sondern versetzt zueinander. Also z.B.
Arbeitsroutine 1 bei 10ms, 20ms, 30ms...
Arbeitsroutine 2 bei 10ms+1IRQ, 20ms+1IRQ, 30ms+1IRQ...
Arbeitsroutine 3 bei 10ms+2IRQ, 20ms+2IRQ, 30ms+2IRQ...
...
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
#include"dcf.h"
4
5
#ifndef F_CPU
6
#define F_CPU 1000000
7
#endif
8
9
#define IRQS_PER_SECOND 5000
10
#define IRQS_PER_10MS (IRQS_PER_SECOND / 100)
11
12
// Merkt alle 10 Millisekunden den Portzustand des DCF-Ports
Hab die Bitmanipulation glesen, und hab in der zwischenzeit auch
rausgefunden, dass es | und nicht & heißen müsste. Nächstes mal les ich
erst und dann frag ich.
Auf die wirre Zahl des Preloaders bin ich durch ne Rechnung gekommen die
ich online gefunden hab!
Schade, ich war so stolz auf mich, weil ich dachte ich hät´s halbwegs
selbst gelöst.
Und ganz großen dank für das Program und die spitzen Erklärung dazu!
Ich hatte auch zuerst versucht es auf diesem Weg zu machen, aber dann
bin ich auf das andere gestoßen und es hat so einfach ausgesehen. Aber
wie man sieht konnt ich´s trotzdem nicht.
Und nochmal DANKE
Daniela wrote:
> Schade, ich war so stolz auf mich, weil ich dachte ich hät´s halbwegs> selbst gelöst.
Deine Idee (möglichst wenige - ideal ein - IRQ exakt zum richtigen
Zeitpunkt bei 10ms) ist ja nicht verkehrt, nur an der Ausführung hapert
es.
Wenn du beachtest, dass die Timer mit Ganzzahlen arbeiten und wenn du
dich weiter in das Thema einliest (z.B. mit [[AVR - Die genaue Sekunde /
RTC]] und Datenblatt vom AVR), kannst du deinen Weg immer noch
schaffen.