Forum: Mikrocontroller und Digitale Elektronik ATtiny2313 CTC-Mode OC1A & OC1B gegenphasig toggeln


von greenhorn (Gast)


Lesenswert?

Hallo zusammen,

ich möchte mit einem ATTiny 2313 Soundausgabe machen. Um eine grössere 
Laustärke zu erreichen, würde ich gerne die Ausgänge OC1A und OC1B um 
180 Grad phasenverschoben togglen lassen. Das bisher funktionierende 
Codefragment:
1
#define SOUNDON             TCCR1B = (1<<WGM12) | (1<<CS11);
2
3
void buzzer_init(void)
4
{                                                                               
5
    DDRB |= (1 << DDB3) | (1 << DDB4);
6
    TCCR1A = (1<<COM1A0) | (1<<COM1B0); // CTC, Toggle OC0A/OC0B on Compare Match
7
    SOUNDON;
8
    SOUNDOFF;
9
}
10
11
void sound ( unsigned int high, unsigned int duration )
12
{
13
    OCR1A = high;
14
    OCR1B = high;
15
    SOUNDON;
16
    _delay_ms (duration);
17
    SOUNDOFF;
18
}

Dieser Code funktioniert, allerdings ist die Ausgabe an OC1A & OC1B 
gleichphasig. Wie kann ich einem Ausgang jetzt "sagen", das er genau 
entgegengesetzt arbeitet?

Gruß

Greenhorn

von Gast (Gast)


Lesenswert?

Du kannst PB3/4 als normale Ausgänge betreiben.
PB3 setzt du im Zustand 1,PB4 auf 0.

Mit einen Timerinterrupt inventierst du immer die Portzustände.
Somit verändern sich beide zustände gleichzeitig.


Timer Interrupt:

com Portzustände
out PortB,Portzustände

reti

von Benedikt K. (benedikt)


Lesenswert?

Du könntest du mittels den FOC1 Bits einen Pin zu Beginn manuell 
toggeln. Danach wären beide immer gegenphasig.

Oder du könntest anstelle des CTC Modus aber den PWM Modus nutzen, einen 
der beiden Ausgänge invertieren, die Frequenz mittels ICR1 festlegen und 
OC1A und B jeweils auf die Hälfte von ICR1 setzen. Das wäre dann Mode 
14.

von greenhorn (Gast)


Lesenswert?

Hallo reti,

ja, schon, aber ich wollte das Ding eigentlich ohne Interrupt 
durchlaufen lassen.
Ich dachte mir ungefähr so, buzzer_init setze PB3 auf 1 und PB4 auf 0.
Timer startet und jetzt werden die Pins getoggelt. Das hat allerdings 
nicht funktioniert.

Gruß

Greenhorn

von greenhorn (Gast)


Lesenswert?

Hallo Benedikt,

habe ich halluzinationen oder hattest Du nicht gerade geschrieben das 
das mit dem FOC1 bit nur bei Timer0 funktioniert?

gruß

greenhorn

von Benedikt K. (benedikt)


Lesenswert?

Ja, ich hatte TCCR1C im Datenblatt übersehen.

von greenhorn (Gast)


Lesenswert?

Hallo nochmal,

danke an Benedikt für den Tip mit dem FOC1 Bit. Das wars, für alle die 
es interressiert nochmal die geänderte buzzer_init.
1
void buzzer_init( void )
2
{
3
    DDRB |= (1 << DDB3) | (1 << DDB4);
4
    TCCR1A = (1<<COM1A0) | (1<<COM1B0);// CTC, Toggle OC0A/OC0B on Compare Match
5
    TCCR1C = (1<<FOC1A);// OC1A wird einamlig "vorgetoggled"
6
    SOUNDON;
7
    SOUNDOFF;
8
}

Gruß

Greenhorn

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.