汇编-电脑钢琴实现方法及代码
计算机钢琴
一 钢琴功能
程序运行时,是PC成为一架可弹奏的“钢琴”,当按下数字键1~8,一次发出1,2,3,4,5,6,7,i八个音调。按ctrl+c退出程序。
二 实现原理
1 PC机扬声器电路如下图
通过给8253定时器装入不同的计数值,可使其输入不同频率的波形。与门打开后,经过放大器的放大作用,便可驱动扬声器发出不同的音调。要使该音调的声音持续一段时间,需插入一段演示程序,之后再将扬声器切断。
2 控制扬声器发声步骤
2.1 计算频率值
以120000H为被除数,查频率表(已给出)中某项作为除数,所得商即为频率值
2.1 设置控制字(8位:10110110B)
假设此控制字八位由高到底P7-P0,则:
P7P6 = 10: 选择2号计数器
P5P4 = 11: 读/写两个字节(先低位后高位)
P3P2P1 = 011: 选择计时器工作方式3
P0 = 0: 设置计数器的工作码制为二进制
具体代码为:
MOV AL,10110110B;
OUT 43H,AL
若想进一步了解8253计数器,可自行查阅相关资料(网上一大把),这里不多做说明。
2.2 将频率值送入计数器
MOV AL,...
OUT 42H,AL; 设置计数器低8位
MOV AL,...
OUT 42H,AL; 设置计数器高8位
2.3 打开与门
IN AL,61H; 取出61H端口数据
OR AL,03H; 设置61H端口最低两位为 11
2.4 延时
;子程序名:DELAY ;功能: 延迟一定时间 DELAY PROC PUSH CX MOV CX,03H; DELAYLOOP1: PUSH CX; MOV CX,0FFFFH DELAYLOOP2: LOOP DELAYLOOP2 POP CX; LOOP DELAYLOOP1 POP CX RET DELAY ENDP
2.5 关闭与门
IN AL,61H;
AND AL,0FCH; 设置61H端口最低两位为 00
3 频率表(键入字符、音符、频率值的对应关系)
三 实现代码
DATA SEGMENT RATETABLE DW 524,588,660,698,784,880,988,1048 ;频率表 MSG DB 'Please input char 1 ~ 8' ;提示信息 DB 'to get the corresponding voice!',0ah,0dh DB 'Quit with (ctrl C):',0ah,0dh,'$' DATA ENDS STCK SEGMENT STACK db 100 DUP(?) STCK ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX,DATA; MOV DS,AX; LEA DX,MSG; 输出提示信息 MOV AH,09H; INT 21H; ;输入音符 INPUT: MOV AH,01H; INT 21H; CMP AL,03H; 若输入(ctrl + c),则退出程序 JZ QUIT CALL PIANOFUC; 调用程序,根据输入音符发出相应声音 JMP INPUT ;退出程序 QUIT: MOV AH,4CH; INT 21H; ;子程序名:PIANOFUC ;功能: 将AL寄存器中字符1、2、3、4、5、6、7、i的ASCII作为音符 ; 查频率表(RATETABLE),使扬声器发出不同频率的声音 PIANOFUC PROC PUSH BX; PUSH AX; PUSH DX; CMP AL,'1' JZ ONE CMP AL,'2' JZ TWO CMP AL,'3' JZ THREE CMP AL,'4' JZ FOUR CMP AL,'5' JZ FIVE CMP AL,'6' JZ SIX CMP AL,'7' JZ SEVEN CMP AL,'8' JZ EIGHT JMP QUIT_PIANOFUC ONE: MOV BX,0 JMP OUT_VOI TWO: MOV BX,2 JMP OUT_VOI THREE: MOV BX,4 JMP OUT_VOI FOUR: MOV BX,6 JMP OUT_VOI FIVE: MOV BX,8 JMP OUT_VOI SIX: MOV BX,10 JMP OUT_VOI SEVEN: MOV BX,12 JMP OUT_VOI EIGHT: MOV BX,14 OUT_VOI: MOV AX,0000H; 常熟120000H做被除数 MOV DX,0012H; DIV RATETABLE[BX]; 计算频率值 MOV BX,AX; 将之存入BX寄存器 MOV AL,10110110B; 设置定时器工作方式 OUT 43H,AL MOV AX,BX; OUT 42H,AL; 设置低位 MOV AL,AH; 设置高位 OUT 42H,AL IN AL,61H; 打开与门 OR AL,03H; OUT 61H,AL CALL DELAY IN AL,61H; 关闭与门 AND AL,0FCH; OUT 61H,AL; ;退出程序 QUIT_PIANOFUC: POP DX POP AX POP BX; RET PIANOFUC ENDP ;子程序名:DELAY ;功能: 延迟一定时间 DELAY PROC PUSH CX MOV CX,03H; DELAYLOOP1: PUSH CX; MOV CX,0FFFFH DELAYLOOP2: LOOP DELAYLOOP2 POP CX; LOOP DELAYLOOP1 POP CX RET DELAY ENDP CODE ENDS END START