Forum: Mikrocontroller und Digitale Elektronik Melodiengong


von Florian S. (didi34)


Lesenswert?

Ich habe folgendes Programm programmiert, welches sechs Töne 
nacheinander in aufsteigender Tonleiter auf einem Lautsprecher ausgeben 
soll, jedoch kommen nur Tiefe und Hohe Töne durcheinander aber nicht 
nach der reihe. Was mache ich falsch?
1
/*
2
 * melodiengong.c
3
 *
4
 * Created: 01.10.2012 13:56:27
5
 *  Author: Florian
6
 */ 
7
8
#define F_CPU 8000000
9
#include <avr/io.h>
10
#include <util/delay.h>
11
#include <math.h>
12
#include <avr/interrupt.h>
13
14
#define int overflow=0,i=1;
15
16
17
void sleep ( uint8_t ms )
18
{
19
  for(; ms > 0; ms--) _delay_us(1);
20
}
21
22
void melodie_spielen(float periode)
23
{
24
    DDRB = 0xff;
25
    PORTB |= (1<<PB2);// high halbe Periodendauer
26
    sleep(periode/2);  
27
    PORTB &= ~(1<<PB2);// low halbe Periodendauer
28
    sleep(periode/2);
29
      
30
    
31
}
32
int main(void)
33
{
34
  sei();
35
  TIMSK = (1<<TOIE0);
36
  TCCR0 = (1<<CS02);
37
  TCNT0 = 0x00;
38
  while(1)
39
  {
40
    while(i==1)
41
    melodie_spielen(3370);
42
    while(i==2)
43
    melodie_spielen(3370);
44
    while(i==3)
45
    melodie_spielen(3030);
46
    while(i==4)
47
    melodie_spielen(2840);
48
    while(i==5)
49
    melodie_spielen(2525);
50
    while(i==6)
51
    melodie_spielen(2273);
52
    }  
53
    return 0;
54
  }
55
56
ISR(TIMER0_OVF_vect) // Timer interrupt
57
{
58
  if(overflow <=61)
59
  {
60
    overflow++;
61
  }
62
  else
63
  {
64
    if(i==6)
65
    {
66
      i=1;
67
    }
68
69
    else
70
    {
71
      i=i+1;
72
    }    
73
      overflow = 0;
74
  }
75
}

von avr (Gast)


Lesenswert?

Florian Schuller schrieb:
> void sleep ( uint8_t ms )
> {
>   for(; ms > 0; ms--) _delay_us(1);
> }

Wann wird ms wohl kleiner 0 sein...

von avr (Gast)


Lesenswert?

Florian Schuller schrieb:
> #define int overflow=0,i=1;

Das #define ist auch sinnlos...

Außerdem fehlt hier ein volatile.

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

avr schrieb:
> Wann wird ms wohl kleiner 0 sein...

Muß es nicht, gleich null reicht ja ...

von loeti (Gast)


Lesenswert?

Sollte da nicht _delay_ms() aufgerufen werden?

von Florian S. (didi34)


Lesenswert?

>Sollte da nicht _delay_ms() aufgerufen werden?

Nein die Periodendauer wird in microsekunden angegeben

von avr (Gast)


Lesenswert?

Joachim Drechsel schrieb:
> avr schrieb:
>> Wann wird ms wohl kleiner 0 sein...
>
> Muß es nicht, gleich null reicht ja ...

stimmt da war ich wohl selbst blind.

von Walter (Gast)


Lesenswert?

lässt sich das überhaupt compilieren mit dem komischen define?
sollte da nicht i undefiniert sein.

float braucht man hier auch nicht!

von Bernhard S. (b_spitzer)


Lesenswert?

Das kann so nix werden. Erstmal was über Datentypen in C nachlesen!!
1
void sleep ( uint8_t ms )
Erwartet 8-Bit Werte (1 Byte, 0-255)
1
void melodie_spielen(float periode)
Hätte eigentlich gerne Fleißkommazahlen (4Byte...)
1
sleep(periode/2);
Ruft dann obige Funktion auf, die nur bis 255 funktioniert,
1
melodie_spielen(3370);
Ruft die Funktion mit einem 16-Bit (2 Byte) Ganzzahl-Wert auf, der 
halbiert aber immer noch viel zu groß für sleep() wäre....

Dabei macht der Compiler munteres Byte-Raten und packt Dir die unteren 8 
Bit des Wertes in den Übergabewert von sleep().

von Achim M. (minifloat)


Lesenswert?

Florian Schuller schrieb:
> float periode
Florian Schuller schrieb:
>     sleep(periode/2);

Und schon wird ein Typ implizit gewandelt. uint16_t hätte es auch getan. 
Das muss auch nicht erst kompliziert emuliert werden, bläst den Code 
nicht auf, verbraucht weniger Rechenzeit und Flashspeicher.

Ganz gewiefte Jungs und Mädels machen die Tonerzeugung über zwei Timer. 
Einer macht die Töne, einer macht die Dauer.

von avr (Gast)


Lesenswert?

Joachim минифлоть schrieb:
> Ganz gewiefte Jungs und Mädels machen die Tonerzeugung über zwei Timer.
> Einer macht die Töne, einer macht die Dauer.

Wobei der Aufwand dann schon DDS übersteigt. Mit DDS ist es dann auch 
spielend leicht mehrere Töne gleichzeitig abzuspielen.

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.