Forum: Mikrocontroller und Digitale Elektronik Kanon erzeugen auf dem Microcontroller Atmel T89C51RC2


von Daniel H. (tales404)


Lesenswert?

Hallo Jungs...


Ich muss für die Schule mit meinem Microcontroller einen Kanon(eine 
Abfolge von selbsterzeugten Töne, die 2mal zeitversetzt abläuft) in
Assembler erzeugen...

Leider weiss ich nicht welcher controllertyp dieser genannte 
Microcontroller ist, konnte ich auch nicht herausfinden...(bisher wusste 
ich nichtmal dass es verschiedene typen gibt...)

Das Problem ist, ich weiss noch nicht so wirklich wie ich das mache...

Also mache ich das mit Timer? oder register die ich runterzähl?

Als Lautsprecher dachte ich nehme ich einen normalen Kopfhörer... eben 
die drähte dann an die pins.. sollte so gehen oder? brauche ich da noch 
einen widerstand dafür?


Für jede Hilfe bin ich sehr sehr dankbar...

Tales...

von Achim M. (minifloat)


Lesenswert?

Daniel Hennig schrieb:
> Also mache ich das mit Timer? oder register die ich runterzähl?

Mit Timer wäre natürlich sehr elegant. Allerdings bräuchtest du schon 
zwei Timer, um auch zwei verschiedene Töne zu erzeugen. Es sei denn, die 
Timer laufen schnell genug.
Register runterzählen geht natürlich auch, aber wenn du nun schon weißt, 
dass der Prozessor in Hardware Register runterzählen kann(manche Leute 
nennen das auch Timer)... :)


Daniel Hennig schrieb:
> Als Lautsprecher dachte ich nehme ich einen normalen Kopfhörer... eben
> die drähte dann an die pins.. sollte so gehen oder? brauche ich da noch
> einen widerstand dafür?
32Ω-Kopfhörer an 5V ergibt mit Sicherheit ein bisschen Qualm oder 
zumindest kaputte Kopfhörer. Ich würde schon einen Widerstand 
zwischenschalten. Schau dazu nach
a)wieviel Strom die Ports können
b)wieviel Leistung man an den 32Ω umsetzen kann(Links 32Ω, Rechts 32Ω. 
Üblicherweise werden 1mW für ein im Kopfhörer erlebbares Ergebnis voll 
ausreichen. Oder du schlachtest eine dudelnde Grußkarte, der Piezo 
braucht keinen Vorwiderstand).

mfg mf

von Daniel H. (tales404)


Lesenswert?

Danke für die schnelle Antwort...

Also wie mach ich das denn dann mit einem Timer?? denn die Warteschleife 
gibt ja den Ton an, in welcher frequenz er gespielt wird...

muss ich denn das unterprogramm warte einfach nach cpl per Timer callen 
oder wie?



Hmm wie find ich das dann heraus wieviel widerstand ich brauch? und wie 
bekomm ich raus wie viel volt mein Kopfhörer hat, also der Mc hat 
angeblich 5V.

Die Daten die ich über mein Kopfhörer rausfinden konnte waren folgende:

Nennimpedanz: 32 Ohm
Empfindlichkeit: 125 dB/V

weiss nicht ob das 2 das richtige ist oder vlt auch was völlig Anderes?

Mein Lehrer meinte auch ich könnte den aus nem Radiowecker nehmen... 
außerdem meinte er auch, dass das eigentlich fast immer die selben 
Widerstände sind die man für solche lautsprecher braucht...


Tales

von Achim M. (minifloat)


Lesenswert?

Daniel Hennig schrieb:
> Also wie mach ich das denn dann mit einem Timer?? denn die Warteschleife
> gibt ja den Ton an, in welcher frequenz er gespielt wird...

Mach dir erstmal klar, was ein Timer(-interrupt) und was eine 
Warteschleife ist. Für die Tonhöhe(n) sollte vielleicht doch eine 
Warteschleife genutzt werden, damit du zumindest zwei unterschiedliche 
Töne gleichzeitig erzeugen kannst. Die können wegen der Harmonielehre 
auch nur in einigermaßen Vernünftigen Verhältnissen zueinander sein. Es 
reicht denke ich mal die Pythagoräische Stimmung aus. Den Timer würde 
ich dann hernehmen, um interruptgetrieben jeweils nach einem vierteltakt 
neue Noten aus der Partitur zu holen.

