Kommentar: Einfügen von HTML im Kommentar: Link einfügen: <a href="LINKURL" target="_blank">LINKTITEL</a> Bild einfügen: <img src="BILDURL"> Text formatieren: <b>fetter Text</b> <i>kursiver Text</i> <u>unterstrichener Text</u> Kombinationen sind auch möglich z.B.: <b><i>fetter & kursiver Text</i></b> C Quellcode formatieren: <code>Quellcode</code> BASIC Quellcode formatieren: <basic>Quellcode</basic> (Innerhalb eines Quellcodeabschnitts ist kein html möglich.) Wichtig: Bitte mache Zeilenumbrüche, bevor Du am rechten Rand des Eingabefeldes ankommst ! -> I > 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); > > > > > > > > > > > > }