mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik atmega8 uhr


Autor: Walter F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend, bin noch nicht so erfahren mit dem Umgang mit 
Mikrocontrollern,
zerbreche mir schon seit längerem den Kopf wie ich denn eine Uhr 
Software machen könnte, damit ich Datum und Uhrzeit mitzählen lassen 
kann, hab mir schon die Timer im Datenblatt des Atmega8L angeschaut und 
weis nicht wie ich das realisieren könnte, hat mir jemand nen tipp oder 
beispiel code?

gruß Walter

Autor: akw (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du musst den Timer so konfigurieren, dass er jede Sekunde einen Impuls 
erzeugt und zählst bei dem Impuls einfach die Sekundne um eins hoch. 
Nicht schwer!

Autor: Walter F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja nur was muss ich da für einen Vorteiler benutzen damit ich auf eine 
Sekunde komme? mein Atmega8 läuft mit 3,684 Mhz

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine Sekunde wirst du ev. nicht hinkriegen mittels Takt+Prescaler.
Macht aber nichts. Gehst halt dann auf 1/10 oder 1/100 Sekunde oder
überhaupt auf einen völlig anderen Bruchteil einer Sekunde, sagen
wir mal x.

Für deine ersten Schritte ist es am einfachsten den Overflow
Interrupt dafür zu benutzen. Später wirst du lernen wie
man das besser machen kann.
Also: Du hast deinen Timer so aufgesetzt, dass er x mal in der Sekunde
einen Overflow auslöst.
Also brauchst du eine Variable, die mitzählt, wie oft der Overflow
ausgelöst wurde: Bei jedem Overflow zählst du sie um 1 hoch.
Hat diese Variable den Wert x erreicht, ist eine Sekunde vergangen.
Also erhöhst du eine andere Variable, die die Sekunden in deinem
Programm darstellt und setzt den Overflow-Zähler wieder auf 0.
Hat die Sekunden-Variable den Wert 60 erreicht, setzt du die
Sekunden wieder auf 0 und erhöhst dafür die Minuten. Selbiges
in grün: Nach 60 Minuten ist eine Stunde vergangen und nach 24
Stunden ist ein 1 Tag vergangen. Ab da wird es dann marginal
schwieriger, da die Weiterschaltung der Monate in Abhängigkeit
vom Tag vom Monat selbst abhängt. Hat also der Tagzähler 30 erreicht
und ist gerade zb. April, so ist der nächste Tag der 1. und der Monat
geht um 1 hoch (=Mai). usw.
Konzentrier dich zunächst auf die Stunden:Minuten:Sekunden
Oder noch einfacher: Vergiss Stunden und Minuten fürs erste und zähl
einfach nur die Sekunden hoch. In der Phase kannst du dich voll auf
den Timer konzentrieren ohne dich mit Gedanken über Stunden und Tage
und Monate zu verzetteln.


Autor: akw (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also dein 16 Bit Timer zählt bis 65536, dann läuft er über.
Bei 3,684 MHz und nem Vorteiler von 64 zält der Timer in einer Sekunde 
auf 57562,5. Du musst nun deinen Timer auf 7973,5 vorladen, dann läuft 
der Timer genau einmal pro Sekunde über.

Alle Angaben sind ohne Gewähr ;) Rechne lieber nochmal nach, der 
Rechenweg dürfte ja soweit klar sein oder?

Autor: Walter F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hm kannst den Rechenweg kurz erklären?

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> ja nur was muss ich da für einen Vorteiler benutzen damit ich auf eine
> Sekunde komme? mein Atmega8 läuft mit 3,684 Mhz

Da wirst du halt ein bischen Rechnen und Probieren müssen :-)

Ein 8-Bit Zähler generiert nach 256 Zählvorgängen einen Overflow
Interrupt. Wenn dein Quarz also 3684000 Schwingungen in der Sekunde
macht und du einen Vorteiler von 1 benutzen würdest, dann würde
der 8-Bit Zähler in einer Sekunde 3684000 / 256 Überläufe produzieren.
Das sind 14390.625 Überläufe pro Sekunde.

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timer1 Prescaler /8, OCR1A auf 4605, dann haste einen 
Output-Compare-Interrupt (im CTC-Mode) alle 100dstel Sekunden. Variablen 
zählen im INT. Besser wäre es, einen 'geraden' Quarz zu wählen (8 oder 
16 MHz), da teilt sich's leichter!