Ich hoffe, dass du nicht dieselbe Zeitvorgabe hast wie der hier 
Beitrag "Atmel T89C51RC2 RGB LED mit PWM in assembler Programmieren"

Ich schrieb doch bereits: 1mW an den 32Ω im Kopfhörer umsetzen und man 
wird schon was hören können.
U = wurzel(P * R)
I = wurzel(P / R)
Spannung am Kopfhörer werden ca. 180mV, Strom ca. 5,5mA sein
Also müssten am Vorwiderstand fast 5V abfallen bei etwas weniger als 5mA
Ich täts mal mit nem 1kΩ-Widerstand pro Seite probieren. Oder L+R 
parallelschalten, das in Reihe zu 470Ω und ran an den/die Portpins. Was 
hören sollte man da schon.

mfg mf

von Daniel H. (tales404)


Lesenswert?

Ich habe Heute meinen Radiowecker auseinander gebaut. Dieser hat nun 
aber 8ohm und 2 Watt...

Kann ich trotzdem den 1kohm Widerstand benutzen??

Lieg ich damit richtig dass ich die Drähte an p2.0(also der ausgang von 
mc, aus dem die frequenz kommt) und den pin in der nähe, an dem 5V 
steht?

Der Widerstand kommt dann, dachte ich, zwischen den Ausgang des 
mcs(P2.0) und dem Lautsprecher dran... oder?

Tut mir wirklich leid so nervige Fragen stellen zu müssen aber ich blick 
wirklich noch nicht ganz durch egal wie arg ich mich bemühe^^...

Tales

von Karl H. (kbuchegg)


Lesenswert?

Daniel Hennig schrieb:
> Ich habe Heute meinen Radiowecker auseinander gebaut. Dieser hat nun
> aber 8ohm und 2 Watt...
>

Du kennst das Ohmsche Gesetz?

Dann rechne damit

Du hast einen µC Ausgang


    ----o

an diesen schließt du einen Lautsprecher an. Dynamische Effekte 
vernachlässigne wir jetzt erst mal. Der Lautsprecher hat 8 Ohm


    -----o --------+
                   |
                R alias Lautsprecher
                   8 Ohm
                   |
                   |
      -------------+---------- GND

Wenn dein Ausgang auf High (=5 Volt) liegt, wieviel Strom fliesst dann 
durch einen Widerstand von 8 Ohm


    U = R * I

umstellen nach I

           U
     I = -----
           R

           5
     I = -----
           8

     I = 0.625A

also weit über ein halbes Ampere.

Kann dein µC dieses Strom am Ausgang liefern?
(SChau ins Datenblatt deines µC)

Antwort: WOhl eher kaum

> Kann ich trotzdem den 1kohm Widerstand benutzen??

Jetzt rechnest du dasselbe nochmal mit einem zusätzlichen 1K Widerstand

    -----o --------+
                   |
                R 1000 Ohm
                   |
                R alias Lautsprecher
                   8 Ohm
                   |
                   |
      -------------+---------- GND

Die beiden Widerstände kannst du zusammenfassen zu 1008 Ohm

(Ist zwar ein anderer Prozessor, aber so unterschiedlich sind die 
Prozessoren dann auch wieder nicht, was die Eigenschaften des Ausgangs 
angeht:
http://www.hanneslux.de/avr/divers/melody/melody02.html
)

von Daniel H. (tales404)


Lesenswert?

Vielen Vielen Dank für deine Antwort..

nunja da bekomm ich nun 0,004960 Ampere raus...

meinst du mit Datenblatt das hier?
http://atmel.com/dyn/resources/prod_documents/doc4105.pdf


bedeutet die errechnete ampere zahl, dass ichs kann?...
Denn ich würde wirklich gerne nachschauen bevor ich sowas frag aber 
versteh nicht wie...  brach ich eine bestimmte ampere zahl oder wie?

die seite die dur mir gezeigt hast versteh ich leider auch nicht genau 
auf was die mich bringen soll hab sie durchgelesen aber erkenn die 
intension nicht^^

von Karl H. (kbuchegg)


Lesenswert?

Daniel Hennig schrieb:
> Vielen Vielen Dank für deine Antwort..
>
> nunja da bekomm ich nun 0,004960 Ampere raus...

Also 5 Milliampere (mA)

> meinst du mit Datenblatt das hier?
> http://atmel.com/dyn/resources/prod_documents/doc4105.pdf
>
>
> bedeutet die errechnete ampere zahl, dass ichs kann?...

Was sagt dein Datenblatt, wieviel Strom du aus einem Ausgang ziehen 
darfst?

> Denn ich würde wirklich gerne nachschauen bevor ich sowas frag aber
> versteh nicht wie...  brach ich eine bestimmte ampere zahl oder wie?

Nein.
Die Ampere stellen sich ganz von alleine ein. Der Widerstand zieht 
soviel Strom wie sich durch seinen Widerstandswert und der Spannung, die 
über ihm abfällt ergibt. Daraus errechnet sich, wieviel Strom durch ihn 
hindurchfliesst.

Das ist die eine Seite der Medaille. Die andere ist, dass dieser Strom 
irgendwo herkommen muss. Dein µC muss ihn liefern können. Und der kann 
nicht unbegrenzt viel. Wieviel, steht im Datenblatt (bei den 
elektrischen Kennwerten)

Wenn der µC also mehr Strom liefern kann, als sich der Lautsprecher 
zieht, ist alles paletti.
Wenn der Lautsprecher mehr Strom zieht als der µC liefern kann, dann 
überlastest du ihn. Die Ausgangstreiber werden warm, dann heiß und 
irgendwann brennen sie durch.

> die seite die dur mir gezeigt hast versteh ich leider auch nicht genau
> auf was die mich bringen soll hab sie durchgelesen aber erkenn die
> intension nicht^^

Echt nicht?
Da ist ein µC. Und an diesem µC ist ein Lautsprecher angeschlossen. Das 
eine mal ist er direkt (mit einem Elko) angeschlossen und hat 50 Ohm 
Impendanz und das andere mal ist er mit einer Transistorschaltung 
angeschlossen und kann (steht irgendwo im Text) bis runter zu 8 Ohm 
Impendanz haben.

Ach neee, du hast recht. Das hat zu deinem Problem überhaupt keinen 
Bezug :-)

von Sam .. (sam1994)


Lesenswert?

Daniel Hennig schrieb:
> Das Problem ist, ich weiss noch nicht so wirklich wie ich das mache...

Ich hoffe du weißt, was du dir vorgenommen hast. Es ist lange nicht so 
einfach wie es aussieht oder sich am Ende anhört.

> Also mache ich das mit Timer? oder register die ich runterzähl?

Ein Ton besteht erst mal aus Schwingungen, diese müssen erstmal 
irgendwie in Software generiert werden. Da du 2 Kanäle hast musst du 
diese mischen, also addieren. Der Endwert kann man entweder per PWM oder 
DAC ausgeben. Timer sind zwingend erforderlich, einen Vorteil bei 2 
Timern sehe ich nicht.

Der Timer läuft in der Samplefrequenz. Ich würde dir für dein Vorhaben 
ein 1 Sample Buffer empfehlen: Im Timerinterrupt wird erst das zuletzt 
berechnete Sample ausgegeben, danach das nächste berechnet.

von Karl H. (kbuchegg)


Lesenswert?

@Samuel

Machs nicht zu kompliziert. Rechteckschwingung reicht.
Er schwimmt auch so schon heftigst.

von Bernhard S. (b_spitzer)


Lesenswert?

Zunächst mal kann ein T89c51 keinen nennenswerten Strom Treiben. Die 
8051er können nur Strom gegen Masse aufnehmen. Dabei 20mA nie 
überschreiten, sonst ist der Pin im Eimer. Also Lautsprecher mit einer 
Seite an 5V, andere Seite über Widerstand 470 Ohm an Portpin.

