Datum:
Liebe Gemeinde, heute möchte ich euch eine Melodieklingel vorstellen, die in BASCOM programmiert wurde. Ja, es ist BASIC. Nicht abwinken - der Befehl "SOUND" wurde nicht verwendet. Vielmehr wurde der Timer1 im CTC-Modus verwendet und erzeugt, einmal angestoßen, ein Rechtecksignal selbständig, dass den Ton ergibt. Timer0 wurde verwendet, um die Länge des Tones zu begrenzen. Weiterhin habe ich noch den externen INT0 verwendet, um einen Klingeltaster anzuschließen. Die Idee für diese Klingel ist sehr alt. Sie ist in der Zeitschrift Funkamateur im Heft 4 1986 veröffentlicht worden. Wer danach im Internet sucht, wird diesen Artikel auch finden. Die Melodien wurden aus dieser Zeitschrift übernommen. Für den Bau der Klingel wurde ein ATmega8 verwendet. Dieser ist natürlich für diese Anwendung etwas überdimensioniert. Wenn jemand versucht, dieses Programm in einem anderen Controller zu verwenden, sollte er berücksichtigen, dass der Timer1 im ATmega8 als 16-Bit-Timer aufgebaut ist. Er wird hier auch in diesem Modus verwendet. Eine Anpassung an einen 8-Bit-Timer ist zwar möglich, erfordert aber einige Programmänderungen. Zur Hardware gibt es nicht viel zu sagen. Der Ausgang für den Lautsprecher befindet sich an PIN 15 (OCA1). Für Testzwecke kann dort ein Lautsprecher mit einem Widerstand von 220 Ohm in Reihe direkt angeschlossen und gegen Masse geschaltet werden. Wer es lauter braucht, der sollte noch einen Verstärker nachschalten. Der Klingeltaster wird an PIN 4 (INT0) gegen Masse angeschlossen. Wo die Versorgungsspannung von 5 V hin kommt, müsste jedem Elektroniker klar sein. Aufbau der Töne in der Liedtabelle:
Bit 7 6 5 4 3 2 1 0 Tonhöhe (Bit 3:0) 0 - Pause (kein Ton) 1 - c' 261,63 Hz 2 - cis' 277,18 Hz 3 - d' 293,66 Hz 4 - dis' 311,11 Hz 5 - e' 329,63 Hz 6 - f' 349,22 Hz 7 - fis' 369,99 Hz 8 - g' 392,00 Hz 9 - gis' 415,33 Hz A - a' 440,00 Hz B - b' 466,15 Hz C - h' 493,89 Hz D - c" 523,22 Hz E - cis" 554,40 Hz F - d" 587,37 Hz Tonlänge in Achtelnoten (Bit 6:4) 0 - 1/8 1 - ¼ 2 - 3/8 3 - ½ 4 - 5/8 5 - 3/4 6 - 7/8 7 - 1 Stoppbit (Bit 7) Wird an jedem Liedende gesetzt. |
Das Programm:
' Melodieklingel - Guido Scheidat
' Nachbau der Melodieklingel aus FA 4/86 mit modernen Bauteilen
' Übernahme aller Melodien aus der "Funkamateur"
' ATmega8
' intern 8 MHz
' Pin 4 (PD2 / INT0) - Klingeltaster gegen Masse
' Pin 15 (PB1 / OC1A) - Ausgang zum Lautsprecher
$regfile = "m8def.dat" 'Die Anweisung bestimmt Controllertyp, hier AVR ATmega 8
$crystal = 8000000 'Die Frequenz des verwendeten Quarzes
$prog &HFF , &HF4 , &HD9 , &H00 'generated. Take care that the chip supports all fuse bytes.
Dim Viertel As Byte
Dim I As Byte
Dim Lang As Byte
Dim Aktton As Byte
Dim Liedcount As Integer
Dim Enderr As Bit
Const Speed = 4 'darf nicht 0 sein
Liedcount = 0
Lang = 1
Enderr = 0
Viertel = 1
Set Portd.2 'Pull-up ein
Config Portb.1 = Input 'SOUNDOFF
'*** Timer 1 einstellen
'Vorteiler auf 1
Set Tccr1b.cs10
Reset Tccr1b.cs11
Reset Tccr1b.cs12
'Toggle OC1A on Compare Match
Reset Tccr1a.com1a1
Set Tccr1a.com1a0
'Waveform Generation Mode --> Mode 4; CTC
'WGM13 = 0
'WGM12 = 1
'WGM11 = 0
'WGM10 = 0
Reset Tccr1b.wgm13
Set Tccr1b.wgm12
Reset Tccr1a.wgm10
Reset Tccr1a.wgm11
'*** Timer 0 einstellen
Config Timer0 = Timer , Prescale = 1024 'Konfiguriere Timer0
On Timer0 Isr_timer0 'verzweige bei Timer0-Überlauf zu ISR_Timer0
Timer0 = 256 - 243 'Timer0 Zeit für 1/8 Note / 4
Enable Timer0 'schalte den Timer0 ein
'*** externen Interrupt 0 einstellen
Config Int0 = Low Level 'configuriere Int0 Auf Low Level
On Int0 Isr_int0 'springe zu ISR_Int0
Enable Int0 'einschalten von Interrupt Int0
'*** Behandlung von Interrupts
Enable Interrupts 'Einschalten der Interrupts
'*** Hauptprogramm
Do
'....Hauptprogramm -- es gibt kein Hauptprogramm, da Alles über Interrupts gesteuert wird
Loop
End
'*** Interrupt-Routine für Timer 0
Isr_timer0: 'ISR von Timer0
Viertel = Viertel - 1
If Viertel = 0 Then
Viertel = Speed
Lang = Lang - 1
If Lang = 0 Then
If Enderr = 1 Then
'Timer / Counter0 Overflow Interrupt Disable
Disable Timer0 'schalte den Timer0 aus
Config Portb.1 = Input 'SOUNDOFF
Enable Int0 'INT0 erlauben
Else
Aktton = Lookup(liedcount , Lied)
If Aktton.7 = 1 Then Enderr = 1 'Liedende gefunden
Lang = Aktton 'Tonlänge ermitteln
Shift Lang , Right , 4 'Division durch 16
Lang = Lang And &H07
Lang = Lang + 1
Aktton = Aktton And &H0F
If Aktton = 0 Then
Config Portb.1 = Input 'SOUNDOFF
Else
Aktton = Aktton - 1
Reset Tccr1b.cs10 'CTC aus
Shift Aktton , Left , 1 'Multiplikation mit 2
Ocr1ah = Lookup(aktton , Tone) 'Tonhöhe
Aktton = Aktton + 1
Ocr1al = Lookup(aktton , Tone) 'Tonhöhe
Tcnt1l = 0 'Zähler soll bei 0 beginnen
Tcnt1h = 0
Set Tccr1b.cs10 'CTC ein
Config Portb.1 = Output 'SOUNDON
End If
Liedcount = Liedcount + 1 'nächste Note
Aktton = Lookup(liedcount , Lied)
If Aktton = &HFF Then 'Test ob Liedtabelle zu Ende ist
Liedcount = 0
End If
End If
End If
End If
Return
'*** Interrupt-Routine für externen Interrupt 0
Isr_int0: 'ISR von INT0
Disable Int0 'External Interrupt Request 0 Disable
'Tastenentprellung und Sturmklingelsperre
I = 0
While I < 30 'Taste muss mindestens 30 ms gedrückt sein
If Pind.2 = 0 Then
Waitms 1 'Pause
I = I + 1
Else
I = 0
End If
Wend
I = 0
While I < 30 'Taste muss mindestens 30 ms losgelassen sein
If Pind.2 = 1 Then
Waitms 1 'Pause
I = I + 1
Else
I = 0
End If
Wend
'Taste wurde erfolgreich gedrückt und losgelassen
'Jetzt kann die nächste Melodie gespielt werden
Viertel = 1
Lang = 1
Enderr = 0
Enable Timer0
Return
'***
Tone:
Data 59 , 184 ' c' 261,63 Hz Timerwerte für die enspr. Tonhoehen in Hz
Data 56 , 94 ' cis' 277,18 Hz
Data 53 , 52 ' d' 293,66 Hz
Data 50 , 56 ' dis' 311,11 Hz
Data 47 , 102 ' e' 329,63 Hz
Data 44 , 189 ' f' 349,22 Hz
Data 42 , 58 ' fis' 369,99 Hz
Data 39 , 219 ' g' 392,00 Hz
Data 37 , 158 ' gis' 415,33 Hz
Data 35 , 130 ' a' 440,00 Hz
Data 33 , 132 ' b' 466,15 Hz
Data 31 , 162 ' h' 493,89 Hz
Data 29 , 220 ' c'' 523,22 Hz
Data 28 , 46 ' cis'' 554,40 Hz
Data 26 , 153 ' d'' 587,37 Hz
'***
Lied:
'Musi01:
Data &H03 , &H00 , &H05 , &H00 , &H07 , &H00 , &H08 , &H00 , &H0A , &H00 , &H0C , &H00 , &H3A , &H08 , &H00 , &H05 , &H00 , &H3E , &H0A , &H00 , &H07 , &H00 , &HAF
'Musi02:
Data &H35 , &H00 , &H2A , &H00 , &H02 , &H05 , &H10 , &H05 , &H10 , &H85
'Musi03:
Data &H03 , &H00 , &H05 , &H00 , &H37 , &H3A , &H0E , &H20 , &H1C , &H10 , &H2C , &H00 , &HA7
'Musi04:
Data &H47 , &H00 , &H06 , &H00 , &H07 , &H00 , &H0F , &H00 , &H07 , &H00 , &H0E , &H00 , &H0C , &H20 , &H0C , &H20 , &H9C
'Musi05:
Data &H0A , &H00 , &H2F , &H10 , &H1E , &H10 , &H0C , &H0A , &H10 , &HA7
'Musi06:
Data &H53 , &H17 , &H3A , &H3F , &H3C , &H1F , &H1C , &HBA
'Musi07:
Data &H13 , &H20 , &H15 , &H20 , &H17 , &H00 , &H1A , &H1C , &H00 , &H1A , &H1F , &H20 , &H1C , &H20 , &H1A , &HB7
'Musi08:
Data &H17 , &H18 , &H3A , &H27 , &H00 , &H27 , &H00 , &H37 , &H95
'Musi09:
Data &H33 , &H08 , &H00 , &H0A , &H00 , &H3C , &H3F , &H3C , &H3A , &HB8
'Musi10:
Data &H48 , &H00 , &H0A , &H00 , &H08 , &H00 , &H06 , &H00 , &H25 , &H00 , &H21 , &H00 , &HB1
'Musi11:
Data &H45 , &H00 , &H03 , &H00 , &H02 , &H00 , &H05 , &H00 , &H0A , &H00 , &H0C , &H00 , &H5E , &H10 , &HBA
'Musi12:
Data &H0A , &H00 , &H08 , &H00 , &H0A , &H00 , &H08 , &H00 , &H07 , &H20 , &HB3
'Musi13:
Data &H03 , &H00 , &H03 , &H00 , &H25 , &H00 , &H23 , &H00 , &H28 , &H00 , &H47 , &H20 , &H03 , &H00 , &H03 , &H00 , &H25 , &H00 , &H23 , &H00 , &H2A , &H00 , &HC8
'Musi14:
Data &H46 , &H00 , &H14 , &H13 , &H14 , &H36 , &H3F , &H3B , &HA6
'Musi15:
Data &H15 , &H12 , &H50 , &H12 , &H23 , &H15 , &H0E , &H20 , &H0E , &H20 , &HBA
'Musi16:
Data &H28 , &H00 , &H03 , &H00 , &H23 , &H10 , &H38 , &H00 , &H25 , &H00 , &H05 , &H00 , &H25 , &H40 , &H27 , &H00 , &H08 , &H00 , &H2A , &H10 , &H27 , &H10 , &H28 , &H00 , &H0C , &H00 , &HB8
'Musi17:
Data &H4A , &H00 , &H07 , &H10 , &H0A , &H10 , &H07 , &H10 , &H0A , &H10 , &H08 , &H10 , &HA8
'Musi18:
Data &H0C , &H00 , &H0B , &H00 , &H0C , &H20 , &H0C , &H00 , &H0B , &H00 , &H0C , &H20 , &H0C , &H00 , &H0B , &H00 , &H0C , &H20 , &H0A , &H20 , &H98
'Musi19:
Data &H03 , &H00 , &H03 , &H00 , &H28 , &H00 , &H2C , &H00 , &H08 , &H00 , &H08 , &H00 , &H2A , &H00 , &H2D , &H00 , &H03 , &H00 , &H07 , &H00 , &H3A , &H00 , &H0C , &H00 , &H2A , &H00 , &HA8
'Musi20:
Data &H03 , &H00 , &H05 , &H00 , &H27 , &H00 , &H07 , &H00 , &H0A , &H00 , &H28 , &H00 , &H08 , &H00 , &H0C , &H00 , &H1A , &H00 , &H0C , &H0A , &H00 , &H08 , &H00 , &HA7
'Musi21:
Data &H21 , &H00 , &H46 , &H00 , &H08 , &H00 , &H0B , &H00 , &H0A , &H00 , &H08 , &H00 , &H2D , &H00 , &HAD
'Musi22:
Data &H28 , &H00 , &H4D , &H00 , &H08 , &H00 , &H25 , &H00 , &H26 , &H00 , &H48 , &H00 , &H0A , &H00 , &HA8
'Musi23:
Data &H23 , &H00 , &H4F , &H00 , &H0E , &H00 , &H2F , &H00 , &H2C , &H00 , &H4D , &H00 , &H0C , &H00 , &H2D , &H00 , &H27 , &H00 , &H0A , &H00 , &H98
'Musi24:
Data &H6A , &H00 , &H6A , &H00 , &H0A , &H00 , &H3C , &H30 , &H0A , &H00 , &H2C , &H00 , &H0A , &H00 , &H0C , &H00 , &H2A , &H00 , &H09 , &H00 , &HB8
'Musi25:
Data &H0C , &H20 , &H2A , &H20 , &H07 , &H00 , &H05 , &H00 , &H03 , &H00 , &H2C , &H00 , &H2B , &H00 , &HAC
'Musi26:
Data &H07 , &H00 , &H05 , &H00 , &H03 , &H00 , &H05 , &H00 , &H07 , &H00 , &H05 , &H00 , &H03 , &H00 , &H05 , &H00 , &H27 , &H00 , &H0C , &H20 , &H27 , &H00 , &H8C
'Musi27:
Data &H03 , &H00 , &H05 , &H00 , &H27 , &H00 , &H27 , &H00 , &H08 , &H00 , &H05 , &H00 , &H1C , &H0A , &H00 , &HAA
'Musi28:
Data &H23 , &H00 , &H03 , &H00 , &H07 , &H00 , &H2A , &H00 , &H2A , &H00 , &H2A , &H00 , &H0C , &H00 , &H0A , &H00 , &H27 , &H00 , &HA3
'Musi29:
Data &H3F , &H3E , &H3C , &H3A , &H3C , &H18 , &H17 , &H25 , &H00 , &HA3
'Endekennzeichen
Data &HFF
|
Dieses Programm gibt es auch in C. Wenn Bedarf besteht, stelle ich auch dieses noch ein.
Datum:
Das C-Programm kann dann bestimmt auch das Hohe "C". Ja, stell mal rein. Währe nicht schlecht.
Datum:
> Das C-Programm kann dann bestimmt auch das Hohe "C".
Kann es nicht, da diese (sehr kompakte) Form der Codierung nur 15 Töne
plus Pause erlaubt.
...
Datum:
> Bitte Code als Code posten :P
Oder als Anhang. Da sieht man dann auch, wie oft er angesehen oder
heruntergeladen wurde. ;-)
...
Datum:
Angehängte Dateien:Hallo! Super Code! Das Bascom Programm von Guido Scheidat hier als ZIP-Datei. mfg albert
Datum:
Bitte kannst du den Program als C code auch hier schreiben . danke MFG Zreik
Datum:
Guten Morgen, ich habe gestern auf die Schnelle den bascom code für den atMega48 übersetzt. Ging problemlos. Weitere Melodien habe ich hier gefunden: http://sbarth.dyndns.org/seiten/rahmen.php?nav=klingel#v3 Und auch einen Link wieder zurück : Beitrag "Melodieklingel mit PIC" Im Anhang von Artikel - Beitrag "Re: Melodieklingel mit PIC (AVR)" stehen noch weitere Lieder. Diese habe ich den aktuellen Code 'transplantiert', der atMega48 reicht immer noch und das Programm muss noch getestet werden ! Ausblick: Spannend fände ich eine Portierung auf den atTiny85, der hat leider keinen 16-Bit Timer.
Datum:
Ein Beispiel für den Attiny 25 findest du hier Beitrag "Klingel mit 100 Melodien - last minute Weihnachtsgeschenk" Melodien kannst du dir von dort auch gern rauskonvertieren. Viele Grüße, Mirko
Datum:
Angehängte Dateien:Vielen Dank Mirko, der atMega48 läuft. Habe ihn auf ein Steckbrett gesteckt. Im Anhang für alle Mitleser der BASCOM Code und das Intel-Hex-File. Ich verwende KEIEN 8MHz Quarz, sondern den internen 8MHz RC Oszillator ! Die Fusebits stehen in Melodieklingel-48.bas ! .
Datum:
Angehängte Dateien:Hallo, habe das Ganze mal für einen ATTiny2313 übersetzt, zusätzlich wurde eine Umschaltung auf Weihnachtslieder eingebaut (damit ist das Ganze jetzt zu der alten Funkamateur-Variante mit 2 EPROM's kompatible). Und weil ein Freund es forderte :-) ist auch noch ein Power-Save-Modus eingebaut. Der Microproz zieht also nur noch einige µA.
Datum:
Also bei mir spielt der Atiny2313 ganz langsam und dumpf etwas ab. Aber eben keine Melodie :-( Er läuft aber intern auf 8Mhz, was kann da falsch sein? Wie sind die Fusebit-Einstellungen?
Datum:
Der ATTiny läuft wie der Original-ATMega mit dem internen RC-Oszllator
mit 8MHz (also Vorteiler abschalten).
Die Fuses: eFuse FFh
hFuse DFh
lFuse E4h.
Bitte beachten: der ATmega spielt beim Einschalten das erste Lied, der
ATTiny
legt sich nach dem Einschalten sofort Schlafen und wird erst durch
Drücken des Klingeltasters geweckt.
Bobby
Datum:
Genau das war es :-) ..... Tomaten auf den Augen. Teiler abgeschalten und schon singt er wie ein Vogel :-) Danke!
Datum:
Angehängte Dateien:Hallo, liebe Elektroniker, heute will ich mal die C-Version schicken. Danke für die lebhafte Diskusion! Gruß Guido
Datum:
Hi, hab das Ganze getestet, funzt ganz gut, hab statt dem Piezo einen kleinen Schalttransistor bzw. ULN2803 mit Lautsprecher angehängt. Aus mir zunächst nicht ganz erklärlichen Fällen passierte es dann in ca. 50% der Fälle, dass nach Abspielen der Melodie der Schalttransistor durchgeschaltet wurde und sich sowohl Lautsprecher als auch Schalttransistor stark erwärmt haben (naja bei 8 Ohm Lautsprecher an 5 Volt irgendwie logisch). Hab dann "weiter geforscht" und folgendes gefunden: Was mich an dem ganzen Programm stört, ist die ständige Umschaltung des Ports zwischen Input und Output. Damit hat man - wenn eine nachgeschaltete Treiberstufe (ULN2803 oder Transistor) verwendet wird - ein Problem . Man müßte dann zusätzlich Pull-Down Widerstände gegen Masse schalten, da ja der Eingang des Atmega hochohmig ist und die Endstufe verwirrt: Also folgender Verbesserungsvorschlag für die ISR_int0 Routine, der Portb.1 bleibt einfach als Ausgang definiert und es wird nur die Timersteuerung für den Portb.1 ein- bzw. ausgeschaltet: statt Config Portb.1 = Input 'SOUNDOFF besser: reset Tccr1a.com1a0 und statt Config Portb.1 = output 'SOUNDON besser: set Tccr1a.com1a0 Dann bleibt der Pin B.1 ganz fix auf GND-Niveau, wenn nichts ausgegeben wird. Endstufe und Lautsprecher bleiben dann ganz cool
Datum:
Hallo Manfred, hallo alle! Ja, dieses Problem besteht. Es zieht sich durch, seit der Veröffentlichung in der Zeitschrift Funkamateur. Da das Programm in seiner Quelle offen ist, kann ich niemanden daran hindern, Änderungen vorzunehmen. Warum das Problem bei mir nicht auftritt, ist die Tatsache, dass ich einen richtigen Verstärker angeschlossen habe. Da hier mindestens ein Kondensator in Reihe zum Signal geschaltet ist, können keine statischen Zustände am Lautsprecher ankommen. Gruß Guido
Datum:
Danke Guido, schön, dass du meine Erfahrung bestätigt hast. Mit meinem Vorschlag ist das Problem ja behoben, ich finde es auch verständlicher, nicht die Richtung des Ports zu ändern (Ausgang auf Eingang mit der Problematik des hochohmigen Eingangs), sondern einfach den Timerausgang vom Port zu nehmen und damit wieder die defaultmäßige Ausgangsstellung (=0) aufleben zu lassen. Falls jemand einen RTTTL-Klingeltonspieler will, denn habe ich hier veröffentlicht - Beitrag "Re: RTTTL-Klingeltoninterpreter für Atmega8 in BASCOM II" für den sind viel einfacher Songs zu finden, da es diese Klingeltonplayer noch zu Hauf im Internet gibt und auch Converter, die aktuelle Songs einstimmig von MP3 auf RTTTL konvertieren können.