Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - Zum C-Control-I-Forum - Zum C-Control-II-Forum

Re: LCD_WriteText() lässt die Uhr langsamer laufen Kategorie: Programmierung C (von Mike - 13.08.2007 14:31)
Als Antwort auf Re: LCD_WriteText() lässt die Uhr langsamer laufen von Hannes - 14.05.2007 8:09
Ich nutze:
C-Control Pro Mega32, CC-Pro 32 Application Board
Hallo, kann es sein, da� die LCD-Schreibroutine usw. manchmal tatsächlich etwas mehr als 10 ms benötigt,
und irgendwie kurzfristig den 10-ms-Interrupt unterdrĂĽckt?
Dann würde beim nächsten 10-ms-Interrupt
irqcnt=Irq_GetCount(INT_TIM2COMP)
statt 1 eine 2 oder so zurĂĽckgegeben.  Aber in RTC wird cnt1 immer nur um 1 erhöht:
cnt1++;
Dadurch werden die sporadischen 20-ms-SprĂĽnge nicht berĂĽcksichtigt.
Vielleicht sollte man im 1. Ausdruck oben "irqcnt" durch "cnt1" ersetzen und die Zeile "cnt1++;" entfernen.
Dann müsste man nur die cnt1==50 und cnt1==100 evtl. anpassen, falls wir zufällig keine "Punktlandung"
auf 50 oder 100 haben.

GrĂĽĂ?e -- Mike


