⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elekeyboard.asm

📁 电子钟
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;;;;;;;;;;;;;;;;;;;;电子琴;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;功能:
;      1.电子琴基本音阶的发生,低音、高音、中音
;      2.播放音乐
;      3.播放音阶时指示灯亮 
;-----------------------------------------------------------------
DRAW MACRO START_X,START_Y,END_X,END_Y,COLOR		;画矩形的宏程序
	LOCAL DRAW_NEXT
	PUSH AX
	PUSH BX
	PUSH CX
	PUSH DX 
	MOV AH,0CH			
	MOV AL,COLOR				
	MOV BH,0				
	MOV CX,START_X			
	MOV DX,START_Y
DRAW_NEXT:
	INT 10H
	INC CX
	CMP CX,END_X
	JNE DRAW_NEXT
	MOV CX, START_X
	INC DX
	CMP DX,END_Y
	JNE DRAW_NEXT
	POP DX
	POP CX
	POP BX
	POP AX	
	ENDM
;--------------------------------------------------------------
DRAWSQRE MACRO START_X,START_Y,END_X,END_Y,COLOR		;画出边框的宏程序
	LOCAL ROW_UP,ROW_DOWN,RANK_LEFT,RANK_RIGHT
	PUSH AX
	PUSH BX
	PUSH CX
	PUSH DX
	PUSH SI
	MOV AH,0CH
	MOV AL,COLOR
	MOV BH,0
	MOV CX,START_X
	MOV DX,START_Y
ROW_UP:							;画上边沿
	INT 10H
	INC CX
	CMP CX,END_X
	JNE ROW_UP
RANK_RIGHT:     				;右边沿
	INT 10H
	INC DX
	CMP DX,END_Y
	JNE RANK_RIGHT
	MOV CX, START_X
	MOV SI,END_X
	INC SI
ROW_DOWN:						;下边沿
	INT 10H
	INC CX
	CMP CX,SI
	JNE ROW_DOWN 
	MOV DX,START_Y
	MOV CX,START_X 
RANK_LEFT:						;左边沿
	INT 10H
	INC DX
	CMP DX, END_Y
	JNE RANK_LEFT
	POP SI
	POP DX
	POP CX
	POP BX
	POP AX
	
	ENDM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;数据段
DATA SEGMENT
       ;定义在屏幕绘制字

       START_COL DB ?                     ;存储起始行

       TEXT  DB 16   ;起始行                                                           
             DB 2          ;起始列                                                   
             DB 06H      ;字体颜色                                                   
             DB 0ffh,'WELCOME TO THE PIANO',0ffh     ;显示字
             DB 0FFH, 'press a to j to piano'  
             DB 0FFH,0FFH,'press shfit to choose tune',0ffh
             db 0ffh,'press 1 to 5 to choose music'     
 
       ;白色琴键坐标

    ST_LX DW  50,61,72,83,94,105,116
    ST_MX DW  127,138,149,160,171,182,193
    ST_HX DW  204,215,226,237,248,259,270
    ST_Y   DW  50
    ED_LX DW  60,71,82,93,104,115,126
    ED_MX DW  137,148,159,170,181,192,203
    ED_HX DW  214,225,236,247,258,269,280
    ED_Y   DW  90

       ;黑色琴键坐标

    BT_X  DW 57,68,90,101,112
           DW 134,145,167,178,189 
           DW 211,222,244,254,265
    BT_Y  DW  50
    BD_X DW  64,75,97,108,119
          DW  141,152,174,185,196
          DW  218,229,251,262,273
    BD_Y  DW  70

;音乐频率值

       LOWD  DW 131
       LOWDD DW 147,165,175,196,220,247

       MID  DW 262
       MIDD DW 294,330,349,392,440,494
       
       HGH  DW 523
       HGHD DW 587,659,797,783,879,987,1046

    KEYFLAG DB 1                                       ;标记低(0)、中(1)、高(2)音键
       KEYNUM DW 1                                       ;存储1~7
    DELAY_TIME DW 1000                          ;延时
       SONG DW 100                                         ;保存所选的自动演奏的曲目
       TUNE DW 1                                             ;标记c
       AUDIO DW 1                                          ;标记低(1)、中(2)、高音(3)

;自动演奏的歌曲频率和延时

MUS_FREQ1 DW 440,392,330,392,523,440,392,440
         DW 330,392,440,392,330,262,220,392
         DW 330,2 DUP(294),330,2 DUP(392),440,330
         DW 294,262,392,330,294,262,220,262,196
         DW -1
MUS_TIME1 DW 37,12,3 DUP(25),2 DUP(12),50
         DW 25,2 DUP(12 ),2 DUP(25),4 DUP(12 ),50
         DW 37 ,12 ,25,2 DUP(12 ),2 DUP(25),50
         DW 37 ,5 DUP(12 ),100
         
MUS_FREQ2 DW 196,262,330,392,330,294,262,262,262,262,220,196,196,196,131,659,392,392,392,440,392,392
          DW 294,330,294,262,294,440,392,523,392,392,392,440,392,330,294,262,262,294,220,196,220,523,294,330,294,330,262,262,-1
          

MUS_TIME2 DW 8,8,16,8,16,5 dup(8),2,2,16,8,8,16,4 dup(8)
          dw 2,2,8,2,2,8,8,16,8 dup(8),2,2,16,8,8,2,2,16,8,8,8
MUS_FREQ3 DW 262,262,294,330,330,349,392,440,392,330
         DW 392,349,330,294,349,330,294,262
         DW 262,262,294,330,330,349,392,440,392,330
         DW 392,349,330,294,330,294,262,196
         DW 392,349,330,294,196,196,349,330,294,262
         DW 392,349,330,294,196,196,349,330,294,262
         DW 262,262,294,330,330,349,392,440,392,330
         DW 392,349,330,294,330,294,262
         DW -1
MUS_TIME3 DW 3 DUP(25,2 DUP(12)),50
         DW 2 DUP(25,2 DUP(12),50)
         DW 3 DUP(25,2 DUP(12)),50
         DW 2 DUP(25,2 DUP(12)),2 DUP (50)
         DW 3 DUP(25,2 DUP(12)),50
         DW 3 DUP(25,2 DUP(12)),50  
         DW 3 DUP(25,2 DUP(12)),50
         DW 2 DUP(25,2 DUP(12)),50

MUS_FREQ4 DW 262,262,294,330,330,294,262,262,220,196
        DW 262,294,330,294,262,294
        DW 262,294,330,330,294,294,262,220,220,294,262,262,220,196
        DW 196,220,220,262,262,294,294,262,220
        DW 294,330,294,262,262,294,262,220,196,220
        DW 196,220,262,294,330,392,294,330,262,294,262,220
        DW 220,294,247,220,196,196
        DW 4 DUP(392),330,392,440,440,392,330
        DW 5 DUP(440),392,392,330,294
        DW 440,392,440,392,330,294,330,294,262,220
        DW 4 DUP(294),262,220,196
        DW 2 DUP(440,392),2 DUP(330,294),262,220
        DW 3 DUP(294),262,220,392
        DW -1

MUS_TIME4 DW 3 DUP(20,10,10),50
       DW 20,10,20,10,10,80
       DW 20,10,20,10,10,3 DUP(20,10),20,20,80
       DW 20,10,10,20,20,20,10,10,40
       DW 20,10,20,20,10,5,5,10,10,40
      DW 20,10,2 DUP(20,10,10),10,5,5,20
       DW 20,20,20,10,10,80
       DW 10,20,10,20,10,10,40,10,10,20
       DW 8 DUP(10),80
       DW 20,10,10,20,20,4 DUP(10),40
       DW 15,5,10,10,20,20,80
       DW 20,10,10,20,20,4 DUP(10),40
       DW 40,20,20,40,40,100
 MUS_FREQ5  DW 523,587,659,196,523,659,587,196,247,587,523,523,247
            DW 523,523,196,220,523,523,220,196,196,523,659,797,659,523,587,587,-1
  MUS_TIME5 DW 11 DUP(20),40,10,10,40,20,20,11 DUP(20),5,5,40

 MUS_FREQ6 DW ?          ;存储乐曲频率 
 MUS_TIME6 DW ?           ;存储乐曲时间


DATA ENDS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;代码段
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CODE SEGMENT

     ASSUME DS:DATA,CS:CODE
MAIN PROC FAR
;主程序
START:  
       CALL INIT                                       ;调用初始化程序
NEW_SCAN:       
       CALL SCAN_KEY                            ;扫描所按下的键
       
       CMP SONG,100                                 ;判断是否按下了自动播放的歌曲键
       JE  HAND_PLAY                            ;若不是,继续判断

       CALL PLAY_SONG                          ;若是,演奏音乐
       JMP NEW_SCAN                              ;演奏结束,重新扫描有无键按下

HAND_PLAY:

       CMP KEYNUM,100                           ;判断是否手动演奏
       JZ  NEW_SCAN                              ;若不是,重新扫描有无键按下
                                                              ;若是,进行按键处理
       PUSH BX                     
       MOV BX,KEYNUM      
       CALL KEY_DOWN                          ;在屏幕上显示按下状态
       POP BX
       CALL LOAD_AUDIO ;判断高低音,并装入对应频率段地址到BX中
       PUSH SI
       MOV SI,KEYNUM
       MOV DI,[BX+SI]
       CALL GEN_HAND                            ;发声
       POP SI
       PUSH BX

       MOV BX,KEYNUM                           ;在屏幕上显示弹起状态
       CALL KEY_UP
       POP BX
       JMP NEW_SCAN                              ;重新扫描有无键按下,直到按下ESC键

MAIN ENDP

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;手动演奏发声程序
GEN_HAND PROC NEAR
;IN:DI
       PUSH AX
       PUSH BX
       PUSH CX
       PUSH DX
       PUSH DI
       MOV AL,90H       ;初始化
       MOV DX,28BH
       OUT DX,AL
       MOV AL,0B6H                                 ;定时器初始化
       OUT 43H,AL
       MOV DX,12H
       MOV AX,348CH
       DIV DI
       OUT 42H,AL                                    ;定时器送处值
       IN AL,61H                                        ;开扬声器
       MOV AL,AH
       OUT 42H,AL
       IN AL,61H
       MOV AH,AL
       OR AL,3
       OUT 61H,AL
WAIT1:  
       CALL WAITF                                   ;调用延时程序
       IN AL,60H                                 
       TEST AL,80H                               ;查询键是否放开
       JNZ LED_OFF                                         ;未放开继续查询
       JMP WAIT1
LED_OFF:
       MOV AL,0                                   ;放开则关扬声器
       OUT 61H,AL
       POP DI
       POP DX
       POP CX
       POP BX
       POP AX

   RET

GEN_HAND ENDP

;------------------------------------------------------------------------
PIANO_DRAW  PROC NEAR   	 ;绘制琴键
 	LEA 	SI,ST_LX     				;载入白色起始点地址
      	LEA 	DI,ED_LX    			;载入白色结束点地址
       	MOV 	CX,21    				;白键数目
NEXT_DRAW:
     	DRAW 	[SI],ST_Y,[DI],ED_Y,0FH  	;调用宏定义画白键
     	DRAW 	[SI],90,[DI],93,07H  		;阴影
      	ADD 	SI,2    					;下一个键
      	ADD 	DI,2
      	LOOP 	NEXT_DRAW

       	LEA 	SI,BT_X    		;载入黑色起始点地址
       	LEA 	DI,BD_X    		;载入黑色结束点地址
       	MOV 	CX,15    		;黑键数目
NEXT_BLOCK:
       	DRAW 	[SI],BT_Y,[DI],BD_Y,00H
       	ADD 	SI,2
       	ADD 	DI,2
       	LOOP 	NEXT_BLOCK
 	RET
PIANO_DRAW ENDP
;----------------------------------------------------------------------
KEY_DOWN PROC NEAR    	;键按下时,在屏幕上显示
	PUSH 	SI
 	PUSH 	DI
 	CALL 	LOAD    			;载入所按下键在屏幕上的位置
 	DRAW [SI+BX],90,[DI+BX],92,0FH
        DRAW [SI+BX],92,[DI+BX],94,07H
 	POP 	DI
 	POP 	SI
 	RET
KEY_DOWN ENDP
;----------------------------------------------------------------------
KEY_UP PROC NEAR    		;键弹起时,恢复正常状态
 	PUSH 	SI
 	PUSH 	DI
 	CALL 	LOAD    			;载入所弹起键在屏幕上的位置
  	DRAW [SI+BX],90,[DI+BX],93,07H  ;恢复阴影
        DRAW [SI+BX],93,[DI+BX],94,05H  ;恢复背景色
 	POP 	DI
 	POP 	SI
  	RET
KEY_UP ENDP
;-------------------------------------------------------------------------
LOAD PROC NEAR     					;载入键在屏幕上的位置
 	CMP 	KEYFLAG,00H    			;判断是否是低音键
 	JNZ  	LOAD_HGH    			;继续判断
 	LEA 	SI,ST_LX    			;载入低音键起始坐标首地址
     	LEA 	DI,ED_LX    		;载入低音键结束坐标首地址
 	JMP 	LOAD_END    			;载入结束
LOAD_HGH:
 	CMP 	KEYFLAG,02H    		;判断是否是高音键
 	JNZ 	LOAD_MID    			;继续判断
 	LEA 	SI,ST_HX    			;载入高音键起始坐标首地址
     	LEA 	DI,ED_HX    			;载入高音键结束坐标首地址
 	JMP 	LOAD_END
LOAD_MID:
 	LEA 	SI,ST_MX    			;载入中音键起始坐标首地址
 	LEA 	DI,ED_MX    			;载入中音键结束坐标首地址
LOAD_END: 
  	RET
LOAD ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SCAN_KEY PROC NEAR
;检查按键状态,并存入对应的变量和寄存器
       MOV SI,100
       MOV DI,100

       MOV KEYNUM,100                          ;赋初值      
       MOV AH,0                                       ;读键盘
       INT 16H
       MOV DL,AH 

       CALL SCAN_SONG                         ;判断是否是自动播放键(大键盘数字键1~5)
       CMP AH,01H                                    ;是否是结束键
       JNE FLAG_SCAN                      ;若不是继续检测
       CALL EXIT                                      ;若是则退出
FLAG_SCAN:                                          

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -