Hallo Zusammen, ich hab eine Routine geschrieben, die einen uint16 bei TCNT0 > 230 um eins hoch zählt. TCNT0 läuft mit 2304 KHz. Ziel ist es die uint16 Variable als 100us-Timer zu verwenden. Die Hochzählroutine wird zyklich im main() aufgerufen. Das komische ist, dass die uint16 Variable ca. 6 mal langsamer zählt als angedacht. Testweises pintoggeln läuft mit 6 Sek Periodendauer, nicht 1sek. wie durch die Tesroutine vorgegeben. und jetzt der Knaller: Wenn ich mitten im Code in der main() die Zeile t = TCNT0 / 3; einfüge läufts wie gewollt mit einer Sekunde Periodendauer, wobei t eine uchar ist und sonst nirgends auftaucht als in dieser Zeile. es ist auch egal ob ich "/3" oder "/10" oder "/100" schreibe, das Ergebnis ist das selbe. Die Frage ist nun: wie kann diese eine Zeile den Programmablauf so massiv beeinflussen? Es ist nur ein Lesezugriff auf den TCNT0 und t wird auch nicht weiter verarbeitet. Seh ich den Wald vor lauter Bäumen nicht mehr oder ist das wirklich strange? Vermutlich fehlt hier einiges an Info für ne Analyse... also bitte melden Gruß, Ralf
Hi >Das komische ist, dass die uint16 Variable ca. 6 mal langsamer zählt als >angedacht. Testweises pintoggeln läuft mit 6 Sek Periodendauer, nicht >1sek. wie durch die Tesroutine vorgegeben. Sicher, das es nicht 8x langsamer ist? das würde auf die CKDIF-Fuse hinweisen. MfG Spess
bin mal neugierig ob der code euch schlauer macht. die Routine inkrementiert die 10 counter. die if-Abfrage erkennt ein Overflow void timers (void){ unsigned char i; static char oldtim; // 0,1ms intervalle if (TCNT0 < oldtim) { for (i = 0; i < 10; i++){ counter[i]++; } TCNT0 = 0; oldtim = 0; } oldtim = TCNT0; } Konfig von Timer0: TCCR0A=0x02; TCCR0B=0x02; TCNT0=0x00; OCR0A=230; OCR0B=0x00; So sollte er imo mit 2,3MHz takten was bei OCR0A = 230 alle 100us ein Overflow erfährt. Hinweis: Ich habs jetzt mal mit nem Interrupt versucht und alle Aufrufe auskommentiert. Der Chip macht jetzt also nichts mehr anderes als auf das ov zu warten. Innerhalb vom if-Statement lass ich einen Pin toggeln. Verhalten bleibt identisch. btw: die UART z.b. rennt gut. die Bitbreite passt einwandfrei! so und jetzt? überseh ich was essentielles?
Hallo, dein Zeitfelher entsteht, weil du TCNT0 in der Schleife in Main wieder auf Null setzt - das wird vom Timer auutomatisch gemacht. Im übrigen ist diese Auswertung des Timerüberlaufs - nimm's mir nicht krumm - völlig vermurkst. Nimm die ISR des Timers setzte dort ein Flag und werte dieses in der Main Schleife aus. Sascha
Ralf S. schrieb: > überseh ich was essentielles? Ja. Du hast nicht die geringste Ahnung, wie man einen Timer benutzt. Dein Thread sollte die Überschrift "Seltsames Benutzen..." tragen. Arbeite erstmal die Grundlagen durch: http://www.mikrocontroller.net/articles/AVR-Tutorial:_Timer mfg.
ja schön ist es nicht, das weis ich... aber die isr will ich nicht nehmen, weil ich allgemein auf Interrupts verzichten will. Der Programmablauf sollte so deterministisch wie möglich sein und eine ISR kommt eben wann sie will. das setzen von TCNT0 = 0; ist an der Stelle tatsächlich unnötig.. stimmt.. mach ich raus... aber das führt doch noch lange nicht dazu, dass die Routine 6 mal langsamer läuft als sie soll und vor Allem diese eigentlich sinnlose Zeile mit der Teilung das Programm zum wuppen bringt... btw, kleiner Rückzieher: Der Programmablauf mit der ISR haut hin... (nicht wie oben beschrieben), war ein sehfehler...
Danke Thomas für Deinen konstruktiven Beitrag. Du hast mir wirklich weiter geholfen! Jetzt weiß ich endlich wofür Timer da sind.
Ralf S. schrieb: > ja schön ist es nicht, das weis ich... aber die isr will ich nicht > nehmen, weil ich allgemein auf Interrupts verzichten will. Der > Programmablauf sollte so deterministisch wie möglich sein und eine ISR > kommt eben wann sie will. wenn du meinst > das setzen von TCNT0 = 0; ist an der Stelle tatsächlich unnötig.. > stimmt.. mach ich raus... aber das führt doch noch lange nicht dazu, > dass die Routine 6 mal langsamer läuft als sie soll doch, der Timer läuft und zählt TCNT0 kontinuierlich hoch und setzt den bei erreichen von OCR0A auf Null. Nun kommt deine Routine zum Zug und erhöht erst mal gemütlich deine 10 Counter, in der Zeit ist TCNT0 schon weitergelaufen. Dann setzt du TCNT0=0 und der Timer muss wieder bei Null beginnen was die Zeit natürlich erhöht. > und vor Allem diese > eigentlich sinnlose Zeile mit der Teilung das Programm zum wuppen > bringt... dann solltest du mal dein ganzes Programm zeigen Sascha
Ralf S. schrieb: > Danke Thomas für Deinen konstruktiven Beitrag. Du hast mir wirklich > weiter geholfen! Jetzt weiß ich endlich wofür Timer da sind. Na' das freut mich doch. Dann ist dein Zähler ja in 5 Minuten fertig. Mehr braucht man für so einen Piffelkram nämlich nicht. mfg.
Ralf S. schrieb: > Spätestens nach dem Text brauchst Du ne Kippe danach, oder Thomas? Irgendwie findest du dich dich witzig, oder? Aber du bist der Trottel, der einen kleinen Zähler nicht zum Laufen bekommt. Und das finde ich wieder witzig. mfg.
nun ich bitte in diesem Forum um Hilfe, weil ich bei meinem Problem an meine fachlichen Grenzen gekommen bin. Da Du mir mit diesem Problem nicht weiter geholfen hast, scheinen Deine Grenzen <= den Meinen zu sein. Fragt sich nun wer der größere Trottel ist. Anders gefragt: inwiefern bereichert es Dich anderen ihr fachliches Defizit vorzuhalten anstatt einen konkreten Lösungsanstz zu suchen? Die anderen haben das doch auch geschafft...
Ralf S. schrieb: > Da Du mir mit diesem Problem nicht weiter geholfen hast Doch, das habe ich schon lange getan: Thomas Eckmann schrieb: > Arbeite erstmal die Grundlagen durch: > http://www.mikrocontroller.net/articles/AVR-Tutorial:_Timer Wenn du das nicht annimmst und stattdessen hier rumheulst, ist das dein Problem. Genauso wie dein Zähler, der nicht funktioniert. Aber in dem Artikel findest du die Grundlagen dazu, das zu lösen. mfg.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.