Zum anderen Problem: Kanon ist dann schon ziemlich heftig. Du brauchst 2 
Instanzen zur Frequenzerzeugung und 2 weitere Instanzen zur Erzeugung 
der Tondauer. Das alles am besten mit Interrupt etc. Ich habe sowas für 
eine Tonfolge in C programmiert. Kannst Du ja in ASM umstricken.

unn tschuess
Bernhard
1
/*  Melodieerzeugung mit 2 Timern
2
  Timer 0 erzeugt einen Grundtakt von 25ms für die Notendauer
3
  Timer 1 erzeugt die Ausgabefrequenz
4
  Im Array Noten[] steht die gewünschte Melodie
5
  Im Array Dauer[] steht die Notendauer (1, 2, 4, 8, 16 möglich)
6
7
  Timer 1 erzeugt die Frequenz aus dem Wert Noten[aNote]
8
  Reload-Wert für Timer: halbe Periodendauer in us
9
  1000000[us/s]/(2*Frequenz) = 500000/Frequenz
10
  
11
  Timer 0 erzeugt die Tondauer aus dem Wert Dauer[aNote]
12
  Notendauer: 120 Viertel/Minute => Viertel Note dauert 0,5s
13
  Halbe Note dauert 1s, ganze Note dauert 2s, achtel Note dauert 0,25s
14
  Grundzeit ist 25ms, für ein Achtel muss dann 80/8 mal gewartet werden
15
  zwischen 2 Noten ist 25ms Pause => Timer 1 wird dabei ausgeschaltet!
16
*/
17
#include <at89c5131.h>   // läuft auch auf dem T89C51RD2
18
19
// Frequenzen für Tonleiter: a0 = 440Hz, a1 = 880Hz
20
// Der Abstand zwischen 2 Halbtönen ist 2^(1/12)
21
// (12. Wurzel aus 2). Für eine Oktave (=12 Halbtöne)
22
// ergibt sich wieder der Faktor 2 (= 2^(1/12) ^12).
23
#define a0 440
24
#define b0 466
25
#define h0 493
26
#define c1 523
27
#define cis1 554
28
#define d1 587
29
#define dis1 622
30
#define e1 659
31
#define f1 698
32
#define fis1 739
33
#define g1 783
34
#define gis1 830
35
#define a1 880
36
#define b1 932
37
#define h1 987
38
#define c2 1046
39
#define cis2 1108
40
// Pause erzeugt keine Frequenz (Abfrage in Service_T1()).  
41
// Mit Werten kleiner 8Hz gäbe es einen Überlauf bei aFrequenz.
42
#define pause 10
43
44
// Melodie mit Notenwert und Länge 4 = 1/4 Note, 8=1/8 Note etc.
45
code unsigned int  Noten[]={c1,f1,f1,g1,f1,e1,d1,b0,d1,g1,g1,a1,g1,f1,e1,c1,e1,a1,a1,b1,a1,g1,f1,d1,c1,c1,d1,g1,e1,f1,pause,0};
46
code unsigned char Dauer[]={ 4, 4, 8, 8, 8, 8, 4, 4, 4, 4, 8, 8, 8, 8, 4, 4, 4, 4, 8, 8, 8, 8, 4, 4, 8, 8, 4, 4, 4, 2,    1,0}; 
47
// Tonleiter zum Test
48
//code unsigned int  Noten[]={c1,cis1,d1,dis1,e1,f1,fis1,g1,gis1,a1,b1,h1,c2,pause,0};
49
//code unsigned char Dauer[]={ 4, 4  , 4, 4  , 4, 4, 4  , 4, 4  , 4, 4, 4, 4,   2 ,0}; 
50
// C-Dur Akkord
51
//code unsigned int  Noten[]={c1,e1,g1,c2,pause,0};
52
//code unsigned char Dauer[]={ 4, 4, 4, 4,   2 ,0}; 
53
54
data unsigned char aNote=0;             // Nummer der aktuellen Note
55
data unsigned char aDauer=0;             // Zähler für Notendauer
56
data at 0x08 unsigned int aFrequenz;       // Timer-Wert für aktuelle Frequenz
57
data at 0x08 unsigned char Reload_H,Reload_L;// aufgeteilt über 2 Char-Variablen
58
59
sbit at P2_0 Ausgang;  
60
61
void init(void);
62
void Service_T0(void);
63
void Service_T1(void);
64
65
66
void main(void)
67
{  
68
  init();
69
  while(1){
70
    if (TF0==1){  // Timer für Notendauer
71
      Service_T0();
72
      // aktuelle Note zu Ende, jetzt kurze Pause, danach nächste Note!
73
      if(aDauer == (80/Dauer[aNote])){  
74
        TR1 = 0; // Tonerzeugung aus 
75
        // nächsten Ton vorbereiten => aNote+1
76
        aFrequenz = 65536 - (unsigned int)(500000/Noten[aNote+1]); 
77
      }
78
      // Pause zu Ende, Notenzähler erhöhen
79
      else if (aDauer == (80/Dauer[aNote]+1)){  
80
        aNote++;            // nächste Note
81
        aDauer=0;          // Notendauer zurücksetzen
82
        TR1 = 1;
83
        if (Noten[aNote] == 0){ // Melodietabelle endet mit 0
84
          aNote = 0;         // Melodie von vorne beginnen
85
          aFrequenz = 65536 - (unsigned int)(500000/Noten[aNote]);
86
        }  
87
      }
88
    }
89
    if (TF1==1)    // Timer für Tonerzeugung
90
      Service_T1();
91
  }
92
}
93
94
void init(void)
95
{
96
  aNote = 0;
97
  // Timer-Werte für ersten Ton bestimmen
98
  aFrequenz = 65536 - (unsigned int)(500000/Noten[aNote]);
99
  TMOD = 0x11;            // beide Timer 16 Bit
100
  TL0 = (65536-25000)%256;    // Grundtakt 25ms
101
  TH0 = (65536-25000)/256;
102
  TL1 = Reload_L;          // Aufteilung in TL1 und TH1
103
  TH1 = Reload_H;          // erfolgt über den Speicherort
104
  TR0 = 1;
105
  TR1 = 1;
106
}
107
108
void Service_T0(void)
109
{
110
  TL0 = (65536-25000)%256;  // Grundtakt 25ms
111
  TH0 = (65536-25000)/256;
112
  TF0 = 0;
113
  aDauer++;      // Zähler für Dauer erhöhen
114
}
115
116
void Service_T1(void)
117
{
118
  TL1 = Reload_L;
119
  TH1 = Reload_H;
120
  TF1 = 0;
121
  if (Noten[aNote]!=pause)
122
    Ausgang = ~ Ausgang;  // Frequenz erzeugen, wenn keine Pause
123
}

von Alex (Gast)


Lesenswert?

Um mal kurz dazwischen zu schießen:

Hier gibt es noch Hintergrundinformationen und Links zum Thema 
Klangerzeugung:

http://www.mikrocontroller.net/articles/Klangerzeugung

Außerdem findet man dort auch einen kleinen Schaltplan, der zeigt, wie 
man einen 8Ohm-Lautsprecher an den Mikrocontroller anschließen könnte.

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz Buchegger schrieb:


> Was sagt dein Datenblatt, wieviel Strom du aus einem Ausgang ziehen
> darfst?

Auf Seite 81, die Fussnote 6
(die haben das ziemlich gut versteckt).
maximal 10mA an einem Portpin, 26mA(!) am kompletten Port 0

von Daniel Hennig (Gast)


Lesenswert?

danke für diese schnelle Antwort



Also der im elektro Geschäft, der mit den Widerstand geschenkt hat, 
meinte der reicht bis zum 5mal so Vielen, wie ich benötigen würde, 
allerdings wusste er nicht welchen Lautsprecher und welchen Mc ich habe 
er wusste nur Mc an Lautsprecher und war darüber auch sehr verwundert 
weil er meinte man könnte höchstens ein kleines piepsen, wenn man genau 
hinhört, wahrnehmen...


Leider haben wir den Microcontroller immer nur Softwaretechnisch 
betrachtet, über die Hardware haben wir nie viel gesprochen.. wie haben 
nur Assembler mit ihm programmiert... und selbst das haben wir meist nur 
simluliert ohne controller^^..


