logo资料库

简易电子琴程序设计.doc

第1页 / 共8页
第2页 / 共8页
第3页 / 共8页
第4页 / 共8页
第5页 / 共8页
第6页 / 共8页
第7页 / 共8页
第8页 / 共8页
资料共8页,全文预览结束
STACK SEGMENT DB 1024 DUP(?) STACK ENDS DATA SEGMENT STR0 DB 13,10,3 DUP(9),' [-1-2-3-4-5-6-7-]$' STR1 DB 13,10,3 DUP(9),'H [ Q W E R T Y U ]$' STR2 DB 13,10,3 DUP(9),'M [ A S D F G H J ]$' STR3 DB 13,10,3 DUP(9),'L [ Z X C V B N M ]$' SAVE DW 1024 DUP(0FFFFH) TUNE DW 220,247,278,294,330,371,416 DW 441,495,556,589,661,742,833 DW 882,990,1112,1178,1322,1484,1655 ;低音 ;中音 ;高音 ;按键状态缓存,用于判断是否有手动按键,1 为有,0 为无 ;按键编号缓存,用于提取对应的按键位置 ;延时缓存,用于播放时存入 BX 中来计数 KEY_TUNE DW 0 KEYNUM DW 1 DELAY_TIME DW 7000 DATA ENDS CODE SEGMENT ASSUME CS:CODE ,DS:DATA START:MOV AX,DATA MOV DS,AX MOV SI,OFFSET STR0 CALL SHOW MOV SI,OFFSET STR1 CALL SHOW MOV SI,OFFSET STR2 CALL SHOW MOV SI,OFFSET STR3 CALL SHOW MOV CX,0 MOV SI,OFFSET SAVE NEW_SCAN: MOV AH,0 INT 16H MOV DL,AL ASCII 码来检测 CMP AH,01H JNE FLAG_SCAN CALL EXIT FLAG_SCAN: KEY_L1: CMP DL,'Z' JNE KEY_L2 ;读键盘,键盘扫描码存入 AH,ASCII 码存入 AL ;AL 中的 ASCII 码存入 DL,为了便于修改,通过 ;是否是结束键,ESC 键作为结束键,其扫描码为 01H ;若不是继续检测 ;若是则退出 ;是否是 Z ;不是则继续扫描
MOV KEYNUM,0 MOV KEY_TUNE,1 JMP SCAN_END KEY_L2: CMP DL,'X' JNE KEY_L3 MOV KEYNUM,2 MOV KEY_TUNE,1 JMP SCAN_END KEY_L3: CMP DL,'C' JNE KEY_L4 MOV KEYNUM,4 MOV KEY_TUNE,1 JMP SCAN_END KEY_L4: CMP DL,'V' JNE KEY_L5 MOV KEYNUM,6 MOV KEY_TUNE,1 JMP SCAN_END KEY_L5: CMP DL,'B' JNE KEY_L6 MOV KEYNUM,8 MOV KEY_TUNE,1 JMP SCAN_END KEY_L6: CMP DL,'N' JNE KEY_L7 MOV KEYNUM,10 MOV KEY_TUNE,1 JMP SCAN_END KEY_L7: CMP DL,'M' JNE KEY_1 MOV KEYNUM,12 MOV KEY_TUNE,1 JMP SCAN_END KEY_1: CMP DL,'A' JNE KEY_2 MOV KEYNUM,14 ;是则改变按键编号缓存 ;改变按键状态缓存 ;键扫描结束 ;是否是 X ;是否是 Y ;是否是 V ;是否是 B ;是否是 N ;是否是 M ;是否是 A
MOV KEY_TUNE,1 JMP SCAN_END KEY_2: CMP DL,'S' JNE KEY_3 MOV KEYNUM,16 MOV KEY_TUNE,1 JMP SCAN_END KEY_3: CMP DL,'D' JNE KEY_4 MOV KEYNUM,18 MOV KEY_TUNE,1 JMP SCAN_END KEY_4: CMP DL,'F' JNE KEY_5 MOV KEYNUM,20 MOV KEY_TUNE,1 JMP SCAN_END KEY_5: CMP DL,'G' JNE KEY_6 MOV KEYNUM,22 MOV KEY_TUNE,1 JMP SCAN_END KEY_6: CMP DL,'H' JNE KEY_7 MOV KEYNUM,24 MOV KEY_TUNE,1 JMP SCAN_END KEY_7: CMP DL,'J' JNE KEY_H1 MOV KEYNUM,26 MOV KEY_TUNE,1 JMP SCAN_END KEY_H1: CMP DL,'Q' JNE KEY_H2 MOV KEYNUM,28 MOV KEY_TUNE,1 ;是否是 S ;是否是 D ;是否是 F ;是否是 G ;是否是 H ;是否是 J ;是否是 Q
JMP SCAN_END KEY_H2: CMP DL,'W' JNE KEY_H3 MOV KEYNUM,30 MOV KEY_TUNE,1 JMP SCAN_END KEY_H3: CMP DL,'E' JNE KEY_H4 MOV KEYNUM,32 MOV KEY_TUNE,1 JMP SCAN_END KEY_H4: CMP DL,'R' JNE KEY_H5 MOV KEYNUM,34 MOV KEY_TUNE,1 JMP SCAN_END KEY_H5: CMP DL,'T' JNE KEY_H6 MOV KEYNUM,36 MOV KEY_TUNE,1 JMP SCAN_END KEY_H6: CMP DL,'Y' JNE KEY_H7 MOV KEYNUM,38 MOV KEY_TUNE,1 JMP SCAN_END KEY_H7: CMP DL,'U' JNE SCAN_END MOV KEYNUM,40 MOV KEY_TUNE,1 SCAN_END: CMP DL,'P' JNZ HAND_PLAY CALL PLAY JMP NEW_SCAN HAND_PLAY: CMP KEY_TUNE,1 0 为无 ;是否是 W ;是否是 E ;是否是 R ;是否是 T ;是否是 Y ;是否是 U ;判断是否按下了自动播放键 ;若不是,继续扫描 ;若是,调用演奏音乐子程序 ;演奏结束,返回 RESTART ;取按键状态缓存值,判断是否手动演奏,1 为有,
JNZ AGAIN;若不是,重新扫描有无键按下 MOV AX,KEYNUM ADD CX,2 MOV BX,CX MOV WORD PTR[SI+BX-2],AX JMP SOUND AGAIN: JMP NEW_SCAN SOUND: LEA BX,TUNE MOV SI,KEYNUM MOV DI,[BX+SI] DI CALL PLAY_MIU JMP NEW_SCAN ;装入对应频率段地址到 BX 中 ;取按键编号缓存值,存入 SI ;取对应编号的音符频率值,存入 ;调用手动发声程序 MOV AH,1 ;直到有字符输入才结束 INT 21H MOV AX,3 ;获取光标信息 INT 10H MOV AH,4CH ;不带返回码结束 INT 21H PLAY_MIU PROC NEAR PUSH AX PUSH BX PUSH CX PUSH DX PUSH DI MOV KEY_TUNE,0 MOV AL,0B6H OUT 43H,AL ;在 8253 的 43 端送出一个控制字 0B6H(10110110B) ;从而对定时器 2 初始化,准备接收计数初值 MOV DX,12H MOV AX,348CH ;1.1931MHZ/给定频率=12348H/给定频率=计数初值 ;12348H 存入 DX:AX 中,作 32 位运算,商存入 AX,余数存入 DX AH DIV DI OUT 42H,AL MOV AL,AH OUT 42H,AL IN AL,61H MOV AH,AL ;DI 中存放给定频率 ;给定时器 2 写入 AX 中存放的计数初值 ;开扬声器 ;把 8255 输出端的 61H 的 0、1 两位置 1,并把端口状态存入 OR AL,3 ;打开扬声器
OUT 61H,AL WAIT1: CALL WAITF ;调用延时 IN AL,60H 码+80H>80H TEST AL,80H JZ WAIT1 MOV AL,AH OUT 61H,AL POP DI POP DX POP CX POP BX POP AX RET PLAY_MIU ENDP WAITF PROC NEAR PUSH AX PUSH CX MOV CX,DELAY_TIME WAITF1: ;读取键盘扫描码,按下和放开都有相应的扫描码,放开码=按下 ;AL 和 80H 相与,影响标志位 ;未放开则继续延时 ;恢复 8255 端口 61H 的状态,关扬声器 ;恢复寄存器状态 ;AX 入栈 ;T=DELAY_TIME*15.08US ;读 8255 的 PB 端口 ;检查 PB4 口 ;判断 AL 变化否 ;等待 AL 变化 ;保存 PB4 的新状态(AL 中) ;CX-1 不为 0 则回到 WAITF ;AX 出栈 IN AL,61H AND AL,10H CMP AL,AH JE WAITF1 MOV AH,AL LOOP WAITF1 POP CX POP AX RET WAITF ENDP PLAY PROC LEA BX,TUNE ;装入对应频率段地址到 BX 中 READ: MOV SI,WORD PTR[SAVE] 存入 SI MOV DI,[BX+SI] ADD SAVE ,2 CMP WORD PTR[SAVE],0FFFFH JZ TT PUSH AX ;取按键编号缓存值,
PUSH BX PUSH CX PUSH DX MOV AL,0B6H OUT 43H,AL ;在 8253 的 43 端送出一个控制字 0B6H(10110110B) ;从而对定时器 2 初始化,准备接收计数初值 MOV DX,12H MOV AX,348CH ;1.1931MHZ/给定频率=12348H/给定频率=计数初值 ;12348H 存入 DX:AX 中,作 32 位运算,商存入 AX,余数存入 DX AH DIV DI OUT 42H,AL MOV AL,AH OUT 42H,AL IN AL,61H MOV AH,AL OR AL,3 OUT 61H,AL CALL WAITF CALL WAITF CALL WAITF CALL WAITF CALL WAITF CALL WAITF CALL WAITF CALL WAITF CALL WAITF CALL WAITF MOV AL,AH OUT 61H,AL ;DI 中存放给定频率 ;给定时器 2 写入 AX 中存放的计数初值 ;开扬声器 ;把 8255 输出端的 61H 的 0、1 两位置 1,并把端口状态存入 ;打开扬声器 ;恢复 8255 端口 61H 的状态,关扬声器 POP DX ;恢复寄存器状态 POP CX POP BX POP AX LOOP READ TT: MOV CX,0 JMP NEW_SCAN RET PLAY ENDP EXIT PROC NEAR MOV AH,4CH
INT 21H RET EXIT ENDP SHOW PROC MOV DX,SI MOV AH,9 INT 21H RET SHOW ENDP CODE ENDS END START
分享到:
收藏