Forum: Mikrocontroller und Digitale Elektronik TIMER0 "fast PWM" Frage zu höherer Frequenz bei geringerer Auflösung


von StefanK (stefanka)


Lesenswert?

Hallo,

wie kann ich eine möglichst hohe PWM-Frequenz erzeugen, wenn ich dafür 
die Auflösung opfere?

Der ATtiny13 (Target) schafft mit seinem internen Oszillator 9,6MHz. 
Daraus ergibt sich bei 256bit Auflösung eine PWM-Frequenz von 37,5kHz.

Angenommen, es reicht eine Auflösung von z.B. 128Bit. Damit käme man auf 
75kHz. Nur wie realisiere so ich ein PWM-Signal?

Wie muß ich die Register bedaten? Was ist per SW zu tun, z.B. in der 
Interrupt-Routine?

TCCR0A = ??? (1 << COM0A0) | (1 << WGM01);  // CTC Modus 2, bei 
CompMatch wird TCNT0 resettiert und OC0A-Pin getoggelt;
TIMSK0 = (1 << OCIE0B);                     // Interrupt enable für 
OCR0B CompMatch
OCR0A  = 128;                               // Periodendauer des 
PWM-Signals
OCR0B = duty;                              // Dauer der Hi-Phase des 
PWM-Signals

//TIMER0 starten
TCCR0B = TCCR0B = (1 << CS00);             // CS00 bit für prescaler=1
OC0A-Pin = 1;                              // PWM starten

ISR(TIMER0_COMPB_vect)
{
   OC0A-Pin = 0; // PWM-Pin invertieren
}

Würde das grundsätzlich funktionieren, oder gibt es eine bessere 
Methode, PWM mit unterschiedlichen Auflösungen und Frequenzen zu 
erzeugen?

von S. L. (sldt)


Lesenswert?

Modus 7; ISR ist unnötig bzw. sinnlos.

von Achim M. (minifloat)


Lesenswert?

StefanK schrieb:
> 256bit

Ne, nur 8bit, respektive 7bit.

StefanK schrieb:
> ISR(TIMER0_COMPB_vect)
> {
> OC0A-Pin = 0; // PWM-Pin invertieren
> }

Ne, das Invertieren musst du per Register einstellen.

StefanK schrieb:
> Wie muß ich die Register bedaten?

Es gibt einen Modus, wo TCCR das Maximum definiert und OCR0x bei compare 
match nicht toggeln, sondern den jeweiligen Pin Setzen bzw. Rücksetzen. 
Rücksetzen bzw. Setzen kommt automatisch beim Umsprung des Timers auf 0. 
Steht alles im Datenblatt.

StefanK schrieb:
> Was ist per SW zu tun, z.B. in der Interrupt-Routine?
Na deinen neuen OCR0x schreiben. Beim Umsprung des Timers auf 0 wird der 
in ein Schattenregister geladen, womit zwar deine OCR0x erst in der 
nächsten Periode verwendet werden, dafür hast du eine Race-Condition per 
Hardware aufgelöst.

mfg mf

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

StefanK schrieb:

> Angenommen, es reicht eine Auflösung von z.B. 128Bit. Damit käme man auf
> 75kHz. Nur wie realisiere so ich ein PWM-Signal?

Niemals nicht. Du meinst entweder eine Auflösung von 128 diskreten 
Zuständen oder (gleichbedeutend) eine von 7 Bit. Damit wären dann die 
ca. 75kHz erreichbar. "128 Bit" ist einfach Unfug.

> Wie muß ich die Register bedaten? Was ist per SW zu tun, z.B. in der
> Interrupt-Routine?

Kann man machen. Aber gerade bei der Registeraktualisierung gibt es 
Fallstricke zu beachten. Nicht in jedem Timer-Modus ist eine sichere 
Aktualisierung durch gepufferte Register verfügbar. Das gilt 
insbesondere für die Änderung der Frequenz. Duty hingegen ist typisch in 
allen PWM-Modi gepuffert.

> OCR0A  = 128;                               // Periodendauer des

Das sollte übrigens lauten: "OCR0A = 127", wenn 7 bit bzw. 128 Stufen 
angestrebt werden.

> Würde das grundsätzlich funktionieren

Natürlich.

> oder gibt es eine bessere
> Methode, PWM mit unterschiedlichen Auflösungen und Frequenzen zu
> erzeugen?

Nur für die Timer1/3 der klassischen AtMega oder für die D-Type-Timer 
der neueren Baureihen. Da sind auch gepufferte Frequenzänderungen 
möglich.

von StefanK (stefanka)


Lesenswert?

Modus 7 also, OK danke. Das mit den 256bit sollte natürlich 256 
Inkremente heissen, klar.

Das PWM-Signal soll für die Dauer von OCR0B hi sein und bei Compare 
Match mit OCR0B auf lo gehen. Bei Compare Match von OCR0A soll der 
PWM-Pin wieder auf hi gehen, der TCNT0=0 und eine neue Periode gestartet 
werden.

Wie muß ich TCCR0B und TCCR0B für Modus 7 bedaten?

von Achim M. (minifloat)


Lesenswert?

Ob S. schrieb:
> Da sind auch gepufferte Frequenzänderungen möglich.

Oops! Danke für die Klarstellung.
Das würde bedeuten, dass man vor OCR0x beschreiben den Timer anhalten 
muss, gucken ob er schon da war und den neuen Wert oder eben direkt den 
Ausgang beschreiben muss. Danach den Timer wieder starten... Puuuh...

mfg mf

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Achim M. schrieb:

> Oops! Danke für die Klarstellung.
> Das würde bedeuten, dass man vor OCR0x beschreiben den Timer anhalten
> muss, gucken ob er schon da war und den neuen Wert oder eben direkt den
> Ausgang beschreiben muss. Danach den Timer wieder starten... Puuuh...

Nö. Das wäre ja bezüglich der Auswirkungen noch schlimmer als als der 
Fehler durch ungepufferte Periodenregister. Praktisch wohl fast 
unbrauchbar.

von S. L. (sldt)


Lesenswert?

an StefanK:
Dies ist für einen ATtiny85 (und in Assembler) - auf Ihre Verhältnisse 
umsetzen müssen Sie selbst, aber das Prinzip sollte klar werden.
1
    sbi     DDRB,1                                  ; OC0B: PWM-Pin auf Ausgang
2
    puti    OCR0A,128 -1                            ; TOP
3
    puti    OCR0B,76                                ; duty
4
    puti    TCCR0A,(1<<COM0B1)|(1<<WGM01)|(1<<WGM00); PWM, Modus 7
5
    puti    TCCR0B,(1<<WGM02)|(1<<CS00)             ; /1
6
7
main_loop:
8
  rjmp      main_loop

von StefanK (stefanka)


Lesenswert?

jetzt ist vieles klarewr. Danke an alle!

von Rick (rick)


Lesenswert?

Falls es mal eine Schippe mehr sein darf, die Tiny 25/45/85 haben eine 
PLL, die 64 MHz erzeugt (PCK) um Timer1 zu takten.
Damit sind 500 kHz PWM-Frequenz (bei 7 Bit) machbar.
Mit 8 Bit Auflösung reicht es noch für 250 kHz...

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Rick schrieb:
> Falls es mal eine Schippe mehr sein darf, die Tiny 25/45/85 haben eine
> PLL, die 64 MHz erzeugt (PCK) um Timer1 zu takten.
> Damit sind 500 kHz PWM-Frequenz (bei 7 Bit) machbar.
> Mit 8 Bit Auflösung reicht es noch für 250 kHz...

Ja, das habe ich z.B. hier

Beitrag "Westminster Soundgenerator mit ATtiny85"

benutzt.

Aber: An der PWM-Frequenz würde ich da nicht zur Laufzeit herumfummeln 
wollen...

von Georg M. (g_m)


Angehängte Dateien:

Lesenswert?

Bei den aktuellen AVR-Mikrocontrollern muss kein PWM-Kanal für die 
Periode geopfert werden.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Georg M. schrieb:

> Bei den aktuellen AVR-Mikrocontrollern muss kein PWM-Kanal für die
> Periode geopfert werden.

Es ging nicht darum, möglichst viel PWM-Käle zu haben, sondern darum, 
einen  möglichst schnellen zu haben.

Falls dir das nicht aufgefallen ist...

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.