DATA SEGMENT
msg DB 0DH,0AH,'[ 1 2 3 4 5 6 7 ]'
DB 0DH,0AH,' [ q w e r t y u ]'
DB 0DH,0AH,'_________________'
DB 0DH,0AH,'9: EXIT'顷局段
DB 0DH,0AH,'_________________','$'
********音调******后面用到-1判断音乐播是否放完
sound_0 DW -1
sound_11 DW 441,-1
sound_12 DW 495,-1
sound_13 DW 556,-1
sound_14 DW 589,-1
sound_15 DW 661,-1
sound_16 DW 742,-1
sound_17 DW 833,-1
sound_1 DW 882,-1
sound_2 DW 990,-1
sound_3 DW 1112,-1
sound_4 DW 1178,-1
sound_5 DW 1322,-1
sound_6 DW 1484,-1
sound_7 DW 1655,-1
timeDW 25
DATA ENDS
************************
STACK SEGMENT
Db 200 DUP ('STACK')
STACK ENDS
***********************
CODE SEGMENT
ASSUME DS:DATA,SS:STACK,CS:CODE
START:
MOV AX,DATA
MOV DS,AX
MOV aH,0
MOV AL,00
INT 10H
*****定义一个宏*****
SHOW MACRO b
LEA DX,b
MOV AH,9
INT 21H
ENDM
********一个声音宏********
onesound macro soundis,jumpis,letteris
CMP AL,letteris
JNZ jumpis
LEA SI,soundis
LEA BP,DS:time
CALL MUSIC
JMP input
ENDM
show msg
INPUT: MOV AH,01H
INT 21H
CMP AL,'9'
jnz go
mov ah,4ch
int 21h
go: onesound sound_11,a0,'q'
a0: onesound sound_12,b0,'w'
b0: onesound sound_13,c0,'e'
c0: onesound sound_14,d0,'r'
d0: onesound sound_15,e0,'雀誉t'
e0: onesound sound_16,f0,'y'
f0: onesound sound_17,g0,'u'
g0: onesound sound_1,h0,'1'
h0: onesound sound_2,i0,'2'
i0: onesound sound_3,j0,'3'
j0: onesound sound_4,k0,'4'
k0: onesound sound_5,l0,'5'
l0: onesound sound_6,m0,'6'
m0: onesound sound_7,n0,'7'
n0: onesound sound_0,o0,al
o0: jmp input
********************发声腊仿
GENSOUND PROC NEAR
-------------
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DI
--------------
MOV AL,0B6H
OUT 43H,AL
MOV DX,12H
MOV AX,348ch
DIV DI
OUT 42H,AL
MOV AL,AH
OUT 42H,AL
IN AL,61H
MOV AH,AL
OR AL,3
OUT 61H,AL
WAIT1: MOV CX,3314
call waitf
DELAY1: DEC BX
JNZ WAIT1
MOV AL,AH
OUT 61H,AL
----------------
POP DI
POP DX
POP CX
POP BX
POP AX
-------------------
RET
GENSOUND ENDP
**************************
waitf proc near
push ax
waitf1:
in al,61h
and al,10h
cmp al,ah
je waitf1
mov ah,al
loop waitf1
pop ax
ret
waitf endp
************************
MUSIC PROC NEAR
PUSH DS
SUB AX,AX
PUSH AX
FREG: MOV DI,[SI]
CMP DI,-1音乐是否放完?
JE END_MUS
MOV BX,DS:[BP]
CALL GENSOUND
ADD SI,2
ADD BP,2
JMP FREG
END_MUS:
RET
MUSIC ENDP
CODE ENDS
**********************
END START
有图,Q我1352282
设计任务及要求
1. 以8255接八个开关K1~K8,做电子琴按键输入。
2. 以8253控制扬声器,拨动不同的开关,发出相应的音阶。
要求: K1—静音
K2—发si的音493Hz
K3—发la的音440Hz
K4—发sol的音392Hz
K5—发fa的音349Hz
K6—发mi的音329Hz
K7—发re的音293Hz
K8—发do的音261Hz
二. 方案比较和认证
通过8255和8253来实现电子琴模拟,主要可以分成两部分,分别为输入部分和发音部分。输入部分主要是由8255和8个常开型开关来完成。常开型开关如右图。8个常开型开关K1~K8与8255的A口PA0~PA7相接,不触动开关时,为高电平输入,当按下开关时,就接地,为低电平输入。例如当K1键按下时,从8255中A口输入的数为11111110B,十六进制为0FEH。每一个开关含段按下时,都对应一个ASCII码,如下表所示:
开 关 K1 K2 K3 K4 K5 K6 K7 K8
对应数据 0FEH 0FDH 0FBH 0F7H 0EFH 0DFH 0BFH 7FH
对应频率 静音 493 Hz 440 Hz 392 Hz 349 Hz 329 Hz 293 Hz 261 Hz
输入部分的硬件实现比较简单,所以说主要还是在发音部分。在设计中驱动扬声器地声的主要有两种方式,分别是以位触发和定时器控制。下面就这两种肢塌不同的方式确定两个不同的设计方案。
方案1:
发声采用位触发方式。电路原理图如下所示。程序直接控制PPI(8255可编程序外围接口芯片)的输出控制寄存器(I/O端口为61H)的第一位,使该位按所需的频率进行1和0的交替变化,从而产生一串脉冲控制波形,这些脉冲经过放大后驱动扬声器发出声音。
可以利用软件延时来控制所产生的脉冲波形的长度和脉宽,就可以实现产生不同频率和不同音长的声音。软件实现的程序如下:
IN AL,61H
MOV AH,AL
AND AL,0FCH ;关断定历老圆时器通道2的门控
SOUND:XOR AL,2 ;触发61H端口第1位
OUT 61H,AL
MOV CX,DX ;(DX)=控制脉冲的计数值
WAIT: LOOP WAIT ;延时循环
DEC BX ;(BX)=脉冲持续的时间
JNZ SOUND
MOV AL,AH
OUT 61H,AL ;恢复61H端口
#include<AT89X51.H>unsigned char table[]={0x3f,0x60,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}unsigned char tempunsigned char keyunsigned char i,junsigned char STH0unsigned char STL0unsigned int code tab[]={64021,64103,64260,64400,64524,64580,64684,64777,64820,64898,64968,65030,65058,65110,65157,65178}void main(void){ TMOD=0x01 ET0=1 EA=1 while(1) { P3=0xff P3_4=0 temp=P3 temp=temp&0x0f粗渗 if(temp!=0x0f) { for(i=50i>0i--) for(j=200j>0j--) temp=P3 temp=temp&0x0f if(temp!=0x0f) { temp=P3 temp=temp&0x0f switch(temp) { case 0x0e: key=0 break case 0x0d: key=1 break case 0x0b: key=2 break case 0x07: key=3 break } temp=P3 P1_0=~P1_0 P0=table[key] STH0=tab[key]/256 STL0=tab[key]%256 TR0=1 temp=temp&0x0f while(temp!=0x0f) { temp=P3 temp=temp&0x0f } TR0=0 } } P3=0xff P3_5=0 temp=P3 temp=temp&0x0f if(temp!=0x0f) { for(i=50i>0i--) for(j=200j>滑凳源0j--) temp=P3 temp=temp&0x0f信态 if(temp!=0x0f) { temp=P3 temp=temp&0x0f switch(temp) { case 0x0e: key=4 break case 0x0d: key=5 break case 0x0b: key=6 break case 0x07: key=7 break } temp=P3 P1_0=~P1_0 P0=table[key] STH0=tab[key]/256 STL0=tab[key]%256 TR0=1 temp=temp&0x0f while(temp!=0x0f) { temp=P3 temp=temp&0x0f } TR0=0 } } P3=0xff P3_6=0 temp=P3 temp=temp&0x0f if(temp!=0x0f) { for(i=50i>0i--) for(j=200j>0j--) temp=P3 temp=temp&0x0f if(temp!=0x0f) { temp=P3 temp=temp&0x0f switch(temp) { case 0x0e: key=8 break case 0x0d: key=9 break case 0x0b: key=10 break case 0x07: key=11 break } temp=P3 P1_0=~P1_0 P0=table[key] STH0=tab[key]/256 STL0=tab[key]%256 TR0=1 temp=temp&0x0f while(temp!=0x0f) { temp=P3 temp=temp&0x0f } TR0=0 } } P3=0xff P3_7=0 temp=P3 temp=temp&0x0f if(temp!=0x0f) { for(i=50i>0i--) for(j=200j>0j--) temp=P3 temp=temp&0x0f if(temp!=0x0f) { temp=P3 temp=temp&0x0f switch(temp) { case 0x0e: key=12 break case 0x0d: key=13 break case 0x0b: key=14 break case 0x07: key=15 break } temp=P3 P1_0=~P1_0 P0=table[key] STH0=tab[key]/256 STL0=tab[key]%256 TR0=1 temp=temp&0x0f while(temp!=0x0f) { temp=P3 temp=temp&0x0f } TR0=0 } } }}
void t0(void) interrupt 1 using 0{ TH0=STH0TL0=STL0P1_0=~P1_0}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)