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?
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.
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.