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?
PWM ändert, wie der Name schon sagt, nur das Tastverhältnis, die Freuqenz bleibt gleich. Die du unterschiedliche Tonhöhen haben willst musst du das anders machen, z.B. CTC Mode
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.
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? ;-)
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; }
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.
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
Habe jetzt noch TIMSK |= (1 << OCIE1A); hinzugefügt, aber das half leider auch nichts :-(
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 | }
|
Marcel wrote:
> yep, hab ich....
Und?
Zeigst du jetzt endlich mal dein Programm so wie es jetzt ist,
oder sollen wir weiter raten, was eventuell nicht stimmen könnte?
Da fällt mir gleich mal auf ISR(TIMER1_COMPA) Der Name des Interrupts ist falsch. Interrupt Namen enden immer auf '_vect', also kann das schon mal nicht TIMER1_COMPA heissen.
TCCR1B = (1<<WGM12)|(1<<WGM13)|(1<<CS12); TIMSK |= (1 << OCIE1A); OCR1A = 0x0015; Wenn du WGM12 und WGM13 setzt, dann gilt als Topwert nicht OCR1A sondern ICR1. Quelle: Siehe Datenblatt
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.