PWM Sinus 440 Hz funktioniert nicht

Gast #1232001
Lesenswert?

Hallo

ich habe hier einen ATmega8 @ 16 Mhz.


Mit diesem möchte ich ein 440 Hz Sinussignal per PWM ausgeben.

Timer 2 ist auf fast PWM geschaltet.

Es wird vorher eine Tabelle mit 20 verschiedenen Sinuswerten berechnet.


Der Timer1 COMPA Interrupt gibt der PWM jeweils den nächsten berechneten 
Sinuswert. Dieser Interrupt wird alle T=1/(440Hz*20 Schritte) ausgelöst.

Somit sollte an OC2 ein 440 Hz Sinussignal anliegen.

Leider habe ich kein Scope hier sondern nur einen Lautsprecher. Der 
Ausgang geht an 2 Transistoren (Endstufe) und von dort aus an den 
Lautsprecher. Es ist nichts zu hören.


Vielleicht kann mit ja jemand von euch helfen. Ich bedanke mich schonmal 
im vorraus.


Hier der Code:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <math.h>
4

5
#define pi 3.1415926
6

7
void init(void);
8

9
unsigned int anzahlWerte=20;
10
unsigned char sinusWerte[20];
11

12
unsigned int step=0;
13

14
ISR(TIMER1_COMPA_vect)
15
{
16
    OCR1AL=sinusWerte[step];
17
  step++;
18
  if(step==20) step=0;
19
}
20

21

22

23
int main(void)
24
{
25

26
  init();
27
  while(1);
28
  return 0;
29
}
30

31
void init(void)
32
{
33
  int i;
34
  for(i=0;i<anzahlWerte;i++)
35
    sinusWerte[i]=(unsigned char)(127.5+127.5*sin(2.0*pi*i/anzahlWerte));
36
  DDRB=0b00001000;    // PWM Ausgang OC2
37
  TCCR2=(1<<WGM21)|(1<<WGM20)|(1<<COM21)|(1<<CS20);  // Fast PWM, non invertig mode, no prescaler
38
  OCR2=128;  // Lautsprecher aus: PWM auf 50%
39
  
40
  TCCR1A=(1<<WGM12);  // CTC
41
  TCCR1B=(1<<CS11);  // CLK/8
42
  OCR1AL=227;      // Entspricht Sinus mit ca 440 Hz
43
  sei();
44
}
Gast #1232035
Lesenswert?

So, noch ein Fehler; ich hatte den Interrupt nicht aktiviert.


TIMSK=(1<<OCIE1A);


habe ich in der init() Funktion hinzugefügt.

Der Ausgang wird an einer LED getestet und es leuchtet mit ca 1,5 Hz.


Um diesen jetzt auf 440 Hz zu bringen muss TCNT1 beim Aufruf des 
Interrupt resettet werden.


Ich dachte dies würde durch
1
TCCR1A=(1<<WGM12);  // CTC
 passieren. Leider macht ers nicht. Vielleicht kann mir jemand sagen was 
ich falsch gemacht habe?
Gast #1232081
Lesenswert?

Hallo! Danke soweit.

Hab alles umgeändert. Ändert aber nichts daran, dass TCNT1 nicht 
gelöscht wird. Ich bin soweit der 440 Hz Ton ausgeben zu können:

ISR(TIMER1_COMPA_vect)
{
  TCNT1=0;
    OCR2=sinusWerte[step];
  step++;
  if(step==20) step=0;
}


Ich dachte durch das

TCCR1A=(1<<WGM12);  // CTC

wäre TCNT1=0; unnötig. Leider wird TCNT1 nur gelöscht wenn ich es selber 
in den Interrupt reinschreibe. Dann sind auch die 440 Hz zu hören.

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