Forum: Mikrocontroller und Digitale Elektronik Simple Tonausgabe über PWM führt zu merkwürdigem Fehler


von rechteckmusiker (Gast)


Lesenswert?

Hallo,
ich versuche gerade "What is Love" als PWM-Rechtecksignal mit einem 
ATMega8 auszugeben. Das ganze ist mehr eine Art Konzepttest. Jetzt habe 
ich die Elektronik soweit aufgebaut, dass sie funktioniert (Tonleiter 
und so klingt ganz gut), nur der erste Takt vom Song macht Probleme.
1
#include <avr/io.h>
2
#define F_CPU 1000000
3
#include <util/delay.h>
4
#include <avr/interrupt.h>
5
6
7
/* avr-gcc -mmcu=atmega8 -Ostest.c
8
 * avr-objcopy -O ihex a.out source.hex
9
 * sudo avrdude -c avrisp2 -p m8 -U flash:w:source.hex
10
 * S. 98 in datasheet ist eine tabelle mit den konfigurationen für pwm
11
 * */
12
 
13
int calcICRforFrequeny(int frequency) {
14
  return F_CPU / (2*8*frequency);
15
}
16
17
void delay() {
18
  int i;
19
  for (i=0;i<100000;i++);
20
}
21
22
int main() {
23
  const int BPM = 120;
24
  const int lHalbe_ms = 1000;
25
  const int lViertel_ms = 500;
26
  const int lAchtel_ms = 250;
27
  DDRB = (1 << PB1); //PB1 als Output
28
  TCCR1A = (0 << COM1A1) | (1 << COM1A0) | (0 << WGM11) | (0 << WGM10); //CTC
29
  TCCR1B = (1 << CS11) | (0 << CS10) | (1 << WGM12) | (1 << WGM13); //Vorteiler und CTC
30
  cli();
31
  
32
  for (;;) {
33
    //Pause
34
    DDRB = 0;
35
    _delay_ms(lAchtel_ms);_delay_ms(lAchtel_ms);
36
    DDRB = (1 << PB1);
37
    //Note 1
38
    ICR1 =  calcICRforFrequeny(622);
39
    _delay_ms(lAchtel_ms);
40
    //Note 2
41
    ICR1 = calcICRforFrequeny(659);
42
    _delay_ms(lAchtel_ms);
43
    //Note 3
44
    ICR1 =  calcICRforFrequeny(622);
45
    _delay_ms(lAchtel_ms);
46
    //Note 4
47
    ICR1 = calcICRforFrequeny(739);
48
    _delay_ms(lAchtel_ms);_delay_ms(lAchtel_ms);
49
    
50
  }
51
  
52
  return 0;
53
}

Das spielt er auch ein paar Mal richtig ab, aber irgendwann fängt er 
komisch an zu stocken. Hört sich komisch an. So, als ob manchmal einfach 
der Sound weg wäre. Weiss jemand, was das sein könnte? Hängt das 
vielleicht mit _delay_ms zusammen?

von Frank (Gast)


Lesenswert?

Wie sieht die Schaltung aus?

von rechteckmusiker (Gast)


Lesenswert?

Ziemlich ähnlich zu der Schaltung aus dem Wiki 
(https://www.mikrocontroller.net/articles/Klangerzeugung#Tonausgabe) 
unter dem Stichpunkt PWM. Das ganze ist komplett auf einer 
Lochrasterplatine aufgebaut. Der ATMega8 wird über USB betrieben, der 
Impedanzwandler über eine Batterie

von S. Landolt (Gast)


Lesenswert?

Vorab: eine PWM kann ich hier nicht erkennen.
Zum Problem: in calcICRforFrequeny TCNT1=0; einfügen.

von S. Landolt (Gast)


Lesenswert?

PS
Zur Begründung: Was passiert, wenn ICR1 auf einen Wert gesetzt wird, der 
kleiner als der momentane Wert von TCNT1 ist? Timer1 läuft weiter bis 
65536 und fängt wieder bei 0 an, das dauert. Bei der Tonleiter kann das 
nicht passieren, diese ist streng monoton steigend.

von rechteckmusiker (Gast)


Lesenswert?

S. Landolt schrieb:
> Vorab: eine PWM kann ich hier nicht erkennen.

Ja, da hast du eigentlich recht. Wie würde man dies dann nennen? 
Signalgeneration im CTC Modus?

S. Landolt schrieb:
> Zur Begründung: Was passiert, wenn ICR1 auf einen Wert gesetzt wird, der
> kleiner als der momentane Wert von TCNT1 ist? Timer1 läuft weiter bis
> 65536 und fängt wieder bei 0 an, das dauert. Bei der Tonleiter kann das
> nicht passieren, diese ist streng monoton steigend.

Ich danke dir, das wird es sicherlich sein! Ich kann es gerade leider 
nicht mehr ausprobieren, aber das klingt sehr logisch.

von S. Landolt (Gast)


Lesenswert?

Errata:
65535 muss das heißen.
Das mit der Tonleiter ist falsch, sie selbst steigt zwar, aber damit 
sind die ICR-Werte fallend. Warum es trotzdem bei der Tonleiter 
funktioniert hat, weiß ich nicht.

von Audiomann (Gast)


Lesenswert?

vielleicht, weil die Werte im Nenner stehen?

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.