Guten Tag, hab schon die Suchfunktion bemüht und schon einige Stunden mit Experimenten verbracht, aber ich komme nicht zum gewünschten Ergebnis. Auch im Datenblatt habe ich für mein Problem nichts gefunden. Leider komme ich nicht drauf was genau passiert. Mein Projekt: Tacho der mittels Reedkontakt die Umdrehungen meines Rades mißt und daraus unter anderem die Geschwindigkeit errechnet. Prozessor: ATMEGA169 der dauernd schläft und beim Ticken des asynchronen Timer2 (64 mal pro Sekunde, macht immer 64 Schritte bei 4096Hz) aufwacht. Der Reed ist am Pin Change Interrupt welcher auch den Schläfer weckt. Code ist mal im Anhang was die problematischen Teile angeht. Um den PCI kurz zu halten, lese ich beim Schließen des Kontaktes den Timer2 Zustand aus und die Variable revolution. Mein Rad dreht so langsam, dass der Timer2 mehrfach tickt, bis eine Umdrehung fertig ist. Um die Anzahl der Timerschritte zu berechnen, multipliziere ich die Anzahl der revolutions mit 64, addiere der Timerstand hinzu und subtrahiere den alten Timerstand vom letzten Mal. Oh Wunder: Funktioniert wunderbar. Aber hin und wieder ist das Resultat der Timerschritte falsch, es scheint um 64 zu hoch oder zu wenig zu sein. Hab beide Effekte. Liegt es daran, dass beide Interrupts gleichzeitig feuern und dabei die Berechnung einen Fehler bekommt? Ich inkrementiere die revolutions im Timer2 Interrupt, denke wenn beide gleichzeitig feuern kommt das einmal zu spät. Habe daraufhin in diesem Falle eine revolution zur gezogenen Kopie hinzugefügt, es kommt aber immer mal sporadisch solch ein Ausreisser vor. Timer1 mit 16 Bit wäre natürlich besser geeignet, da entfällt das Aufzählen der Timer Interrupts. Wegen Stromsparen nutze ich aber nur den asynchronen Timer2 der leider nur 8 Bit hat. Ich teste zur Zeit mit einem externen Frequenzgenerator ohne Reed, also da ist nix mit Prellen und so. Also: Es funktioniert im Prinzip, aber es kommen selten sporadisch Ausreisser. Woher kann das kommen? Wie fange ich diese Dinger ab? Interrupt Spezies: Wer kanns erklären? Besten Dank Thomas
Ich würde mal auf einen prellenden Reed-Kontakt tippen. Wie wär´s wenn Du das erstmal abfängst?
Hab doch geschrieben dass ich mit einem elektronisch generierten Takt arbeite... Der Reed kommt später und prellt nicht.
Es könnte ein problem mit fast gleichzeitig auftretenden Interrupts sein. Es kann dann passieren das die Reihenfolge mit der der Overflow Interrupt und der PCI aufgerufen werden nicht stimmt. Den Fall muß man dann in Software abfragen, anhand des Zählerstandes. Ein ähnliches Problem gibt es auch bei der Messung über timer1 mit ICP und Überlauf.
Das prüfe ich schon ab: if (TIFR2&0x02) //in case Timer2 and PCI fire at the same time, PCI has priority { tmp_rev++; revolution=0; } else revolution=0; Wenn beide gleichzeitig feuern hat der externe PRIO und sieht bei TIFR2 nach ob der andere auch will. Dann wird bei tmp_rev einer zugezählt und das Ergebnis stimmt. Hab den Fall analysiert und die Geschwindigkeit stimmt hier. Die Ausreisser kommen woanders her. Soweit hab ich es nachvollzogen...
Kannst du uns ein Modell-Flow-Chart machen. (Skizze ) und dann hier reinposten. Möglicherweise geht das noch trickreicher zu lösen. Siehe hier im Forum das Project mit dem 32 Bit-Zähler von Peda. glaube ich. Das war echt ausgefuchs gemacht. Mit der mathematischen Korrektur u. Konditioneller Nachberechnung. Suche ich auch noch raus. Ich poste noch das Komplette PDF Teil. Embedded Design Pattern. Der Professor schreibt, sonst ist das nicht störungfrei möglich, OK aber wieso. ???? Geht das nur so 100% richtig???, und hier bei dir nur 99,99 % Der Professor aus der FH Klaustal hat einen Leitfaden dazu geschrieben, aber nur nicht das „Zauberwort“ volatile hat er vor die dedizierten IRQ-Variablen geschrieben. OK ist halt so... aber warum meldet der Prof. da bedenken an. ???? Und schaltet dediziert den IRQ_ab und geht die volatile Varaiablen holen. bzw. lesen und zwischenspeichern. Und schaltet danach dediziert den General-Master-IRQ wieder an. Aber auch speziell bei den AVRs mit dem GNU C Compiler ist das volatile var „atomar“ wichtig.!!!! Siehe Anhang: Störungfreie Ubergabe der volatile Variablen vom IRQ zum MAIN 1) Dedizierte Befehle mit cli, bzw. sei ... Befehl im Main.
Hast du Z.B erst mal zum testen Z.B 10K-Pull-Ups an dem dedizeiten Extern-IRQ PINs?? PitFall: Die intern MCU-Pulls sind soo weak sometimes. Grundsätzlich wird der z.B IRQ_#1 als flg im Latch gespeichert, falls der andere bearbeitet wird. Es geht also kein IRQ veschütt. Der im Rahmen der z.B Latenzzeit z.B bei 16MHZ respektive liegt.
Hallo Holger, danke erstmal für die Posts, auch wenn ich nicht ganz folgen kann. Ich versuche es mal zu erklären was ich tu: Es gibt zwei Interrupts, den PCI und den Timer2. Timer2 feuert 64 Mal pro Sekunde und macht zwischendurch 64 Schritte. Ich möchte die Anzahl der Schritte des Timer2 zwischen zwei PCI messen. Dazu setze ich im PCI den Wert revolution (volatile) auf 0 und inkrementiere den in jedem Timer2 Interrupt. Damit weiß ich, wie oft der Timer gefeuert hat. Wenn der nächste PCI kommt nehme ich mir eine KOPIE dieses Wertes. Da das in einem Interrupt erfolgt brauche ich kein cli() und sei(), ich mach keine nested Interrupts. Einverstanden? Die Atomarität sollte also gewährleistet sein. Mit new_round=1 signalisiere ich der main() dass eine neue Geschwindigkeit berechnet werden soll. Ich habe vorher mir den Wert des TCNT2 kopiert (auch im Interrupt) als curr_TC. Dieser fließt bei der Berechnung mit ein und wird für die nächste Berechnung als old_TC behalten nachdem die Berechnung fertig ist. Alle Variablen sind volatile. Die vergangenen Timerticks sind also: tmp_rev *64 + curr_TC - old_TC im Moment wenn der PCI feuert. Die Falschwerte die ich ab und an bekomme sind haben immer 64 zu wenig bei den Timerticks, dadurch bekomme ich eine falsche Geschwindigkeit. Die Werte für TCNT2 sind oft aber nicht immer 0 in diesem Fall. Den Fall dass beide IRQ gleichzeitig vorliegen, der PCI also Vorrang hat und der Timer noch nicht die revolution hochzählen konnte, habe ich abgefangen. Dieser liefert das korrekte Ergebnis. Die Ausreisser haben einen anderen Grund. Ist da in dem Konzept ein Fehler den ichnicht sehe? Gruß Thomas
Hi Sieht mir nach Zählerüberlauf aus. Wenn ich dich richtig verstanden habe, möchtest du eine Geschwindigkeit messen. Die ergibt sich aus Zeiteinheiten pro Umdrehung. Also: Zeitinterrupte zählen. Ereignisimpuls von Umdrehung löst folgendes aus: Gezählte Zeiteinheiten der Berechnungsroutine auf sep. Variable zur Verfügung stellen und Zeitzähler auf 0 setzen.Entweder direkt von hier die Berechnung und Aktualisierung der Anzeige aufrufen, oder Flag setzen und vom Hauptprogramm Flag bearbeiten lassen. Entschuldige, wenn ich's nicht mit Code verdeutliche, ich hab von "C" nur einen ganz blassen Schimmer. Aber immerhin, ich weiß, wie man es schreibt .... Also, vielleicht noch mal in Blöcke gefasst: Timer_ISR: Zählen der Interrupts IO_ISR: Zeitzähler umkopieren, Zeitzähler löschen Berechnung auslösen So sollte es gehen und der Zähler kann so gewählt werden, das er nicht "überläuft". Gruß oldmax
Hi Oldmax, genau so mache ich es und es funktioniert ja richtig! Nur ab und an bekomme ich "Ausreisser": Hab das mal analysiert: Mein externer Taktgenerator läuft mit einer Frequenz, so dass ich etwa 107 "Sachen" fahre. Passt! Jedoch dann und wann fahre ich entweder 135 oder auch mal 88 Sachen. Bei 4096Hz Takt für Timer2 und einem Radumfang von 2.16m vergehen also etwa 300 Ticks bei 107km/h. Bei 88 sind es etwa 364, bei 135 etwa 236. Diese Werte bekomme ich sporadisch. Es ist also ab und zu ein Fehler von genau 64 Ticks da, WARUM?? Es kommt nicht vom Doppelinterrupt, wenn also beide zugleich feuern. Den Fall hab ich analysiert und abgefangen, passt. Gruß Thomas
Thomas schrieb: > Bei 88 sind es etwa 364, bei 135 etwa 236. Diese Werte bekomme ich > sporadisch. Es ist also ab und zu ein Fehler von genau 64 Ticks da, > WARUM?? > > Es kommt nicht vom Doppelinterrupt, wenn also beide zugleich feuern. Den > Fall hab ich analysiert und abgefangen, passt. Ganz sicher? Da sich deine Geschwindigkeit ja normalerweise nicht sprunghaft verändert, könntest du ja auch mal die Ausreisser mitprotokollieren (also die Ausgangswerte), wenn es doch passiert. Dann hast du besseres Zahlenmaterial zur Analyse und bist nicht auf Ratespielchen angewiesen.
Ich bin ziemlich sicher. Habe einen Parameter definiert, der mir ein Segment meiner Anzeige einschaltet. Dieser wird mit der Bedingung if (TIFR2&0x02) im PCI gesetzt. Das ist wohl der Fall hier. Im PCI ist TIFR2 auf 2, also wartet der Timer2 Interrupt bis der PCI fertig ist da dieser höhere Prio hat. Einsprüche hier? Mein Segment geht dann und wann an, die Geschwindigket ist aber richtig in dem Moment. Und im Gegensatz dazu geht mein Segment nicht an, es hat aber eine falsche Geschwindigkeit gegeben. Deshalb bin ich einigermassen sicher dass der Fall Doppelinterrupt nicht mein Problem ist. Ich hab die Ausreisser mal mitprotokolliert, es ist meist ein Wert von 364 oder 236 Timerticks wenn 300 erwartet wird. Das sind immer 64 zu viel oder zu wenig, meine simulierte Frequenz von aussen ist konstant.
Das Abfangen des geleichzeitigen Interupts sieht mir noch nicht ganz richtig aus. Wenn man den verpaßten Timer Overflow erkannt hat, und dann durch tmp_rev++; revolution=0; nachholt, muß man den anstehenden Timerinterupt auch noch löschen. Sonst wird 2 mal erhöht. Je nachdem ob der Effekt beim Start oder Stop bekommt, gibt das dann den einen overflow zu viel oder zu wenig. Sonst ggf. nochmal den kompletten Code zu den ISRs posten.
Ich habe schon diverse Versionen die alle das selbe Problem haben. Den Timer Interrupt will ich nicht löschen, der macht noch andere Sachen: Uhr weiterzählen LCD steuern. Deshalb bin ich auch auf 64Hz festgelegt. Ich hänge mal meinen Code dran, das ist eine Version die noch am wenigsten das Problem zeigt. Der problematischste Fall ist zu hohe Geschwindigkeit, die wird als Maximalgeschwindigkeit abgespeichert. Die Ausreisser nach unten sind nicht ganz so kritisch. Aber ich will wissen woran es liegt. Also: ZIP im Anhang. Besten Dank!!
Super das du den Code gepostet hast. An duo tüftel IRQ#s rumspielen macht immer viel Spass, und ich lernt was dabei. Ich versuche mir immer ein Bild von der Anwendung. zu machen. Du hast viel Zeit in dein Projekt investiert. Ist deine Anwendung etwar so wie in diesem Video??? Die ist mit einem PIC gemacht. Ich habe mal eine Drehzahl in (RPM) mit CAPTURE MODE gemacht. PIN-EXT-IRQ EDGE GATE geht Puls in das Capture Reg.=Zähler von 80535 MCU. Hast du einen Anderen Weg vor falls das nicht mit deinem Algorithmus klappen sollte.??? 1)Ist das so ein Schaltbild ???? http://www.youtube.com/watch?v=ic7t_mYDPWM Analoges Integral nachbilden. Digitaler Analog-Tacho RPM Rounds Per MINUTE. Stichwort: CAPTURE MODE: VIA TIME-CLOCKS triggers Gated Counter. ++CountedClocks per MCU-CLOCK SPEED Wie bei der ADC Messung mache ich einen Messbuffer auf,wo die Werte gemittelt werden, damit ich da arithmetisch via Mittelwert FILTER:geglättet rauskomme. Du hast keinen Mittelbuffer in deinem Code. Viel Erfolg. Gruss Holger.
Bei der Erkennung eines noch ausstehenden Overflow Interrupts könnte ein Fehler passieren. Genau hab ich es nicht kontrolliert, aber besonders wenn der Takt relativ hoch ist, könnte es passieren, das die ISR für den Overflow zu schnell fertig wird, trotz der länge. Dann wäre der Counter 2 noch beim Wert 0, obwohl die Overflow ISR schon ganz fertig ist. Meiner meinig nach sicherer geht das Erkennen eines aussteheden Interrupts über das Interrupt flag Register, zusammen mit der Forderung das der Timerwert klein ist. So funktioniert es jedenfalls bei Timer1 und ICP. An 2.tes Mögliches Problem könnte ein mechnisches Prellen sein. Das sollte dann aber zu ausreißen mit deutlich zu hoher Geschwindigkeit führen, nicht gerade der eine falsche Überlauf.
http://www.ermicro.com/blog/?p=1461 Flow-Charts sind auch dabei. Ich habe den Code mal analysiert. Da ist eine STATE-ENGINE für PCI drin (PIN-CHANGE-IRQ)= PCI Einfach und sicher, denke ich.. Mit Kombinations-Hilfe als TIMER OVERFLOW IRQ = (TOVR-IRQ) Sauber gemacht mit case switch()..... IRQ ACK, u. volatile....Koppel-Variablen. Gruss Holger. // PIC18 High-priority Interrupt Service void interrupt high_isr(void){ static unsigned char pulse_state=0; unsigned int rpm_timer; if (TMR0IF) { // Check for TIMER0 Overflow Interrupt rpm_value = 0; // Reset the global volatile RPM Value TMR0IF=0; // Clear TIMER0 interrupt flag,T-OVR_(ACK-IRQ#1AVR) } if (INT0IF){ // Check for External INT0 Interrupt switch(pulse_state) { case 0: // First Low to High Pulse TMR0H = 0; // Zero the high byte in TMR0H Buffer TMR0L = 0; // Clear 16-bit TIMER0 Counter pulse_state=1; // P´reset for-Next_STATE ‘#S1 break; case 1: // Second Low to High Pulse at STATE ‘# rpm_timer=TMR0L; // Get the first 8-bit TIMER0 Counter rpm_timer+=(TMR0H << 8); // Get the last 8-bit TIMER0 Counter // Calculate RPM = 60 x (1/Period) // RPM Value = 60000 (1 / (0.032 ms x rpm_timer)) rpm_value = (int) (60000.0 / (0.032 * rpm_timer)); pulse_state=0;// XOR P´reset forNext_STATE ‘#S0 } INT0IF = 0; // Clear INT0 interrupt flag, _(ACK-IRQ#1AVR) }
Danke erstmal an euch, aber ich bin nich sicher dass ich das Problem verstehe. Ulrich schreibt: "Bei der Erkennung eines noch ausstehenden Overflow Interrupts könnte ein Fehler passieren. Genau hab ich es nicht kontrolliert, aber besonders wenn der Takt relativ hoch ist, könnte es passieren, das die ISR für den Overflow zu schnell fertig wird, trotz der länge. Dann wäre der Counter 2 noch beim Wert 0, obwohl die Overflow ISR schon ganz fertig ist." Was ist damit gemeint? Die Erkennung des ausstehenden Timer IRQ wenn der PCI feuert? Was ist gemeint mit "zu schnell fertig"? Wenn TCNT2 nach dem Timer Interrupt immer noch auf 0 ist so ist das aus meiner Sicht normal und OK. Ich hab das Problem mit 500KHz Takt und auch 8MHz. Welchen Fall muss ich denn nun genau analysieren? Ich sehe drei Möglichkeiten: 1.PCI feuert alleine, so ist es üblich. Sollte unproblematisch sein. 2.Timer und PCI feuern gleichzeitig: PCI hat Prio, Timer wird nacher bedient. 3.Timer IRQ wird bedient, PCI funkt dazwischen. Für Punkt drei habe ich es mal mit und ohne nested Interrupt versucht, das Problem bleibt. Was meinst du Ulrich? Geht es um Punkt 2? Ich fürchte ich stehe hier auf dem Schlauch.
Das Problem mit der zu schnellen Ausführung des Interrupts könnte passieren, wenn erst der Timer Interrupt Auftriff, und dann gleich danach der PCI. Mit dem 500 kHz Takt sollte das aber eher selten passieren. Auch sonst ist da Zeitfenstser vermutlich ziehmlich keine und der Fehler würde nur sehr selten auftreten. Mir ist da noch eine Mögliche Fehlerquelle eingefallen: Bei einigen der AVRs gibt es einen Fehler beim Timer, und es kann passieren das ein Timer Interrupt verloren geht, wenn man zur falschen Zeit in das OCR register schreibt. Habs nicht genau nachgelesen, nur so aus dem Gedächnis.
Hi Ulrich, stimmt, hab ich irgendwie nicht so richtig verstanden. Aber diese Änbderung bringt es auch nicht: TCCR2A |= (1<<CS21) | (1<<WGM21); while (ASSR&0x01) ;//wait until OCR2UB reads 0, TCNT2 reads correctly curr_TC = TCNT2;//take snapshot of timer 2 status NOW! Hatte da vorher den OCR2A beschrieben, das ist ungünstig. Habe in anderen Versionen auch schon mal das Timer IF Register gelsesen anstatt TCNT2 auf 0 zu prüfen. Egal was ich versuche, das Problem bleibt. Danke für den Tip erstmal.
Hi Ich habe mal deine Geschwindigkeitsmessung nachgerechnet.... Also, wenn du mit 64 Hz über eine Bewegung die Zeitimpulse mißt, also alle 15,2ms dann ist deine Rotationsgeschwindigkeit 1/(imp*(1/64)) also 1/(imp*0,0152s) Annahme, dein Rad hat 1 m Umfang und du hast bei einer Umdrehung 17 Impulse gezählt, dann ergibt das 3,77 m/s. Hochgerechnet 13,574 Km/h. nächste Annahme : du hast 18 Impulse gezählt ergibt eine Umfangsgeschwindigkeit von 12,8Km/h. Nun lassen wir das Rad mal langsam drehen.. also wesentlich mehr Zeitinterrupts zählen. Angenommen 1000 Also (1/(1000*1/64))*60*60 ergibt 230,4 m/h 2. Rechnung mit 1001 Impulsen (1/(1001*1/64))*60*60 =230,1 m/h Nun lassen wir es mal extrem schnell laufen, d. h. es gibt nur wenige gezählte Zeitinterrupts z. 2 Also (1/(2*1/64))*60*60 ergibt 115,2 km/h 2.Rechnung mit 3 Impulsen (1/(3*1/64))*60*60 ergibt 76,8 km/h Wenn du nun knapp um den nächsten Zeitimpuls drehst, kann die Ungenauigkeit der Reed-Kontakte dazu führen, mal einen Zeitimpuls mehr oder weniger zu sehen, je nachdem. Irgendwo multiplizierst du diese Zeitimpulse auch noch mit 64, wofür auch immer. Kein Wunder, das dein Fehler auch diese 64 irgendwie aufzeigt..... Zu deinem Programm: Ich hab keine Ahnung von C, aber soviel ich sehe, ist deine Rechnung auch falsch. Wenn du genauer werden möchtest, dann löse mit ms auf und leite die anderen Ereignisse aus dieser ms ab. Dazu wird der Timer mit entsprechendem Vorteiler und Überlauf parametriert.Dazu kann ich hier das Timer-Tutorial empfehlen. Hier mal beispielsweise den Unterschied aus ms-Interrupts Also (1/(1000*0,001s))*60*60 ergibt 3,6 km/h (1/(1001*0,001s))*60*60 ergibt 3,596 km/h (1/(10*0,001s))*60*60 ergibt 360 km/h (1/(11*0,001s))*60*60 ergibt 327,272km/h Du siehst, 1 Interrupt mehr oder weniger fällt nicht so stark ins Gewicht. Diese Rechnung hab ich überhaupt nicht durchschaut.... new_round=0; { time = tmp_rev*64+curr_TC-oldTC; loc_tmp= 2160; loc_tmp= 72*loc_tmp; loc_tmp/=time; veloc=(loc_tmp+2)/5; //km per hour, rounding included } oldTC=curr_TC; //remember last Timer value Vielleicht seh ich das aber auch nur falsch, weil ich deinen Code nicht versteh. Gruß oldmax
Hallo Oldmax, ich weiß, der Code von anderen (und meine eigener nach ein paar Wochen) ist immer schwer zu verstehen. Ich erkläre es gerne mal: Ich betreibe ein LCD das mit 32Hz umschaltet, deshalb nehme ich den Timer2 mit 64Hz. Der ist fest, kann ich nicht ändern. Ausserdem zählt er meine Uhr weiter. Die 64Hz sind aber nur die Überläufe, die Schrittweite ist 1/4096Hz also etwas mehr als 240µs. Ich zähle nicht allein die Überläufe (revolution) sondern lese auch den TCNT2 aus. Damit bekomme ich eine schön hohe Auflösung. Beispiel: Reed schaltet, ich lese TCNT2=20 aus und revolution=10. Nächste Umdrehung: TCNT2 = 55, revolution = 10. Zwischen den Reed Schaltpunkten habe ich also 10*64 +55-20 Timerticks gehabt, das sind 675 Ticks zu 244µs. Auflösung ist 244µs, reicht mir vollkommen aus. 64 weil jede revolution schon 64 Ticks hatte, 55 weil ich in diesem Timerzyklus bis 55 gekommen bin und -20 weil ich letztes Mal bei erst bei 20 angefangen habe. Ich hoffe es ist klar geworden. Klar kann ich für diese Spielereien den 16 Bit Timer1 nehmen, aber den kann ich nicht asynchron betreiben wie Timer2. Stichwort: Stromsparen. Ich hab das in anderen Projekten auch schon mal so gemacht, geht auch braucht aber mehr Strom. Es fällt ein Timertick nicht so ins Gewicht, ein Überlauf zuviel oder zu wenig schon. Ich stimme zu, das löst aber nicht mein Problem. Zur Info: Es funktioniert ja richtig, die Geschwindigkeit wird genau angezeigt, alles super. Mein Problem sind die Ausreisser dann und wann, oder um genau zu sein: Was verursacht die denn?? Wenn ich es verstanden habe kann ich es bestimmt lösen. Gruß Thomas
Würde es so machen, revolution muss natürlich ein signed Typ werden:
1 | if (TIFR2&0x02) |
2 | { |
3 | tmp_rev++; |
4 | revolution = -1; |
5 | curr_TC = 0; |
6 | } |
7 | else |
8 | revolution=0; |
Hi Jetzt hab ich's verstanden... Na ja, bin ja auch schon etwas älter, da rieselt's schon leicht. Aber ich bin noch lernfähig. Ok, dann werd ich mal weiter denken... Ich bin immer noch davon überzeugt, es liegt an der Multiplikation mit 64... Gruß oldmax
So Freunde, ich hab mal meine serielle Schnittstelle angeworfen und mit meiner Testfrequenz (elektornisch generiert) die Interrupts gefeuert. Es werden dabei etwa 300 Ticks erwartet, ich habe mal die Ticks, die Timerüberläufe (Revs), den TCNT2 Wert TC und den TC vom letzten Male (oldTC) ausgedruckt. Sowas kommt heraus, bitte mal um Kommentare was da schiefgeth, es ist nicht immet TCNT2=0 oder so... 300 Revs:5 oldTC:38 TC:18 301 Revs:4 oldTC:18 TC:63 300 Revs:5 oldTC:63 TC:43 300 Revs:5 oldTC:43 TC:23 300 Revs:5 oldTC:23 TC:3 301 Revs:4 oldTC:3 TC:48 300 Revs:5 oldTC:48 TC:28 300 Revs:5 oldTC:28 TC:8 301 Revs:4 oldTC:8 TC:53 300 Revs:5 oldTC:53 TC:33 301 Revs:5 oldTC:33 TC:14 300 Revs:4 oldTC:14 TC:58 300 Revs:5 oldTC:58 TC:38 272 Revs:4 oldTC:38 TC:54 299 Revs:5 oldTC:54 TC:33 301 Revs:5 oldTC:33 TC:14 259 Revs:4 oldTC:14 TC:17 300 Revs:4 oldTC:17 TC:61 250 Revs:4 oldTC:61 TC:55 263 Revs:4 oldTC:55 TC:62 299 Revs:5 oldTC:62 TC:41 300 Revs:5 oldTC:41 TC:21 301 Revs:5 oldTC:21 TC:2 273 Revs:4 oldTC:2 TC:19 300 Revs:4 oldTC:19 TC:63 300 Revs:5 oldTC:63 TC:43 300 Revs:5 oldTC:43 TC:23 300 Revs:5 oldTC:23 TC:3 300 Revs:4 oldTC:3 TC:47 300 Revs:5 oldTC:47 TC:27 301 Revs:5 oldTC:27 TC:8 300 Revs:4 oldTC:8 TC:52 300 Revs:5 oldTC:52 TC:32 301 Revs:5 oldTC:32 TC:13 300 Revs:4 oldTC:13 TC:57 300 Revs:5 oldTC:57 TC:37 300 Revs:5 oldTC:37 TC:17 300 Revs:4 oldTC:17 TC:61 301 Revs:5 oldTC:61 TC:42 300 Revs:5 oldTC:42 TC:22 300 Revs:5 oldTC:22 TC:2 300 Revs:4 oldTC:2 TC:46 300 Revs:5 oldTC:46 TC:26 300 Revs:5 oldTC:26 TC:6 300 Revs:4 oldTC:6 TC:50 300 Revs:5 oldTC:50 TC:30 300 Revs:5 oldTC:30 TC:10 300 Revs:4 oldTC:10 TC:54 301 Revs:5 oldTC:54 TC:35
Guten Morgen, noch eine kurze Rückmeldung an MWS: Das hatte ich schon alles versucht, offensichtlich kommt das Problem nicht nur vor wenn die Interrupts zusammenfallen. Hat leider nicht geholfen. Ich hab den Testcode mal angehängt, so habe ich das Problem mal ohne das ganze LCD Gerümpel nachgebildet. Hat jemand eine Idee was da passiert? Ich feuere den externen Interrupt mit etwa 13.6Hz. Auch bei anderen Frequenzen tritt das sporadisch auf. Bin bis Freitag beruflich unterwegs und kann mich erst dann wieder melden. Gruß Thomas
Und nochwas: Ich hab mal die Ticks anders berechnet, nicht revolutions aufgezählt und dann mit 64 multipliziert, sondern jeden Interrupt die Variable um 64 erhöht, das spart die Multiplikation. Und plötzlich kommt das Problem nur noch SEHR vereinzelt vor, und dann scheint mir der TC Null zu sein. Sehe ich mir an wenn ich wieder Zeit habe, am Wochenende geht es weiter. Bid die Tage, Gruß Thomas
> Hat jemand eine Idee was da passiert?
So wie ich das sehe hast Du da keine groben Schwankungen, sondern nur
einen Fehler von 1, gleichbedeutend der kleinsten Auflösung des Timers.
Das ist normal, wenn Timerfrequenz und Sampelfrequenz in keinem fest
verzahnten Zusammenhang steht. Die Genauigkeit würde besser, wenn der
Prescaler 1 würde und der Timer einfach durchläuft, also ohne Compare.
Den Rest wie gehabt, im Ovf Int die Runden zählen und ggf. anstehende
Ovf Ints in der PC Int behandeln.
Der Thread ist ja schon etwas älter, gibt es da inzwischen eine Lösung? Ich vermute, dass es daran liegt, dass in der main mit Variablen gerechnet wird, die größer als 8bit sind. Problemlösung müsste dann sein, während der Rechnung die Interrupts abzuschalten.
Manuel schrieb: > Der Thread ist ja schon etwas älter, gibt es da inzwischen eine Lösung? Es gab ja nicht mal ein eindeutiges Problem. Oliver
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.