Timer 1, Mode 0 (Normal Mode). Wie löse ich sicher und schnell auf Wunsch einen CompA Interrupt aus? OCR1A = TCNT1+1 macht es ja offensichtlich nicht. Offensichtlich ist da der Timer schon weiter. Auch +5 reicht noch nicht. OCR1A = TCNT1+10 geht dagegen. Aber da muss es doch eine bessere Methode geben?
Hi
>Aber da muss es doch eine bessere Methode geben?
FOC1A in GTCCR setzen.
MfG Spess
Spess, danke, aber es gibt keinen GTCCR im Atmega32. Es gibt einen FOC1A im TCCR1A. Den hab ich schon probiert - der beinflusst zwar den WaveForm Generator, aber löst keinen Interrupt aus. Oder verstehe ich da etwas nicht richtig? Grüsse
Hi >Es gibt einen FOC1A im TCCR1A. Den hab ich schon probiert - der >beinflusst zwar den WaveForm Generator, aber löst keinen Interrupt aus. >Oder verstehe ich da etwas nicht richtig? Entschuldige ich hatte das falsche Datenblatt erwischt. Was willst du denn machen? Die Interruptroutine ausführen? MfG Spess
Das Bit lässt sich per Software nur löschen (durch schreiben einer 1), nicht setzen. Falls es keine Rolle spielt, dass der Timerstand verändert wird: TCNT1=OCR1A; müsste eigentlich immer funktionieren. Nicht schön, zugegeben.
Hi
>Das Bit lässt sich per Software nur löschen (durch schreiben einer 1),
Welches?
MfG Spess
Ich möchte ein bestimmtes Protokoll mit einem definierten Timing erzeugen auf einem Bus. Ich lasse jetzt mal einige Infos weg, sonst wirds zu lang: In Kürze: Ein Startbit wird benötigt. Dies ist immer null. 1) Dazu setze ich die OC1A auf low (also den Ausgang auf low), setze den OCR1A auf TCNT+6 (ab 6 gehts). 2) Dann geht der uC ab in die ISR, dort wird OCR1A auf den Ablaufwert für das null-bit gesetzt (34us) und der Ausgang OC1A auf high konfiguriert, so dass er nach den 34us wieder high ist. Diese 34us werden in der ISR umgeschaltet auf andere Zeiten, daher dieser Ansatz. Hat jetzt aber mit dem Problem nichts zu tun. Dieses OCR1A = TCNT+6 scheint einfach unelegant, da von der Laufzeit abhängig. Offensichtlich muss man dem OCR1A 6 Takte Vorlauf geben, damit der Timer den Befehl nicht 'überholt'. Daher die Überlegung, dass es da (ähnlich FOC1) etwas besseres geben müsste - eigentlich. Grüsse
@Joachim - spielt leider eine Rolle. Es läuft auch noch ein Capture-ISR und ein Lese-ISR auf CompB, zum Lesen vom Bus und zur Konflikterkennung (CSMA). Dafür brauche ich (glaube ich) den Timerstand.
hm... bliebe noch die "brutale" Methode: #asm ("cli") #asm ("rcall timer1_compa_isr") Auch nicht das, was den smarten Programmierer zum Jubeln bringt...
Korrekt. TIFR.OCF1A lässt sich leider nicht zum auslösen des Interrupts verwenden. Ich glaube fast langsam, es geht einfach nicht. OCR1A = TCNT+<Laufzeit-Delta> scheint nötig. Das scheinen die 6 Takte zu sein. Das unschöne ist, diese 6 Takte führen dann zusammen mit dem Overhead des ISR zu ca einer us verlängerter 0-Zeit beim ersten Aufruf. Kann man zwar wegkorrigieren, aber suche noch nach einer eleganteren Lösung. Im Grunde modifizierte ich hier Peter Danneggers suart Lösung. Er umgeht das Problem, indem er halt einfach eine unbestimmte Zeit wartet, bis der Timer auslöst und macht dann auch das Startbit im Timer. Diese unbestimmte Zeit ist aber in meinem Fall wieder störend.
Hmm, ja - zumindest ein interessanter Ansatz. Danke Euch einmal soweit. Jetzt gehts erstmal ins Bett. Mal sehen was morgen noch so an Ideen reintrudeln mag. Grüsse
Jalu schrieb: > Im Grunde modifizierte ich hier Peter Danneggers suart Lösung. Er umgeht > das Problem, indem er halt einfach eine unbestimmte Zeit wartet, bis der > Timer auslöst und macht dann auch das Startbit im Timer. Es wird immer mit der Bitzeit synchronisiert, wie bei einer HW-UART auch. Wenn man die Bytes hintereinander sendet, wird garnicht gewartet, d.h. das nächste Startbit kommt genau hinter das vorherige Stopbit. Peter
Hm, da stecke ich nicht drin, keine Ahnung. Kann sein, dass das alles gar kein Problem ist Obige Lösung würde jedenfalls funktionieren. Könnte natürlich passieren, dass in der Zeit tatsächlich ein OCR1A-Ereignis eingetreten ist (und damit direkt nach reti erneut ein dann ungewollter Interrupt ausgelöst wird). Wenn du das behandelst, dürfte das Vorgehen sauber sein.
@Peter, ja, von bit zu bit schon. Was ich meinte, war der Start. Da kann es ja unterschiedlich lange dauern, bis der Transfer anspringt. Du wirst sagen, na und. Ich habe vor dem Startbit eine bestimmte Anzahl von Bitzeiten, die der Bus frei sein muss, bevor ich anfangen darf zu senden. D.h. es ist einfacher, mit einem OCR1A Interrupt zu beginnen, da ich dann direkt nach diesem Vorlauf von x Bitzeiten in die TX Routine springen kann und nur einen minimalen und definierten Zeitversatz habe. Grüsse PS: Nun gut, Du wirst jetzt vermutlich weiterhin sagen, diesen Vorlauf auch in der gleichen ISR Routine abzuwickeln - dieser Gedanke kommt mir gerade. Dann ist 'Vorlauf' und 'Senden' perfekt syncronisiert. Könnte man ja von einem 'State' abhängig machen und in einer Switch-Anweisung abhandeln. Mal sehen.
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.