Autor: Walter F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok danke für die infos, werd ich gleich ma probieren ;)

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> hm kannst den Rechenweg kurz erklären?

Ist doch simpel:

Der Vorteiler sagt dir wieviele Takte vergehen müssen, damit
der Zähler um 1 hochzählt. Klar?

Also: Wenn dein Quarz 3864000 Takte in der Sekunde generiert,
wie weit zählt der dann in 1 Sekunde mit einem Vorteiler von 64?

Offensichtlich bis 3864000 / 64  -> 57562.5

Ziel ist es wieder sich an den Overflow zu klemmen. Wann tritt
der ein? Na wenn der Zähler überläuft. Und da es sich um einen 16
Bit Zähler handelt, kommt der Überlauf bei 65536.
Also: Bei welchem Wert musst du den Timer loslaufen lassen, damit
nach genau 57562.5 Zählvorgängen der Wert von 65536 erreicht wird?
Der Startwert muss offensichtlich 65536 - 57562.5, also 7973.5
sein. Denn wenn der Timer dann 57562.5 mal getickt hat, ist der
gewünschte Wert von 65536 erreicht und er generiert einen Overflow.
Was für dich heist: 1 Sekunde ist vergangen.

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, meinte OCR1A auf 4604 (immer eins weniger als der Teilerfaktor, 
da von 0 aus gezählt wird)!

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@karl heinz:
ist ja theoretisch richtig, aber wie lässt du den Timer einen halben 
Takt zählen? Der Teilerfaktor muss immer ohne Nachkommaanteil passen!

Autor: GISMO (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alles ist zwar ok was hier gesagt wird aber wenn du Dattenblatt genau 
studiert hättest dann wärest du wahrscheinlich REAL TIME CKLOCK gesehn.
The clock source for Timer/Counter2 is named clkT2S. clkT2S is by 
default connected to
the main system I/O clock clkI/O. By setting the AS2 bit in ASSR, 
Timer/Counter2 is
asynchronously clocked from the TOSC1 pin. This enables use of 
Timer/Counter2 as a
Real Time Counter (RTC). When AS2 is set, pins TOSC1 and TOSC2 are 
disconnected
from Port B. A crystal can then be connected between the TOSC1 and TOSC2 
pins to
serve as an independent clock source for Timer/Counter2. The Oscillator 
is optimized
for use with a 32.768 kHz crystal. Applying an external clock source to 
TOSC1 is not
recommended.
For Timer/Counter2, the possible prescaled selections are: clkT2S/8, 
clkT2S/32, clkT2S/64,
clkT2S/128, clkT2S/256, and clkT2S/1024. Additionally, clkT2S as well as 
0 (stop) may be
selected.

Ausserdem egal wie erfahren du bist du muss das Datenblatt lesen. Es 
giebt keine fertige Lösungen.

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das mit dem externen Uhrenquarz ist wegen ungenauer Quarze mit Vorsicht 
zu geniessen! Der produziert natürlich am Timer 2 jede Sekunde einen 
Überlauf, aber wie gesagt, hatte damit schon erhebliche Ungenauigkeiten 
drin!

Autor: Walter F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ohje klappt noch nicht so wirklich, ist das so richtig:

    int sek = 0;
    TIMSK |= (1 << 0);  // Timer/Counter0 Interrupt Aktivieren
    TCCR0 |= (1 << 2);; // Prescaler auf 256 Einstellen
    if (bit_is_set(TIFR,0) ) { // Prüfen ob Ein Überlauf Vorliegt
    sek++;
    PrintInt(sek);
    uart_puts("\r\n");
    }

Autor: Walter F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ah doch funktioniert, ups hatte das ganze in einer schleife somit wurde 
bei jedem durchlauf der timer neu initialisiert und es kam immer 1 raus 
;)

