ATtiny2313 CTC-Mode OC1A & OC1B gegenphasig toggeln

Gast #1323772
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
Gast #1323777
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
#1323778
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.
Gast #1323784
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
Gast #1323821
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

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