PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Stufenlos PWM-Frequenz einstellen



Sebastian132
05.06.2006, 00:05
Hallo! Ich baue gerade eine Countdown-Uhr und bin ein bisschen am ausprobieren mit einem Piezo-Piepser. Nun folgende Frage:

Mit welchen Bits kann ich die Tonhöhe stufenlos variieren (will eine Art amerikanische Polizeisirene realisieren)?
Gut, ich kann mit der relativ groben Vorteiler-Einstellung meines Timers den Rahmen vorgeben. Dann kann ich noch mit dem OCR1A das Puls-Pause-Verhältnis ändern, was jedoch nichts an der eigentlichen Tonhöhe ändert.
Nun habe ich noch gelesen, dass TCNT1L / TCNT1H die Überlaufgrenzen festlegt. Doch auch hier höre ich keinen Unterschied... hier mal mein Test-Code



#include <avr/io.h>
#include <avr/delay.h>




int main ()
{
DDRD=0xFF;

TCCR1A |= (1<<COM1A1)|(1<<PWM10)|(1<<PWM11); //nicht invertierte 10Bit-PWM
TCCR1B |= (1<<CS11); //clk/8 Timerfrequenz
uint16_t i;

OCR1A=128; //Puls-Puase-Verhaeltnis 1:1 (Output Comp. Reg.)

TCNT1L=1;





for(;;){

for(i=0;i<=1023;i++){

TCNT1H=i; //da ändert sich nichts hörbares?

_delay_ms(20);

}
}

}

Gruß,
Sebastian

Sebastian132
05.06.2006, 14:08
Hmm ist das so ein exotisches Problem? Ich habe noch mal hier http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Die_PWM-Betriebsart geschaut, und habe mit den genannten Bits OCR1AH /*L und dem TCNT1H/*L gespielt, aber man hört keine Unterschiede :(.

Kaiser-F
05.06.2006, 14:22
Hi,

Eventuell mit dem PWM-Mode, bei dem man TOP variieren kann ?

Sebastian132
05.06.2006, 14:58
So, ich habs nun :). Im PWM-Mode kann man generell nur das Puls/Pause-Verhältnis regeln (sprich die effektiv herauskommende Gleichspannung). Stufenlose Frequenzänderung ist NICHT vorgesehen. Das macht man am besten im CTC1-Mode und normalem Timer z.B. so ;)
(PP-Verhältnis ist dabei fest 1:1)


#include <avr/io.h>
#include <avr/delay.h>
#include <avr/interrupt.h>




int main ()
{
DDRD=0xFF;

TCCR1A |= (1<<COM1A0); //nicht invertierte 10Bit-PWM
TCCR1B |= (1<<CS11)|(1<<CTC1); //clk/8 Timerfrequenz
uint16_t i;


cli();





for(;;){

for(i=10;i<=5000;i++){
OCR1A=i;

_delay_ms(1);
if (i==4990)
i=0;

}
}

}

Hanni
05.06.2006, 15:05
So, ich habs nun :). Im PWM-Mode kann man generell nur das Puls/Pause-Verhältnis regeln (sprich die effektiv herauskommende Gleichspannung). Stufenlose Frequenzänderung ist NICHT vorgesehen.

Das ist so nicht richtig.

Es gibt durchaus PWM Modi, in denen man den maximalen Zählerstand selbst definieren kann.

Grüße,

da Hanni.

Sebastian132
05.06.2006, 15:35
Hm, so wurde mir das zwar erzählt, aber muss ja nicht stimmen ;). Aber rein interessehalber, wie gehts denn? CTC1 hat laut MC.net-Tutorial keine Wirkung im PWM-Mode. Und wiegesagt, das selberdefinieren diverser Überlaufgrenzen brachte bei mir 0 :(.

blofeld486
10.06.2006, 14:58
Hallo Sebastian!

Welchen Prozessor verwendest du denn?
Beim AT90s8515 ist der Überlaufwert der Timer/Zähler z.B nicht einstellbar.
Beim ATmega8 un anderen 'megas' aber kannst du die obere Grenze in einigen Modi im Register ICR1H/ICR1L einstellen. Um dabei ein Tastverhältnis von 1 zu erreichen sollte OCR1 immer mit ICR1 geteilt durch zwei geladen werden.

Alternativ könntest du den TimerOverflow-Interrupt dazu benutzen, um bei jedem Durchlauf den Zähler/Timer auf einen definierten Startwert zu schreiben.
Viel Erfolg!

Gruß, Claus