Karl Heinz Buchegger schrieb:

> Echt nicht?
> Da ist ein µC. Und an diesem µC ist ein Lautsprecher angeschlossen. Das
> eine mal ist er direkt (mit einem Elko) angeschlossen und hat 50 Ohm
> Impendanz und das andere mal ist er mit einer Transistorschaltung
> angeschlossen und kann (steht irgendwo im Text) bis runter zu 8 Ohm
> Impendanz haben.
>
> Ach neee, du hast recht. Das hat zu deinem Problem überhaupt keinen
> Bezug :-)



Nein... so meinte ich das nicht... dass du da einen bestimmten Grund 
hattest, mir diese Seite zu schicken, war ich mir sicher, leider konnte 
ich nicht wirklich viel daraus rauslesen außer, dass ein Lautsprecher an 
einem mc angeschlossen wurde, aber ich versteh leider nicht wirklich 
mehr dort^^ und Schaltungen kann ich leider eh nicht wirklich lesen... 
wollte dich damit nicht angreifen, dass es schwachsinn war das zu 
schicken oder so.. wenn du das so verstanden hast tuts mir leid, war 
aber nicht so gemeint...



Ah ok danke für die Ermittlung vom Strom was mein mc erzeugen kann... du 
sagst weiter oben ich bräuchte einen Widerstand von 470 ohm, also kann 
ich den 1kohm widerstand wegwerfen?....

Danke für die Programmvorschläge.. Das C Programm werd ich nun mal 
durcharbeiten..

Ich wollte auch schon verschiedene Tutorials darüber durchlesen doch 
meistens sehe ich da befehle die ich nichtmal ansatzweise schonmal 
gesehen habe... obwohl dortsteht dass es assembler sei... Also wir 
benutzen als immer solche befehle mit mov ... und jmp und call und add 
und inc un so weiter... töne haben wir bisher so erzeugt dass wir
CPL P2.0 geschrieben haben
und danach eine Warteschleife kam, deren Dauer die frequenz des tons 
angab... so kamen dann die töne raus.(haben die herz des tons genommen 
und damit die frequent ausgerechnet...

sollte ich mir vlt besser schnell einen piezo Lautsprecher aus dem 
internet bestellen?

Tales

von Sam .. (sam1994)


Lesenswert?

Das Problem am Programm oben ist, dass es
a) nur eine Melodie ist
b) der falsche Ansatz für mehrere Kanäle wäre

Daniel Hennig schrieb:
> und danach eine Warteschleife kam, deren Dauer die frequenz des tons
> angab... so kamen dann die töne raus.(haben die herz des tons genommen
> und damit die frequent ausgerechnet...

Vergiss Warteschleifen, das mag bei einstimmigen Tönen funktionieren, 
sobald mehrere in Spiel kommen, machen sie das Programm unnötig 
kompliziert.

von Daniel H. (tales404)


Lesenswert?

So...

Lautsprecher und alles funktioniert nun... (war ja doch 1000mal 
einfacher als gedacht^^)


So Ein Ton einer bestimmten frequenz mit einer bestimmten Länge hab ich 
auch schon generiert...

?? was? warteschleifen vergessen`? so ist das nicht möglich?
ehm wie soll das denn sonst gehen wenn ich fragen darf? wie stell ich 
die frequenz eines Tons ein und deren Länge?

von Peter D. (peda)


Lesenswert?

Du willst 2 verschiedene Töne gleichzeitig erzeugen.
Dann nimm das PCA:
Figure 15. PCA High-speed Output Mode

Die Pulsdauer (0.5/Frequenz) addierst Du im Interrupt zu CCAP0 bzw. 
CCAP1 (16Bit-Addition).

Und die beiden Ausgänge (CEX0/1) addierst Du dann über 2 Widerstände.


Für einen blutigen Anfänger ist so ein Projekt recht ambitioniert. 
Wieviel Monate hast Du denn Zeit?


Peter

von Ralf N. (runni) Benutzerseite


Lesenswert?

Kannst mal da schauen, sogar mit wav Player ;-)
http://www.ipd.uka.de/~buchmann/microcontroller/index.htm

von Sam .. (sam1994)


Lesenswert?

Daniel Hennig schrieb:
> ?? was? warteschleifen vergessen`? so ist das nicht möglich?
Warteschleifen sind normalerweise unnötig und verschwenden Leistung (die 
ein Synthesizer wirklich braucht).
> ehm wie soll das denn sonst gehen wenn ich fragen darf? wie stell ich
> die frequenz eines Tons ein und deren Länge?

Wenn man das "richtig" machen möchte, hat man eine Struktur, welche 
Länge, Tonhöhe und eine Variable, die die Position der Schwingung angibt 
enthält.

In der regelmäßig aufgerufenen Timerinterrupt steht dann so etwas:
1
Sample (PWM) ausgeben
2
Sample = 0
3
4
Für alle Töne:
5
  Länge--
6
  if Länge == 0
7
    Tonhöhe = nächster Ton
8
    Länge = nächste Ton_Länge
9
    Pos_Schwingung = 0
10
11
  //Schwingung erzeugen
12
  Pos_Schwingung += Tonhöhe
13
  if Pos_Schwingung > 32786
14
    Freq = 127 ansonsten 0
15
16
  //Alles in eine Variable addieren
17
  Sample += Freq
In dem Code hat jeder Ton seinen speziellen Wert, der vorher berechnet 
werden muss.

Das wäre das Grundgerüst für einen ordentlich programmierten 
Synthesizer. Die Methode von Peter Danegger solltest du zuerst 
realisieren, bevor du das hier programmierst. Vorteil von dieser Methode 
ist, man kann solange die Rechenleistung reicht, die Kanäle beliebig 
skalieren.

von Bernhard S. (b_spitzer)


Lesenswert?

Es reicht ein alter Lautsprecher z.B. aus einem alten PC-Gehäuse. Selbst 
mit einem Schutzwiderstand ist der Lautsprecher gut hörbar (besonders, 
wenn 12 Schüler gleichzeitig rumpiepsen...).

Erstmal leise anfangen. Einen Schalttransistor kannst Du später immer 
noch anschließen, wenn das Programm geht.

unn tschuess
B.

von Daniel H. (tales404)


Lesenswert?

So Danke erstmal für die Antworten...

Das ganze soll schon ziemlich schlicht gelöst werden. SO einfach und 
schlicht wie möglich. Das soll nicht total besonderes werden...

Ich habe das nun mal so probiert:



1
LJMP programm
2
3
Ton:
4
Mov R2,#2
5
laenge:
6
MOV R1,#0
7
frequenz:
8
CPL P2.0
9
MOV R0, #50
10
warte:
11
12
MOV A, R4
13
MOV R3, A
14
frequenzDenung:
15
NOP
16
DJNZ R3, frequenzDenung
17
18
DJNZ R0, warte
19
DJNZ R1, frequenz
20
DJNZ R2, laenge
21
RET
22
23
24
programm:
25
MOV R4,#1                                                                                                                                                                                                                                                                                                                                                                                
26
CALL Ton
27
28
MOV R4,#4
29
CALL Ton
30
31
MOV R4,#10
32
CALL Ton
33
34
35
36
bye:
37
NOP
38
LJMP bye
39
40
41
END

Nun kann ich eben durch die 2 Zeilen, in denen ich das register 
initialisiere und das Unterprogramm "Ton" aufrufe einen Ton spielen...

Nun müsst ich eben die Töne und weitere warteschleifen so setzten , dass 
ein kanon rauskommt...
Wäre das vlt durch ein Timer besser möglich? Denn so ist noch ein wenig 
holpig finde ich ...

Außerdem kann ich irgendwie wenn ich mehr als 2 Töne abspielen lassen 
will, das Programm nicht mehr auf meinen Microcontroller ziehen da gibts 
dann ein Timeout error und ich versteh nicht ganz warum..?

von Sam .. (sam1994)


Lesenswert?

Du erzeugst einen Ton, der sieht so aus:
1
    ___     ___     ___
2
___|   |___|   |___|   |___
Dein anderer Ton sieht vielleicht so aus:
1
   __    __    __    __    
2
__|  |__|  |__|  |__|  |__
Wenn du diese jetzt addierst = mischst:
1
                     __
2
   _||________||__  |  |
3
__|               ||   |___  (so ungefähr)

Jetzt siehst du vielleicht auch, warum du Warteschleifen vergessen 
kannst.

Das geht nicht mehr mit einfachem Unschalten von einem Pin. Lies dich 
mal in PWM ein, du brauchst hier eine Möglichkeit eine Analoge Spannung 
zu erzeugen.

von spess53 (Gast)


Lesenswert?

Hi

>Das geht nicht mehr mit einfachem Unschalten von einem Pin. Lies dich
>mal in PWM ein, du brauchst hier eine Möglichkeit eine Analoge Spannung
>zu erzeugen.

Der verwendete AT89C51RC2, hat im Vergleich zu AVRs, nur einen sehr 
rudimentär ausgestatteten Timer:

http://www.atmel.com/dyn/resources/prod_documents/doc4180.pdf

MfG Spess

von Peter D. (peda)


Lesenswert?

spess53 schrieb:
> Der verwendete AT89C51RC2, hat im Vergleich zu AVRs, nur einen sehr
> rudimentär ausgestatteten Timer:

Er hat 4 Timer und 6 PWM-Ausgänge. Das sollte dicke reichen.


Peter

von spess53 (Gast)


Lesenswert?

Hi

>Er hat 4 Timer und 6 PWM-Ausgänge. Das sollte dicke reichen.

Lt. dem Datenblatt nur einen Timer.

MfG Spess

von Sam .. (sam1994)


Lesenswert?

Einer reicht. Was an 2 Timern besser sein soll, kann ich bei einem 
einfachen Synthesizer nicht verstehen.

von Daniel H. (tales404)


Lesenswert?

Also ich soll mich bei diesem Programm eigentlich auf das einfachste 
begrenzen...

Ich könnte ja eigentlich einfach den Kanon so bauen, dass ich gar kein 
Ton gleichzeitig spielen muss... Sondern immer pausen reinmache und ab 
einem bestimmten punkt die Pausen eben mit der selben melodie wieder 
befülle... wenn ich das gescheit mache dürfte da auch ein Kanon 
rausbekommen...
aber wenns geht wollte ich das dann trotzdem vlt über einen Timer machen 
wenn ich das hinbekommen würde(wie ein normaler timer geht weiss ich 
aber nicht wirklich wie ich damit einen Ton spielen soll)

Immoment hab ich leider noch das problem, dass wenn ich mehr als 2 Töne 
spielen lass, also 3 Töne oder 2 Töne und noch ne warteschleife, gibt es 
beim übertragen auf die platine immer einen timeout und ich versteh 
nicht warum... wenn ich dann die entsprechenden Zeilen wieder wegmache 
gehts wieder, so als ob das Programm dann zu groß wäre oder so...

von Bernhard S. (b_spitzer)


Lesenswert?

spess53 schrieb:
> Lt. dem Datenblatt nur einen Timer.

Der AT89C51 hat wie alle 8051 auch die Timer 0/1. In den 
Atmel-Datenblättern sind bei den Derivaten immer nur die zusätzlichen 
Features zur "Grundausstattung" angegeben. Damit hat der Controller die 
beiden Timer 0/1, den Timer 2 und noch das Programmable Conter Array 
(PCA), das auf 5 Kanälen PWM erzeugen kann.

Die übrigen Features verbergen sich im Family-Datasheet (8051 
Microcontrollers Hardware Manual)
http://www.atmel.com/dyn/resources/prod_documents/doc4316.pdf

unn tschuess
Bernhard

von Bernhard S. (b_spitzer)


Lesenswert?

Daniel Hennig schrieb:
> Also ich soll mich bei diesem Programm eigentlich auf das einfachste
>
> begrenzen...


Das passt aber nicht zur Aufgabe... Ich würde meinen Schülern sowas 
nicht ohne weitere Hilfestellung zumuten.

unn tschuess
Bernhard

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.