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

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.