Atmega32 Timer1 OCR1A künstlich auslösen

Gast #2498860
Lesenswert?

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?
Gast #2498925
Lesenswert?

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
Gast #2498942
Lesenswert?

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
Gast #2498971
Lesenswert?

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
Gast #2498976
Lesenswert?

@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.
Gast #2498986
Lesenswert?

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.
#2498995
Lesenswert?

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
#2499005
Lesenswert?

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.
Gast #2500165
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren