汇编--计算机钢琴实现

                                 计算机钢琴


一 钢琴功能

  程序运行时,是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
 




  • 15
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值