TASM 8051 Assembler. melodie.prg page 1 Speech Technology Incorporated. 0001 0000 ;Alle Zeit- und Frequenzwerte 0002 0000 ;fuer Quarz 12 MHz 0003 0000 0004 0000 ;An Port 3.7 schließe man einen Piezo gegen Plus oder Masse an oder führe 0005 0000 ; die Leitung an den Eingang eines Verstärkers. 0006 0000 0007 0000 ;An Port 3.2 bis 3.5 bis vier Taster gegen Masse zwecks Start 0008 0000 0009 0000 ;P1.0 bis P1.3 werden über Treiber Relais zur Ansteuerung von bis zu 4 0010 0000 ; Lautsprecher angeschlossen L= Lautsprecher aktiv 0011 0000 0012 0000 ;reserviert: 0013 0000 ; P3.0 und P3.1 für evtl. serielle Meldung über Hausbus 0014 0000 ; P1.6 und P1.7 für evtl. externem I2C-EEprom 0015 0000 0016 0000 #include "C:\\tasm\\2051.def" 0001+ 0000 ;------------------------------------------------------ 0002+ 0000 ; : 0003+ 0000 ; DEFINES der 89C2051-Systemadressen : 0004+ 0000 ; : 0005+ 0000 ;------------------------------------------------------ 0099+ 0000 #LIST 0017 0000 0018 0000 f_low .EQU 20H 0019 0000 f_high .EQU 21H 0020 0000 dauer .EQU 22H 0021 0000 input .EQU 23h ;zeigt an welche taste gedrückt wurde 0022 0000 0023 0000 ;********* BIT Definitionen 0024 0000 ton .EQU 07Fh ;2F.7 wenn gesetzt wird Ton gespielt 0025 0000 0026 0000 beep .EQU P3.7 ; Anschluß Beeper 0027 0000 0028 0000 0029 0000 ;************** Kaltstart hier ********************** 0030 0000 .ORG 0 0031 0000 start: 0032 0000 75 A8 00 MOV IE,#0 ; No Interrupts! 0033 0003 75 81 70 MOV SP,#70H ; initialisiere SP 0034 0006 80 19 SJMP reset 0035 0008 0036 0008 ;************** Interrupt-Service Routine TIMER-0 ********************** 0037 000B .ORG 0BH 0038 000B C2 8C timer0: CLR TR0 ;Stoppe Timer 0 0039 000D 30 7F 02 JNB ton,tim_00 ;bei Pause Ton abschalten 0040 0010 B2 B7 CPL beep ;Beginn von Timer 0 Interrupt 0041 0012 85 20 8A tim_00: MOV TL0,f_low ;Kopiere Register 20 und 21 0042 0015 85 21 8C MOV TH0,f_high ;in den Timer 0 0043 0018 D2 8C SETB TR0 ;Starte Timer 0 0044 001A 32 RETI ;Timer 0 muß angehalten werden, 0045 001B ;da sonst ein Überlauf des Low- 0046 001B ;Bytes keine Erhöhung des High- 0047 001B ;Bytes bewirken würde. 0048 001B 0049 001B ;************** Interrupt-Service Routine TIMER-1 ********************** 0050 001B .ORG 1BH 0051 001B timer1: ;Beginn von Timer1 Interrupt 0052 001B 75 8D D9 MOV TH1,#-39 ;für 10ms Interrupt bei 12 MHz 0053 001E 15 22 DEC dauer ;Tonlänge runterzählen 0054 0020 32 RETI 0055 0021 0056 0021 ;************** Kaltstart Fortsetzung ********************** TASM 8051 Assembler. melodie.prg page 2 Speech Technology Incorporated. 0057 0021 reset: 0058 0021 75 B8 00 MOV IP,#0 ;Standart Interrupt-Priorität 0059 0024 75 D0 00 MOV PSW,#0 ;Registerbank 0 auswählen 0060 0027 75 89 11 MOV TMOD,#11H ;Beide Timer als 16-Bit Timer 0061 002A 0062 002A 00 h_loop: NOP 0063 002B ;# MOV P1,#0FFh ;alle Lautsprecher-Relais aus 0064 002B 75 90 C0 MOV P1,#0C0h ;alle Lautsprecher-Relais aus 0065 002E 90 00 F8 MOV DPTR,#tabelle ;Zeiger auf Lied-Tabelle 0066 0031 0067 0031 00 h_lo0: NOP ;warte dass alle Tasten losgelassen 0068 0032 D2 B7 SETB beep ;ton aus 0069 0034 E5 B0 MOV A,P3 ;Tastenport lesen 0070 0036 F4 CPL A 0071 0037 54 3C ANL A,#3Ch ;nur P3.2-P3.5 0072 0039 70 F6 JNZ h_lo0 ;noch ne Taste ? -> JUMP 0073 003B 0074 003B 00 h_lo00: NOP 0075 003C E5 B0 MOV A,P3 ;Tastenport lesen 0076 003E F4 CPL A 0077 003F 54 3C ANL A,#3Ch ;nur P3.2-P3.5 0078 0041 60 F8 JZ h_lo00 ;keine Taste gedrück? -> JUMP 0079 0043 7A 00 MOV R2,#0 0080 0045 DA FE DJNZ R2,$ ;einen Moment warten (Entprellung) 0081 0047 E5 B0 MOV A,P3 ;Tastenport lesen 0082 0049 F4 CPL A 0083 004A 54 3C ANL A,#3Ch ;nur P3.2-P3.5 0084 004C 60 ED JZ h_lo00 ;falls nicht mehr Taste->von vorn 0085 004E 0086 004E ; MOV DPTR,#tab_a ;Sondermelodie A 0087 004E 0088 004E 0089 004E 0090 004E E4 h_lo1: CLR A 0091 004F 93 MOVC A,@A+DPTR ;Hole Toninformation 0092 0050 A3 INC DPTR ;nächsten Tabellenplatz 0093 0051 FA MOV R2,A ;merken 0094 0052 54 0F ANL A,#0Fh ;nur low-Nibble 0095 0054 B4 0E 02 CJNE A,#0Eh,h_lo10 ;Liedende ? 0096 0057 80 D8 SJMP h_lo0 ;ja->zur erneuten Tastenabfrage 0097 0059 B4 0F 02 h_lo10: CJNE A,#0Fh,h_lo11 ;Tabellenende ? 0098 005C 80 CC SJMP h_loop ;von vorn beginnen 0099 005E h_lo11: ;sonst tonhöhe berechnen und in timer 0100 005E 60 02 JZ h_lo12 ;Pause bei Tonhöhe 0 0101 0060 D2 7F SETB ton ;sonst Ton erlauben 0102 0062 14 h_lo12: DEC A ;Korrektur für Tabelle (Tonhöhe 0=Pause) 0103 0063 11 D0 ACALL data ;Töne in f_low und f_high ablegen 0104 0065 ;jetzt Oktave berechnen 0105 0065 EA MOV A,R2 ;merker holen 0106 0066 54 30 ANL A,#030H ;der High-Teil der die Oktave bildet 0107 0068 B4 30 0D CJNE A,#030H,okt3 0108 006B E5 21 okt4: MOV A,f_high 0109 006D D3 SETB C 0110 006E 13 RRC A 0111 006F F5 21 MOV f_high,A 0112 0071 E5 20 MOV A,f_low 0113 0073 13 RRC A 0114 0074 F5 20 MOV f_low,A 0115 0076 80 03 SJMP okt31 0116 0078 B4 20 0D okt3: CJNE A,#020H,okt2 0117 007B E5 21 okt31: MOV A,f_high 0118 007D D3 SETB C TASM 8051 Assembler. melodie.prg page 3 Speech Technology Incorporated. 0119 007E 13 RRC A 0120 007F F5 21 MOV f_high,A 0121 0081 E5 20 MOV A,f_low 0122 0083 13 RRC A 0123 0084 F5 20 MOV f_low,A 0124 0086 80 03 SJMP okt21 0125 0088 B4 10 0B okt2: CJNE A,#010H,okt1 0126 008B E5 21 okt21: MOV A,f_high 0127 008D D3 SETB C 0128 008E 13 RRC A 0129 008F F5 21 MOV f_high,A 0130 0091 E5 20 MOV A,f_low 0131 0093 13 RRC A 0132 0094 F5 20 MOV f_low,A 0133 0096 85 20 8A okt1: MOV TL0,f_low ;Kopiere Register 30 und 31 0134 0099 85 21 8C MOV TH0,f_high ;in den Timer 0 0135 009C ;jetzt Tondauer berechnen 0136 009C EA MOV A,R2 ;merker holen 0137 009D 54 C0 ANL A,#0C0h ;High-Teil, der die Länge definiert 0138 009F B4 C0 05 CJNE A,#0C0h,dau1 0139 00A2 75 22 50 MOV dauer,#80 ;800ms 0140 00A5 80 13 SJMP los 0141 00A7 B4 80 05 dau1: CJNE A,#80h,dau2 0142 00AA 75 22 28 MOV dauer,#40 ;400ms 0143 00AD 80 0B SJMP los 0144 00AF B4 40 05 dau2: CJNE A,#40h,dau3 0145 00B2 75 22 14 MOV dauer,#20 ;200ms 0146 00B5 80 03 SJMP los 0147 00B7 75 22 0A dau3: MOV dauer,#10 ;100ms 0148 00BA 75 A8 8A los: MOV IE,#8AH ;Interruptfreigabe für T0 und T1 0149 00BD 75 8D D9 MOV TH1,#-39 ;für 10ms Interrupt bei 12 MHz 0150 00C0 75 88 50 MOV TCON,#50H ;Beide Timer starten 0151 00C3 78 22 MOV R0,#dauer 0152 00C5 warte1: 0153 00C5 B6 00 FD CJNE @R0,#00,warte1 ;Reg. 32 wird in der 2.Interruptrout. verändert. 0154 00C8 0155 00C8 C2 7F CLR ton 0156 00CA C2 8C CLR TR0 ;Timer 0 und damit Ton abschalten. 0157 00CC C2 8E CLR TR1 ;Timer 1 anhalten 0158 00CE 0159 00CE 01 4E AJMP h_lo1 ;nächster Ton 0160 00D0 0161 00D0 ;************** Zeitkonstanten für die Tonhöhen ********************** 0162 00D0 0163 00D0 23 data: RL A ;mal zwei 0164 00D1 C0 E0 PUSH ACC 0165 00D3 24 0A ADD A,#10 ;Korrekturwert zum L-Wert 0166 00D5 83 MOVC A,@A+PC 0167 00D6 F5 20 MOV f_low,A 0168 00D8 D0 E0 POP ACC 0169 00DA 24 04 ADD A,#4 ;Korrekturwert zum H-Teil 0170 00DC 83 MOVC A,@A+PC 0171 00DD F5 21 MOV f_high,A 0172 00DF 22 RET 0173 00E0 ; 1.Okt 2.Okt 3.Okt 4.Okt 0174 00E0 88 F8 .DB 088h,0F8h ;C 261,6 523,2 1046,5 2093,0 0175 00E2 F3 F8 .DB 0F3h,0F8h ;Cis 277,2 554,4 1108,8 2217,6 0176 00E4 59 F9 .DB 059h,0F9h ;D 293,7 587,4 1174,8 2349,6 0177 00E6 B8 F9 .DB 0B8h,0F9h ;Dis 311,2 622,3 1244,6 2498,2 0178 00E8 12 FA .DB 012h,0FAh ;E 329,7 659,3 1318,6 2637,2 0179 00EA 67 FA .DB 067h,0FAh ;F 349,2 698,4 1396,8 2793,6 0180 00EC B8 FA .DB 0B8h,0FAh ;Fis 370,0 740,0 1480,0 2960,0 TASM 8051 Assembler. melodie.prg page 4 Speech Technology Incorporated. 0181 00EE 03 FB .DB 003h,0FBh ;G 392,0 784,0 1568,0 3136,0 0182 00F0 4B FB .DB 04Bh,0FBh ;Gis 415,4 830,7 1661,4 3322,8 0183 00F2 8F FB .DB 08Fh,0FBh ;A 440,0 880,0 1760,0 3520,0 0184 00F4 CF FB .DB 0CFh,0FBh ;Ais 466,2 932,4 1864,8 3729,6 0185 00F6 0B FC .DB 00Bh,0FCh ;H 493,9 987,8 1975,6 3951,2 0186 00F8 0187 00F8 ;Die eingetragenen 1/2 Periodenlängen errechnen sich aus 65535-(10^6/(2*Hz)), 0188 00F8 ;z.B. f=440Hz => 10^6/(2*440)=FB8Fh. 0189 00F8 0190 00F8 #include "lieder.def" 0001+ 00F8 ;************** Beginn der Melodien ********************** 0002+ 00F8 ;jeder Ton ein Byte 0003+ 00F8 ;Aufbau 0004+ 00F8 ; H-Nibble legt Oktave und Tonlänge fest 0005+ 00F8 ; 1.Okt 2.Okt. 3.Okt. 4.Okt. 0006+ 00F8 ; achtel Note 100ms 0xh 1xh 2xh 3xh 0007+ 00F8 ; viertel Note 200ms 4xh 5xh 6xh 7xh 0008+ 00F8 ; halbe Note 400ms 8xh 9xh Axh Bxh 0009+ 00F8 ; ganze Note 800ms Cxh Dxh Exh Fxh 0010+ 00F8 ; 0011+ 00F8 ; L-Nibble bestimmt Tonhöhe und Sonderfunktionen 0012+ 00F8 ; x0h - Pause 0013+ 00F8 ; x1h - c 0014+ 00F8 ; x2h - cis 0015+ 00F8 ; x3h - d 0016+ 00F8 ; x4h - dis 0017+ 00F8 ; x5h - e 0018+ 00F8 ; x6h - f 0019+ 00F8 ; x7h - fis 0020+ 00F8 ; x8h - g 0021+ 00F8 ; x9h - gis 0022+ 00F8 ; xAh - a 0023+ 00F8 ; xBh - ais 0024+ 00F8 ; xCh - h 0025+ 00F8 ; xDh - könnte für x-mal Wiederholung stehen 0026+ 00F8 ; aber noch nicht implementiert 0027+ 00F8 ; xEh - Liedende 0028+ 00F8 ; xFh - Tabellenende 0029+ 00F8 0030+ 00F8 tabelle: 0031+ 00F8 0032+ 00F8 ;komm in meine Liebeslaube 0033+ 00F8 D8 .DB 0D8h 0034+ 00F9 56 .DB 56h 0035+ 00FA 55 .DB 55h 0036+ 00FB 56 .DB 56h 0037+ 00FC 98 .DB 98h 0038+ 00FD A5 .DB 0A5h 0039+ 00FE A1 .DB 0A1h 0040+ 00FF D8 .DB 0D8h 0041+ 0100 F0 .DB 0F0h 0042+ 0101 EE .DB 0EEh ;Ende Lied 1 0043+ 0102