Autor: Walter F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so ich bekomme nun schon einen sekunden takt hin, jedoch habe ich 
vermutlich einen Fehler im Programm, denn die erste Sec zahl die er mir 
ausgibt fängt immer bei rund 600 an, normal müsste doch bei 0 anfangen?


    // Timer Initialisieren
    if (bit_is_clear(TIMSK,0)) {  // Timer/Counter0 Interrupt

    TIMSK |= (1 << 0);
    }

    if (bit_is_clear(TCCR0,2)) {  // Prescaler auf 8 Einstellen
    TCCR0 |= (1 << 2);
    }

    int count, sec;
    if (bit_is_set(TIFR,0) ) { // Prüfen ob Ein Überlauf Vorliegt
    count++;
    }

    if (count == 14400) {
    sec++;
    PrintInt(sec);
    uart_puts("\r\n");
    }
    // Uhr Ende

Autor: Walter F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
aem prescaler ist nicht auf 8 sondern auf 256 falscher kommentar ;)

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: GISMO (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man  Sonic was redes du denn da, Quarz so viel fehler wo hast du denn 
Quarz gekauft ich glaube du hast in selber gebastelt. Wenn du den 
externen Quarz als ungenau bezwéichnst was sagst du dann zu dem internen 
Quarz vergleich mal die Datenblätter befor du hier ein unsinn 
verbereitst. Mensch.

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Peter schon "Werbung" macht, dann mach ich das auch mal:

Beitrag "Ziemlich simple Uhr"

Rahul

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

Bewertung
0 lesenswert
nicht lesenswert
Ich denke mal hier geht es in erster Linie nicht darum eine
exakte Uhr zu bauen. Hier geht es in erster Linie darum
programmieren zu lernen bzw. den Umgang mit dem Timer zu
üben.

> denn die erste Sec zahl die er mir
> ausgibt fängt immer bei rund 600 an

Verfolg mal nach, was den der Startwert der Variable Sec ist.
Es bringt nichts Programmteile zu posten, die sich,
ausser der Erhöhung von Sec, nicht mit Sec befassen.

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

Bewertung
0 lesenswert
nicht lesenswert
> @karl heinz:
> ist ja theoretisch richtig, aber wie lässt du den Timer einen halben
> Takt zählen? Der Teilerfaktor muss immer ohne Nachkommaanteil passen!

Indem ich ihn abwechseln einmal um 1 zu hoch und das nächste mal
um 1 zu tief zählen lasse. Gemittelt hat er dann einen halben
Takt gezählt :-)

Im übrigen ist der ganze Weg auch theoretisch nicht richtig, da
da einige Takte unter den Tisch fallen. Kein Mensch würde das
bei einer richtigen Uhr mit einem Overflow lösen sondern würde
auf den CTC ausweichen. Aber darum gehts im Moment noch nicht
(zumindest mir nicht). Walter muss jetzt erst mal in die Gänge
kommen.

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

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger wrote:
> Ich denke mal hier geht es in erster Linie nicht darum eine
> exakte Uhr zu bauen. Hier geht es in erster Linie darum
> programmieren zu lernen bzw. den Umgang mit dem Timer zu
> üben.
>
>> denn die erste Sec zahl die er mir
>> ausgibt fängt immer bei rund 600 an
>
> Verfolg mal nach, was den der Startwert der Variable Sec ist.
> Es bringt nichts Programmteile zu posten, die sich,
> ausser der Erhöhung von Sec, nicht mit Sec befassen.


Sorry. Hab ich übersehen. Da haben wirs ja:

    if (bit_is_clear(TCCR0,2)) {  // Prescaler auf 8 Einstellen
    TCCR0 |= (1 << 2);
    }

    int count, sec;

Wenn eine Variable zur Welt kommt, hat sie irgendeinen Wert,
der muss noch nicht mal gültig sein (zb. im Falle von double).
Dein sec enthält also irgendwas zufälliges. Wenn du willst, dass
das mit 0 loslegst, musst du sec schon initialisieren:

  int cout, sec = 0;