> Hallo Peter,
>
> es ist definitiv ein Unterschied feststellbar. Bereits nach 5min Laufzeit geht die RTC um 3sec. nach, wenn
> der letzte Befehl   LCD_WriteText(text);   drin ist (kann man ja selber leicht testen). Jetzt ist natĂĽrlich
> der Befehl auch im Demo-Progr. LCD-Uhr vorhanden und die Uhr geht genau, aber der Unterschied
> liegt darin, dass in der letzten Funktion ein längerer String ausgegeben wird, genauso wie in meinem
> Messprogramm, das eine längere Float-Zahl in einen String umwandelt und dieser am LCD jede Sek.
> ausgegeben wird. Ansonsten läuft die RTC mit dem Demo-Progr. LCD-Uhr auf längere Zeit sehr genau,
> so dass ich eine grosse Toleranz des Quarzes ausschliessen kann.
>
> Gruss
>
>
>
>
>
>
>
>
> > > Es ist ein ziemlicher Scheissfehler, wenn man ein Messprogramm laufen lässt und am Ende feststellt,
> > > dass einem 30min abgehen. Den Zeitaufwand um den Fehler zu finden, brauch ich wohl nicht
> > > erwähnen.
> > >
> > > Zum Fehler:
> > > Die Funktion LCD_WriteText() lässt die Echtzeituhr langsamer laufen, ca. 33sec pro Stunde, wenn die
> > > Funkt. jede Sekunde aufgerufen wird.
> > > Was treibt die Funktion mit Timer2, der ja nur für die Systemzeit zuständig ist???
> >
> > Ich hab mir das ganze angesehen, kann aber nicht erkennen, wieso die LCD Ausgabe soviel Zeit verbrauchen
> > soll. Geht die Uhr soviel genauer, wenn die LCD Ausgabe nicht drin ist? Den Timer2 stören die LCD
> > Funktionen nicht, das hab ich geprĂĽft.
> >
> > Man mu� sich ganz klar sein, Quarze gehörige Abweichungen haben können. Die 33sek pro Stunde sind
> > zuviel, aber eine Minute in 12 Sd. ist durchaus normal.
> >
> > Ich bin mit der Konstruktion der Interpreter Interruptroutine selbst nicht ganz glĂĽcklich, es wird zuviel
> > Interpreterzeit damit verschwendet. Ich werde innerhalb der nächsten 7 Tage eine Zusatzfunktion
> > in den Interpreter einbauen, die eine einfache Uhr mit dem 10ms Interrupt direkt in Assembler macht.
> > Man kann dann eine Anfangszeit setzen, und später die aktuelle Uhrzeit abfragen. Die Ungenauigkeit
> > des Quarzes kann dies aber nicht ausbĂĽgeln. In dem Fall empfehle ich eine I2C Echtzeituhr.
> >
> > Gruss Peter
> >
> >
> > >
> > >
> > > Anbei das Demoprogramm LCD-Uhr, die Funkt. LCD_Ausgabe() am Schluss habe ich eingefĂĽgt um
> > > den Fehler zu reproduzieren.
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > > // LCD_Uhr_1: LCD-Uhr  (Anzeigeformat "13:47:24")
> > > // LED1 blinkt mit 1Hz
> > > // erforderliche Library: IntFunc_Lib.cc, LCD_Lib.cc
> > >
> > > // Auf dem Display wird eine LCD-Uhr im Anzeigenformat "13:47:24" dargestellt.
> > > // Zeitbasis 10ms Interrupt mit Zeitkorrektur
> > >
> > > byte cnt1;                                  // globale Variablendeklaration
> > > byte Sekunde, Minute, Stunde;               // globale Variablendeklaration
> > >
> > > //------------------------------------------------------------------------------
> > > // Zeichenausgabe
> > > //
> > > void Write2Digits(byte pos,byte val)
> > > {
> > >     char num[3];
> > >
> > >     LCD_CursorPos(pos);                     // LCD Cursor positionieren
> > >     Str_WriteWord(val,10,num,0,2);          // Zahl mit Basis 10, Offset 0, 2 stellig in String schreiben
> > >     LCD_WriteText(num);                     // String ausgeben
> > > }
> > >
> > > //------------------------------------------------------------------------------
> > > // Ausgabeformat der Uhr festlegen
> > > //
> > > void Display_Time(void)
> > > {
> > >     Write2Digits(0,Stunde);                 // Stunde
> > >     LCD_WriteChar(':');
> > >     Write2Digits(3,Minute);                 // Minute
> > >     LCD_WriteChar(':');
> > >     Write2Digits(6,Sekunde);                // Sekunde
> > > }
> > >
> > > //------------------------------------------------------------------------------
> > > // Zeitberechnung
> > > //
> > > void RTC(void)
> > > {
> > >     cnt1++;                                 // 10ms Zähler erhöhen
> > >     if (cnt1==50)
> > >     {
> > >         Port_WriteBit(PORT_LED1,PORT_OFF);  // LED1 ausschalten
> > >     }
> > >     if (cnt1==100)
> > >     {
> > >         Port_WriteBit(PORT_LED1,PORT_ON);   // LED1 einschalten
> > >         Display_Time();                     // Funktionsaufruf: Display_Time
> > >
> > >         LCD_Ausgabe();
> > >
> > >         Sekunde++;
> > >         if (Sekunde==60)
> > >         {
> > >             Sekunde=0;
> > >             Minute++;
> > >             if (Minute==60)
> > >             {
> > >                 Minute=0;
> > >                 Stunde++;
> > >                 if (Stunde==24) Stunde=0;
> > >             }
> > >         }
> > >         cnt1=0;
> > >     }
> > > }
> > >
> > > //------------------------------------------------------------------------------
> > > // Interrupt alle 10ms
> > > //
> > > void INT_10ms(void)
> > > {
> > >     int irqcnt;
> > >
> > >     RTC();                                  // Funktionsaufrauf: RTC
> > >     irqcnt=Irq_GetCount(INT_TIM2COMP);      // Interrupt Request Counter
> > > }
> > >
> > > //------------------------------------------------------------------------------
> > > // Hauptprogramm
> > > //
> > > void main(void)
> > > {
> > >     LCD_Init();                             // Display initialisieren
> > >     LCD_ClearLCD();                         // Display löschen
> > >     LCD_CursorOff();                        // Display Cursur ausschalten
> > >
> > >     cnt1=0;
> > >
> > >     Port_DataDirBit(PORT_LED1,PORT_OUT);    // LED1 auf Ausgabe vorbereiten
> > >     Port_WriteBit(PORT_LED1,PORT_OFF);      // LED1 ausschalten
> > >     Sekunde=00;                           // Startzeit festlegen z.B. 12:25:00
> > >     Minute=00;
> > >     Stunde=00;
> > >     Irq_SetVect(INT_TIM2COMP,INT_10ms);     // Interrupt Service Routine definieren
> > >     while (1);                              // Endlosschleife, hier können weitere
> > >                                             // Anweisungen stehen
> > > }
> > >
> > >
> > >
> > > //-------------------------------------------------------------------------------------
> > > void LCD_Ausgabe(void)                      // wird jede Sekunde aufgerufen
> > > {
> > >     char text[10];
> > >     text="ABCDEFGH";
> > >     LCD_CursorPos(0x40);                    // Verzögert die RTC
> > >     LCD_WriteText(text);
> > >
> > >
> > > }


    Antwort schreiben


Antworten: