Simple Tonausgabe über PWM führt zu merkwürdigem Fehler

Gast #5153351
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?
Gast #5153394
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.
Gast #5153397
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.
Gast #5153433
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.

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