Autor: Sebastian Heyn (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Wenn alle ihr uhrenprogramm hier reinstellen, dann werd ichs auch mal 
machen! G
Ist in bascom, rechnet wochentage, schaltjahre etc, berechnung erfolgt 
im hauptprogramm, wen ein status-bit gesetzt wurde. bis jetzt noch nicht 
in reeller hardware getestet, allerdings.

Autor: Sebastian Heyn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
zum berechnen der timer benutze ich das programm RNAVR (einfach mal 
googlen).da gibst du einfach taktfrequenz und interrupt frequenz an, und 
du bekommst die werte angezeigt. genau das richtige für den faulen, 
grins

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ GISMO:
diese Erkenntnisse habe ich aus der Praxis! Ein mehrfach geteilter 
(MHz-Bereich)-Quarz ist entsprechend genauer und temperaturstabiler, 
wegen der Masse des Quarzes als ein kHz-Quarz, der nicht geteilt wird. 
Probier doch einfach mal ein paar aus, nicht nur drauf verlassen was im 
Datenblatt steht!

Autor: GISMO (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was soll ich Probieren, nichts ist Perfekt. Ausserdem ich benutze ein 
Real Time Counter seit 2000, wenn du ganz genauers nehmen willst dann 
nehm doch eine Atomuhr, geht auch ebenfalls falsch. Vielleicht solte man 
auch ein Atomuhr Temperatur kompensation verpassen.

Autor: Sebastian Heyn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ist denn der aufwand ewig mit quarzen rumzuspielen gerechtfertigt?
also im zeitalter von dcf kann man doch einmal am tag, oder pro woche 
einfach abgleichen, oder?

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wenn du den externen Quarz als ungenau bezwéichnst

Externe Quarze sind natürlich genauso ungenau. Auch ein Uhrenquarz
ist nicht absolut genau. Deswegen verbaut man unter anderem ja
auch Kondensatoren um den Quarz in seiner Frequenz noch ziehen
zu können. Jeder Uhrmacher gleicht den Quarz einer Uhr auf die
Sollfrequenz ab.

> was sagst du dann zu dem internen Quarz

Welcher interner Quarz?
In einem AVR ist kein 'interner Quarz' eingebaut. Das sind ganz
normale R-C Schwingkreise.


Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab's, wie Sebastian angesprochen hat, mit DCF77 gemacht, die RTC 
übernimmt bei Ausfall oder fehlerhaftem Signal.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sebastian Heyn wrote:
> zum berechnen der timer benutze ich das programm RNAVR (einfach mal
> googlen).da gibst du einfach taktfrequenz und interrupt frequenz an, und
> du bekommst die werte angezeigt. genau das richtige für den faulen,
> grins


Dann mußt Du aber noch die Werte ins Programm eintippen, wäre mir viel 
zuviel Arbeit.

Ich bin noch fauler, ich trag einfach die Formel ein und laß das Rechnen 
den Präprozessor machen.

Bei einem anderen Quarz, schreib ich dann nur die neue Quarzfrequenz 
hin, laß es neu compilieren und gut is.


Peter

Autor: Walter F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so jetzt zählt er mir die Überläufe, jedoch viel zu langsam, nach ein 
paar minuten habe ich 1000 überläufe das kann doch nicht sein, was mach 
ich denn blos Falsch?

        // Timer Initialisieren

        if (bit_is_clear(TIMSK,0)) {  // Timer/Counter0 Interrupt

        TIMSK |= (1 << 0);
        }

        if (bit_is_clear(TCCR0,2)) {  // Prescaler auf 8 Einstellen
        TCCR0 |= (1 << 2);
        }
        if (bit_is_set(TIFR,0) ) { // Prüfen ob Ein Überlauf Vorliegt
        sek++;
        }

    uart_puts("Count:");
        PrintInt(count);
        uart_puts("\r\n");
    uart_puts("Sec:");
        PrintInt(sec);
        uart_puts("\r\n");
        // Uhr Ende

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Abfragen ob das Bit gelöscht ist um es dann zu setzen
kannst du dir sparen. Es ist wesentlich einfacher das
Bit immer zu setzen, egal ob es schon gesetzt ist oder nicht.

Nun, du aktivierst den Timer-Interrupt hast aber keinen
Interrupt Handler. Den Timer Interrupt zu benutzen ist eine
gute Idee. Was hingegen schlecht ist, ist die Abfrage
ob das Overflow Bit in TIFR gesetzt wird. Ein Interrupt
Handler würde ganz einfach aufgerufen werden und
gut ists.

Das könnte so aussehen:
#include <avr/io.h>
#include <avr/interrupt.h>

volatile int Sek;

ISR( TIMER0_OVF_vect )
{
  Sek++;
}

int main( void )
{
  Sek = 0;

  TIMSK = ( 1 << TOIE0 );  // Timer Overflow Interrupts zulassen
  TCCR0 = ( 1 << CS01 );   // Vorteiler von 8

  sei();       // und alle Interrupts scharf stellen, ab jetzt kommen sie

  while( 1 ) {
    uart_puts( "Sec:" );
    PrintInt( Sek );
    uart_puts( "\r\n" );
  }
}


Das ergibt jetzt keine Sekunde, aber es soll ja für dich auch
noch was übrig bleiben.

Autor: Walter F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ah ok danke ;)
jetzt geht es bekomm nun endlich die richtige sekunde hochgezählt,
vielen dank nochmal für die geduld ;)

Autor: fubu1000 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ähhm
i würde keine timer nehmen. denn wenn du eine sekunde mit dem timer 
auszählst und dann das auf nen lcd oder sonstigem anzeigen willst, wirst 
du jede sekunde verfälschen um den faktor der lcd  ansteuerung.
schreib deinen code für die uhr und dann leg warte schleifen ein damit 
du eine sekunde kriegst.
viel genauer und super leicht zu berechnen.
gruss

Autor: fubu1000 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
aso solltest es natürlich in asm schreiben ansonsten iss alles zufall 
mit dem timings.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
fubu1000 wrote:
> i würde keine timer nehmen. denn wenn du eine sekunde mit dem timer
> auszählst und dann das auf nen lcd oder sonstigem anzeigen willst, wirst
> du jede sekunde verfälschen um den faktor der lcd  ansteuerung.


Nö !

Das ist ja gerade der Witz an nem Timer, daß er in Hardware läuft.

Irgendwelche Softwareausführunszeiten kümmern ihn in keinster Weise.

Ein Timer ist immer auf den Zyklus genau.


> schreib deinen code für die uhr und dann leg warte schleifen ein damit
> du eine sekunde kriegst.

Gratulation !

Das ist die absolut richtige Methode, um total ungenau zu werden.
Warteschleifen sind Software und damit völlig Programm- und 
Compilierungsabhängig.


Warum willst Du nen Anfänger verarschen ?
Was hat er Dir getan ?


Peter

Autor: Sven Scholz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich wollte mir auch eine Software Uhr basteln.
Welchen Takt sollte ich denn jetzt dafür verwenden?
Den internen oder ist doch besser meinen 4MHZ Oszillator über XTAL1?
Es gibt ja auch noch die Möglichkeit einen Oszillator zwischen XTAL1 und 
XTAL2 zu schalten?
Also, welches ist auf Dauer gesehen die Beste Lösung?

Das Ganze möchte ich unter BASCOM zum Laufen kriegen. Ich verwende 
hierfür doch einen Timerinterrupt um mir ein Sekunden Signal zu schaffen 
oder?
Es gibt dort ja auch die vorgefertigte WAIT 1-Anweisung. Ist die Genau?

DANKE schon einmal für die ANTWORTEN.

Autor: Marc Meise (bytewood) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Sven

Schau mal auf die MCS Seite unter Application-Notes.
Dort ist eine AN für ne AVR-Uhr.

Autor: Sebastian Heyn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
die wait 1 anweisung ist total nutzlos, weil dein programm, also die 
zeit berechnen ja auch x zeit benötigt. deshalb wirst du pro sekunde 
immer ungenauer. ich hatte oben mal ein bascom beispiel gepostet für 
eine uhr. (rtc.bas)

Autor: Aufreger deluxe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Also ich wollte mir auch eine Software Uhr basteln.
> Welchen Takt sollte ich denn jetzt dafür verwenden?

Der interne ist sehr ungenau und diversen Schwankungen unterworfen 
(Versorgungsspannung, Temperatur). Nimm einen normalen Quarz (sonic 
meint, spezielle 32kHz Uhrenquarze sind zu ungenau) zw. XTAL1 und XTAL2. 
Meine Uhr lief anfangs mit 7,3728MHz und auf 24 Stunden hatte ich eine 
Sekunde Abweichung von der normalen Zeit.

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi nochmal, wenn du Wert auf eine genaue Uhr legst, ist es das Beste 
einen 'geraden' Quarz zu verwenden, z.B. 4, 8 oder 16 MHz. Dieser lässt 
sich per Output-Compare-Mode (mit CTC-Mode) genau auf 1 Sekunde 
runterteilen. Nun hast du einen Interrupt, der genau jede Sekunde 
ausgelöst wird, unabhängig vom restlichen Programm. Immer dran denken: 
beim µC wird ab 0 gezählt, also ist der Wert für z.B. OCRA1 1999 wenn er 
bei Zählerstand 2000 auslösen soll!

Wenn die Baudrate genau sein soll ist natürlich z.B. ein 7,3728MHz - 
Quarz besser, die Uhr dafür schwieriger zu realisieren.

Autor: Aufreger deluxe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wenn die Baudrate genau sein soll ist natürlich z.B. ein 7,3728MHz -
> Quarz besser, die Uhr dafür schwieriger zu realisieren.

Warum? Prescaler des Timers z. B. auf 8 gesetzt, 
Timer-Overflow-Interrupt aktivieren und in der ISR ein (unisgned int) 
bei jedem Interrupt hochzählen. Wenn dieser Wert 3600 ist, ist genau 
eine Sekunde rum. Oder vertue ich ich da gerade?

Autor: Aufreger deluxe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
D. h. ja, so könnte man die Quarzungenauigkeiten nicht raus rechnen; 
alles klar!

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du liegst mit den 3600 richtig, das wären 3600Hz, also 277.77(irgendwas) 
µs. Zeit ist 1/Frequenz, unbedingt Berücksichtigen!
Du kannst sehr wohl auf 3600 zählen, Ist aber wie schon gesagt, 
Programmäßig schwieriger zu realisieren. Bei einem geraden Quarz kannst 
du die Uhr bequem in der Interrupt-Routine unterbringen und hast 1s Zeit 
für den Rest des Programmes, wobei bei deiner Version der 'normale' 
Programmablauf alle 277...µs unterbrochen wird.

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Quarzungenauigkeiten kann man nichr 'rausrechnen, nur messen und 
entsprechen kompensieren. Jedenfalls gilt: je höher die Quarzfrequenz 
und je größer der Teiler, desto kleiner der Fehler.

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

Bewertung
0 lesenswert
nicht lesenswert
> ähhm
> i würde keine timer nehmen. denn wenn du eine sekunde mit dem timer
> auszählst und dann das auf nen lcd oder sonstigem anzeigen willst, wirst
> du jede sekunde verfälschen um den faktor der lcd  ansteuerung.

Weist du.
Wenn du dich darüber mokiert hättest, dass das Ganze am Overflow
Interrupt aufsetzt, anstatt am CTC, hätte ich das ja noch verstanden.
Ich hab ihm den Overflow eingeredet, damit er mal anfängt sich mit
Timern zu beschäftigen. Der Overflow Interrupt ist besser als nichts,
aber der CTC ist das Mittel mit dem man das machen würde.

> schreib deinen code für die uhr und dann leg warte schleifen ein damit
> du eine sekunde kriegst.
> viel genauer und super leicht zu berechnen.

Das allerdings geht genau in die falsche Richtung. Mit Warteschleifen
kriegst du keine halbwegs genaue, langzeitstabile Uhr hin. Selbst
die Uhr mit Overflow-Interrupt ist deinen Warteschleifen haushoch
überlegen.

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.