Forum: Mikrocontroller und Digitale Elektronik Output Compare Problem beim AVR


von Falk B. (falk)


Lesenswert?

Hallo liebe Gemeinde,

ich habe hier ein etwas kniffeliges Problem mit der Output Compare 
Funktion beim AVR. Benutzt wird ein ATmega328. Ich möchte zur Erzeugung 
es speziellen Steuersignals folgendes machen.

OCR1A und OCR1B sollen spezielle Pulse erzeugen. Dabei soll mittels 
OCR1A und der Einstellung "Clear on match" der andere IO-Pin OCR1B per 
CPU in der zugehörigen ISR gesetzt werden sowie über die reine 
Hardwarefunktion OCR1A gelöscht. Und das Ganze umgekehrt mit OCR1B.

Beispielsweise 1000 Takte nach dem aktuellen Zeitpunkt (in einer 
Funktion) soll OCR1A auslösen und in dem zugehörigen Interrupt soll das 
Pin zu OCR1B(!) per CPU auf HIGH gestetzt werden, die Hardware löscht 
OCR1A automatisch. Um das zu tun, muss man den Modus in TCC1A auf Normal 
stellen um dem Waveformgenerator abzukopplen und den normalen Zugiff auf 
das IO Pin per CPU zu ermöglich. Das geht soweit. ABER, nun das Problem.

Ich habe erwartet, dass beim Zurückschalten auf "clear on match" der 
Pegel vom IO-Pin erhalten bleibt. Tut er aber nicht! Sobald TCCR1A mit 
der Einstellung beschrieben wird, kippt das IO-Bit OCR1B zurück auf den 
alten (LOW) Pegel! Mist!

Wenn man ins Datenblatt schaut, Abschnitt 15.8, Figure 15-5 sieht man 
vereinfacht die Logik. Und es wird explizit gesagt

"The design of the Output Compare pin logic allows initialization of the 
OC1x state before the output is enabled."

Aber hier geht scheibar der Update bzw. die Synchronisation zwischen dem 
normalen PORT-Bit und der Kopie im Waveform Generator schief!

Hat jemand eine Idee, wie man das lösen kann? Wie kann man dem 
Waveformgenerator verclickern, dass er den aktuellen Zustand vom Pin 
übernehmen soll, damit beim Zurückschalten auf ihn der Pegel des IO-Pins 
erhalten bleibt? Ich hab schon mehrere nop() und Delays zwischen die 
verschiedenen Operation in der ISR eingefügt, leider ohne Erfolg.
Der Timer 1 läuft kontinuiertlich im Mode 0 mit /8 Taktteiler.
1
ISR (TIMER1_COMPA_vect) {
2
    
3
    TCCR1A = 0;
4
    PORTB |=  (1<<PB2);
5
    _delay_us(20);    
6
    TCCR1A = (1<<COM1A1) | (1<<COM1B1);     // mode 0, clear on COMPARE A/B
7
}

P.S. das delay ist nur drin, um den Puls auf dem Oszi besser zusehen.

Edit. Ein Workaround wäre, die IO-Pins immer per CPU zu schalten und die 
Clear FUnktion der Hardware nicht zu nutzen. Das habe ich schon gemacht, 
geht auch, ist aber etwas unschön und an einigen Stellen ungünstig. Das 
Clear per Hardware wäre schon eine feine Sache.

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

Hmmm, auch wenn Selbstgespräche manchmal kein gutes Zeichen sind, hier 
die Lösung.

Die Bits für die direkte IO-Steuerung per CPU und per Waveformgenerator 
sind vollständig getrennt und der Waveformgenerator wird NICHT irgendwie 
über einen CPU Schreibzugriff auf PORTx synchronisiert. Das war meine 
irrtümliche Annahme. Man kann das IO-Bit bei aktivem Waveformgenerator 
(COM1A0, COM1A1 Bits) nur per CPU steuern, indem man den passenden Modus 
setzt (clear, set, toggle) und ein FORCE Kommando über TCCR3C auslöst. 
Damit enfällt das Umschalten zwischen Normalmodus und Waveformmodus an 
den COMA/B Pins.
1
ISR (TIMER1_COMPA_vect) {
2
    
3
    TCCR1A = (1<<COM1B0) | (1<<COM1B1) | (1<<COM1A1) ;     // mode 0, set on COMPARE B, clear on COMPA
4
    TCCR1C = (1<<FOC1B);
5
    TCCR1A = (1<<COM1A1) | (1<<COM1B1);     // mode 0, clear on COMPARE A/B
6
}

P.S. Auch wenn es nicht so aussieht, aber ich habe an dem Problem schon 
reichlich 1 Tag gearbeitet, bevor ich das hier gepostet habe ;-)

von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

Falk Brunner schrieb:
> auch wenn Selbstgespräche manchmal kein gutes Zeichen sind

Ich hatte wohl das gleiche Problem und das entsprechende Projekt erstmal 
"auf Eis" gelegt.

Danke für Deine „Selbstgespräche”!

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
Noch kein Account? Hier anmelden.