PWM - OCR1A ändert nichts?

Gast #718754
Lesenswert?
• ▲
▼
Hallo!
Ich versuche gerade per PWM Töne auf einem Lautsprecher zu erzeugen. Die 
Tonhöhe würde ich dabei gerne über den OCR1 Wert verändern (Benutze 
einen ATMega16 und Timer1).

So initialisiere ich den Timer:

TCCR1A = (1<<WGM11)|(1<<WGM10)|(1<<COM1A1);
TCCR1B = (1<<CS11) ;
OCR1A = 0x0515;

Aber egal was ich in OCR1A schreibe, der Ton bleibt immer der gleiche 
:-(
Woran kann das liegen?
#718772
Lesenswert?
• ▲
▼
Marcel wrote:
> Was genau ist denn der CTC Mode?

CTC
Clear Timer on Compare

Bei erreichen eines bestimmten Zählerstandes, den du vorgeben
kannst, wird der Timer wieder auf 0 gesetzt.

> Im AVR GCC Tutorial kann ich da auf
> anhieb nix finden :-(

Dann wirds Zeit den mal auszuprobieren. CTC funktioniert fast
so wie der Overflow eines Timers. Nur dass du die Zahl vorgibst
an der dieser 'Overflow' ausgelöst werden soll, bei der
der Timer wieder auf 0 gesetzt wird. Ach ja. Der Interrupt
heist auch anders.

PS: Im AVR Gcc Tutorial wirst du über viele Bereiche deines
Prozessors nichts finden. Deshalb ist es auch so wichtig,
das Datenblatt seines Prozessors zur Hand zu haben. Dieses
Datenblatt kann man bei Atmel downloaden.
Gast #718779
Lesenswert?
• ▲
▼
Interrupt hab ich bisher garnicht benutzt, da gibt es ja einen extra 
output pin für's PWM.
Heißt das also ich mach jetzt einen Interrupt in dem ich einen 
bestimmten Pin umschalte, und stelle dann ein wie oft dieser Interrupt 
aufgerufen wird?
Hab ich das richtig verstanden? ;-)
Gast #718796
Lesenswert?
• ▲
▼
So, habe mal im Datenblatt nachgesehen. Leider kommt jetzt garnichts 
mehr aus dem Speaker (der nun an PortB hängt).
Hier die Timerinitialisierung:

TCCR1B = (1<<WGM12)|(1<<WGM13)|(1<<CS12);
OCR1A = 0x0015;

Und der Interrupt:

ISR(TIMER1_COMPA)
{
    PORTB = 255-PORTB;
}
#718797
Lesenswert?
• ▲
▼
Marcel wrote:
> Interrupt hab ich bisher garnicht benutzt, da gibt es ja einen extra
> output pin für's PWM.

Schon. Aber PWM macht ja ganz was anderes.

> Heißt das also ich mach jetzt einen Interrupt in dem ich einen
> bestimmten Pin umschalte, und stelle dann ein wie oft dieser Interrupt
> aufgerufen wird?
> Hab ich das richtig verstanden? ;-)

So in etwa könnte man das sagen.
Du schreibst eine ISR (eine Interrupt Service Routine).
Diese ISR wird aufgerufen, wenn bestimmte Bedingungen
oder Ereignisse eintreten. Ein derartiges Ereignis ist
zb. das der Timer seinen vorgegebenen Wert erreicht hat
und jetzt auf 0 zurückgesetzt wird.

Darüber müsste es im Gcc Tutorial aber einen Abschnitt
geben.
#718801
Lesenswert?
• ▲
▼
Marcel wrote:
> So, habe mal im Datenblatt nachgesehen. Leider kommt jetzt garnichts
> mehr aus dem Speaker (der nun an PortB hängt).
> Hier die Timerinitialisierung:
>
> TCCR1B = (1<<WGM12)|(1<<WGM13)|(1<<CS12);
> OCR1A = 0x0015;
>
> Und der Interrupt:
>
> ISR(TIMER1_COMPA)
> {
>     PORTB = 255-PORTB;
> }

Da fehlt aber noch einiges.
Es gibt in einem AVR viele Interrupt Quellen. Du musst also
entscheiden welche Interrupts zugelassen werden und welche
nicht. Und du musst die Interrupts generell freigeben.

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmieren_mit_Interrupts
#718822
Lesenswert?
• ▲
▼
Marcel wrote:
> Habe jetzt noch
>
> TIMSK |= (1 << OCIE1A);
>
> hinzugefügt, aber das half leider auch nichts :-(

hast du einen
1
  sei();
gemacht?
1
...
2

3
int main()
4
{
5
   ....
6
   .... alles initialisieren
7
   ....
8

9
   sei();   // ab jetzt können Interrupts zuschlagen
10

11
   while( 1 ) {
12
      ....
13
   }
14
}

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