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 | ||
| ||
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: |
Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - Zum C-Control-I-Forum - Zum C-Control-II-Forum