www.mikrocontroller.net

Forum: Compiler & IDEs LCD Uhr mit 11,0592 MHz, genauigkeit?


Autor: Simon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich haette gerne eine LCD Uhr die einigermaßen genau läuft.
Hab mir die zwei Tutorial's durchgelesen (AVR ASM, GCC).
Und mir daraus was gebastelt.

0.01 sekunden * 11059200 MHz = 110592.
daher ->  OCR1A = 110591;

und beim Interrupt zaehle ich auf 100 hoch.
Denoch funktioniert die Uhr ungenau, wo ist da mein Problem?

TCCR1B = (1<<CS10 | 1<<WGM12);
OCR1A = 110591;
TIMSK |=(1<<OCIE1A);
TIFR = 1<<TOV1;

DDRB = 0xFF;
PORTB = 0xFF;
sei();
        lcd_init();
  lcd_clear();
  set_cursor(0,1);
  lcd_string("Uhrzeit");

while(1)
    {
    }

    return 0;
}



void uhrzeit(void)
{
  lcd_clear;
  set_cursor(0,2);
        lcd_string(itoa(stunden, str, 10));
  set_cursor(2,2);
  lcd_string(":");
  set_cursor(3,2);
  lcd_string(itoa(minuten, str, 10));
  //lcd_string(":");
  set_cursor(7,2);
  //lcd_string(dtostrf(sekunden,1,2,str));
  lcd_string(itoa(sekunden, str, 10));
}


ISR(TIMER1_COMPA_vect)
//ISR (TIMER1_OVF_vect)
{
  tmp1++;
  if (tmp1 == 100) {
  sekunden++;

  if (sekunden > 59 ) {
    sekunden = 0;
    minuten++;
    uhrzeit();
  }

  if (minuten > 59 ) {
    sekunden = 0;
    stunden++;
    minuten = 0;

  }

  if (stunden > 23 ) {
    sekunden = 0;
    stunden = 0;
    minuten = 0;
  }
}

}

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>  OCR1A = 110591;
Überlege bitte mal, wie groß OCR1A ist, und wie groß der höchste Wert 
sein wird, der da reinpasst!

Autor: Klaus R. (klaus2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...und denk dran: du kommst trotz alledem nicht drumherum, die uhr zu 
eichen! das quarz ist nicht genau, nur (halbwegs) stabil!

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus R. wrote:
> ...und denk dran: du kommst trotz alledem nicht drumherum, die uhr zu
> eichen! das quarz ist nicht genau, nur (halbwegs) stabil!
Eichen darf nur eine Eichbehörde anhand eines entsprechenden Normals. 
Der Anwender an sich kann höchstens Kalibrieren.

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

11059200 / 1024 (Vorteiler) = 10800
10800 / 100 (für 10ms IRQ) = 108 -> 107 für OCR-Wert bei CTC.
Reicht sogar ein 8Bit-Timer.

Gruß aus Berlin
Michael

Autor: Simon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab ein Atmega8, da gibt es bei dem Timer0 kein OCR, oder liege ich 
da falsch?.

mmh wieder overflow nehmen?

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

stimmt, Timer 0 kann damit auch keinen CTC-Mode. evtl. Timer 2 nehmen?

overflow hat den Nachteil, daß Du selbst nachladen mußt, bei Vorteiler 
1024 ist das aber keine Problem. Der Vorteiler läuft ja weiter, solange 
also innerhalb der 1024 Takte nach auftreten des Overflow-IRQ der 
Counterwert wieder gesetzt wird, geht nichts falsch.

Gruß aus Berlin
Michael

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
vor allem wurde das wohl nie ausprobiert.

tmpl wird hochgezählt, bei 100 wird die ausgabe aufgerufen.
aber tmpl wird nie auf 0 zurückgesetzt.
wenn die ausgabe aufgerufen wird kann minuten schon auf 60 stehen, die 
sekunden sind immer 0. aber die sollen ja ausgegeben werden.

rufe die uhrzeit() routine am ende von if(tmpl==100) auf und setze tmpl 
wieder zurück.

Autor: Simon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank fuer eure Hilfe!

Ich hab jetzt mal

TCCR2 = (1<<CS02 | 1<<CS00);
OCR2 = 107;
TIMSK |=(1<<OCIE2);



ISR(TIMER2_COMPA_vect)
{}


Hab ich irgendwas vergessen? da zuckt sich garnichts mehr?

Autor: Simon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich hab den Fehler gefunden

ISR(TIMER2_COMP_vect) muss das heiszen.

Aber der Zaehlt die Sekunden viel zu schnell

TCCR2 = (1<<CS02 | 1<<CS00); // vorteiler 1024
OCR2 = 107;
TIMSK |= (1 << OCIE2);
TIFR = 1<<OCF2;


ISR(TIMER2_COMP_vect)
{
  tmp1++;
  if (tmp1 == 100) {

  sekunden++;

  if (sekunden > 59 ) {
    sekunden = 0;
    minuten++;
  }

  if (minuten > 59 ) {
    sekunden = 0;
    stunden++;
    minuten = 0;

  }

  if (stunden > 23 ) {
    sekunden = 0;
    stunden = 0;
    minuten = 0;
  }
  tmp1 = 0;
  uhrzeit();
  }
}

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

> Aber der Zaehlt die Sekunden viel zu schnell
>
> TCCR2 = (1<<CS02 | 1<<CS00); // vorteiler 1024

Mein Datenblatt sagt: CS22, CS21, CS20 auf 1 für 1024...
CS00 und CS02 gehören zu Timer 0, ich habe nicht nachgeschaut, wo da die 
Bits liegen...

Weiter sagt mein Datenblatt noch: WGM21 auf 1 in TCCR2 für CTC-Mode.

> OCR2 = 107;
> TIMSK |= (1 << OCIE2);
> TIFR = 1<<OCF2;
...
>   uhrzeit();

Außerdem weiß ich nicht, was uhrzeit() macht, man macht 
Interruptroutinen so kurz wie möglich, falls es die Ausgabe ist: die 
gehört ins Hauptprogramm.

Gruß aus Berlin
Michael

Autor: Simon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tatsache das funzt langsammer :-)

Danke!

Nur wenn ich das raus nehme aus dem ISR.
da brauche ich irgend was anderes was mir in gewissen zeitabstaenden das 
LCD aktualisiert.

ich koennte jetzt:
a) ein weiteren timer verwenden?
-> was passiert wenn der interrupt gleichzeitig kommt mit dem anderen 
der
die Uhrzeit zaehlt.

b) eine variable aufzaehlen und dann aktuallisieren.
oder gibt noch was anderes?

Danke fuer die Hilfe!

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Simon (Gast)

>da brauche ich irgend was anderes was mir in gewissen zeitabstaenden das
>LCD aktualisiert.

Das macht man per Flag im Hauptpogramm.

Siehe Interrupt.

MFG
Falk

Autor: Simon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist ne idee :-)

Ich zaehle ja auch tmp1 hoch bis 100 um 0.01s in sekunden um zu wandeln

kann man da auch im haupt programm abfragen wann tmp1 == 0 ist?

So wuerde ich jede sekunde einmal aktualisieren.

Autor: Simon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ne vergisst es, das geht nicht.
da ja tmp1 ne ganze weile 0 ist bis das naechste Interrupt ausloest.


Funzt richtig gut jetzt, und recht genau gehts auch.
Vielen Dank an alle!

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.