信息对抗技术电子音阶实验

;============================================
; wjtest_changekey2_3.asm
;使9 10 11 13 14 15不发声 ,按键9 播放友谊地久天长 按键10 显示学号
;测试
;============================================

;端口定义
IOY0 EQU 0600H
MY8255_A EQU IOY0+00H2 ;8255的A口地址
MY8255_B EQU IOY0+01H
2 ;8255的B口地址
MY8255_C EQU IOY0+02H2 ;8255的C口地址
MY8255_CON EQU IOY0+03H
2 ;8255的控制寄存器地址

IOY1 EQU 0640H
MY8254_COUNT0 EQU IOY1+00H2 ;8254计数器0端口地址
MY8254_COUNT1 EQU IOY1+01H
2 ;8254计数器1端口地址
MY8254_COUNT2 EQU IOY1+02H2 ;8254计数器2端口地址
MY8254_MODE EQU IOY1+03H
2 ;8254控制寄存器端口地址
SI_YINQU EQU 3006H ;用于装载音区
SI_YINDIAO EQU 3007H ;用于装载音符
SSTACK SEGMENT STACK ;定义堆栈段
DW 256 DUP(?)
SSTACK ENDS

DATA SEGMENT
BASS DW 221,248,278,294,330,371,416 ;A low
DW 248,278,312,330,371,416,467 ;B
DW 131,147,165,175,196,221,248 ;C
DW 147,165,185,196,221,248,278 ;D
DW 165,185,208,221,248,278,312 ;E
DW 175,196,221,234,262,294,330 ;F
DW 196,221,248,262,294,330,371 ;G

	DW 441,495,556,589,661,742,833   ;A middle
	DW 495,556,624,661,742,833,935	 ;B
	DW 262,294,330,350,393,441,495   ;C
	DW 294,330,371,393,441,495,556	 ;D
	DW 330,371,416,441,495,556,624   ;E 
	DW 350,393,441,467,525,589,661   ;F
	DW 393,441,495,525,589,661,742   ;G
	
	DW 882,990,1112,1178,1322,1484,1665   ;A high
	DW 990,1112,1248,1322,1484,1665,1869  ;B 
	DW 525,589,661,700,786,882,990  	  ;C
	DW 589,661,742,786,882,990,1112  	  ;D
	DW 661,742,833,882,990,1112,1248 	  ;E 
	DW 700,786,882,935,1049,1178,1322	  ;F
	DW 786,882,990,1049,1178,1322,1484	  ;G

DTABLE DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H ;数码管段选 0~7
DB 7FH,6FH,77H,7CH,39H,5EH,79H,71H ;8~f
DB 00H,38H,40H,76H ;不显示,L,M,H

FREQ_LIST DW 371,495,495,495,624,556,495,556,624 ;频率表
DW 495,495,624,742,833,833,833,742,624
DW 624,495,556,495,556,624,495,416,416,371
DW 495,833,742,624,624,495,556,495,556,833
DW 742,624,624,742,833,990,742,624,624,495
DW 556,495,556,624,495,416,416,371,495,0
TIME_LIST DB 4, 6, 2, 4, 4, 6, 2, 4, 4 ;时间表
DB 6, 2, 4, 4, 12, 1, 3, 6, 2
DB 4, 4, 6, 2, 4, 4, 6, 2, 4, 4
DB 12, 4, 6, 2, 4, 4, 6, 2, 4, 4
DB 6, 2, 4, 4, 12, 4, 6, 2, 4, 4
DB 6, 2, 4, 4, 6, 2, 4, 4, 12

REC_MUSIC DW 00H,00H,00H,00H,00H,00H,00H,00H ;记录频率
DW 00H,00H,00H,00H,00H,00H,00H,00H
DW 00H,00H,00H,00H,00H,00H,00H,00H
DW 00H,00H,00H,00H,00H,00H,00H,00H
DW 00H,00H,00H,00H,00H,00H,00H,00H
DW 00H,00H,00H,00H,00H,00H,00H,00H

REC_TIME DB 00H,00H,00H,00H,00H,00H,00H,00H ;记录时间
DB 00H,00H,00H,00H,00H,00H,00H,00H
DB 00H,00H,00H,00H,00H,00H,00H,00H
DB 00H,00H,00H,00H,00H,00H,00H,00H
DB 00H,00H,00H,00H,00H,00H,00H,00H
DB 00H,00H,00H,00H,00H,00H,00H,00H

SAVE_SI_BUFF DW 00H; 记录录音存储地址存储
SAVE_SI_TIME DW 00H;时间存储地址存储
KEY_TIME DB 01H;按键时长数据
YINQU DB 00H;音区标志位
YINDIAO DB 00H;音调标志位
NOTE_TIME DB 00H;按键时长标志位

DATA ENDS

CODE SEGMENT
ASSUME CS:CODE,DS:DATA ;初始化数据段和代码段

START: MOV AX, DATA
MOV DS, AX

	MOV SI,OFFSET REC_MUSIC     ;装入录音初始地址
	MOV SAVE_SI_BUFF,SI         
	MOV CL,2EH  ;47个数;清零用

CLEAN_REC: ;录音表清零
MOV AX,00H
MOV [SI],AX
ADD SI,2
LOOP CLEAN_REC
;清完零
MOV SI,OFFSET REC_TIME ;装入时间表地址
MOV SAVE_SI_TIME,SI

	MOV SI,3000H; 				;初始化缓冲区
	MOV AL,00H ;第六个数码管,初始化键值为0 
	MOV [SI+0],AL
	MOV AL,10H ;第五个数码管无显示
	MOV [SI+1],AL
	MOV AL,0AH ;第四个数码管,初始化键值为A 音调
    MOV [SI+2],AL
	MOV AL,10H ;第三个数码管无显示
	MOV [SI+3],AL
	MOV AL,12H ;第二个数码管,初始化键值为M 音区
	MOV [SI+4],AL
	MOV AL,10H ;第一个数码管无显示
	MOV [SI+5],AL
	
	MOV SI,SI_YINQU
	MOV AL,31H
	MOV [SI],AL
	MOV SI,SI_YINDIAO
	MOV AL,00H
	MOV [SI],AL

UUU: mov DX,MY8255_CON ;初始化8255
mov AL,81H;写8255 芯片的控制字,实现工作在方式0,A 端口和B 端口输出,C 端口输入
out DX,AL
MOV DX, MY8254_MODE ;初始化8254工作方式
MOV AL, 36H ;定时器0、方式3
OUT DX, AL

;又是主程序=====
BEGIN: CALL DIS ;调用显示子程序
mov DX,MY8254_Mode ;初始化8254
mov AL,36H ;定时器0、方式3
OUT DX,AL
CALL CLEAR ;清屏
CALL CCSCAN ;扫描
JNZ INK1 ;检测到有键按下
JMP BEGIN ;未检测到有键按下

INK1: CALL DIS
CALL DALLY
CALL DALLY
CALL CLEAR
CALL CCSCAN
JNZ INK2 ;有键按下,转到INK2
JMP BEGIN

;确定按下键的位置
INK2: MOV CH,0FEH
MOV CL,00H
COLUM: MOV AL,CH
MOV DX,MY8255_A
OUT DX,AL
MOV DX,MY8255_C
IN AL,DX
L1: TEST AL,01H ;is L1?
JNZ L2
MOV AL,00H ;L1
JMP KCODE
L2: TEST AL,02H ;is L2?
JNZ L3
MOV AL,04H ;L2
JMP KCODE
L3: TEST AL,04H ;is L3?
JNZ L4
MOV AL,08H ;L3
JMP KCODE
L4: TEST AL,08H ;is L4?
JNZ NEXT
MOV AL,0CH ;L4

;确定键值
KCODE: ADD AL,CL
PUSH AX
CALL QINSTART
;按键弹起
KON: CALL DIS
CMP NOTE_TIME,01H
JNZ COUNT_TIME

K0:
CALL CLEAR
CALL CCSCAN
JNZ KON
CMP NOTE_TIME,01H
JNZ SET
K1: POP AX

NEXT: INC CL
MOV AL,CH
TEST AL,08H
JZ KERR
ROL AL,1
MOV CH,AL
JMP COLUM
KERR: JMP BEGIN

;=按键时长记录===
COUNT_TIME:
CALL DELAY1;
INC KEY_TIME
JMP K0
RET

;===更新录音区和计时区
SET:
MOV SI,SAVE_SI_TIME
MOV AL,KEY_TIME
MOV [SI],AX
INC SAVE_SI_TIME;时间表地址加一
MOV KEY_TIME,00H;按键时长清零方便下一次使用
INC SAVE_SI_BUFF
INC SAVE_SI_BUFF ;记录频率表下移(为空)
JMP K1
RET

;==qin=
QINSTART:
QIN:
CMP AL,0FH;判断键16是否按下 每按一次改变音区
JZ LQU ;按下就去音区段
CMP AL,0BH;判断是否按下键12 按下跳到改音调
JZ JUMP_ADIAO2 ;按下就去改音调
;不需要用到的按键的处理,如果想使用按键,可直接该按键需要跳转的地方
CMP AL,08H;
JZ JUMP_YOUYI ;跳到播歌
CMP AL,09H;
JZ JUMP_XUEHAO;跳到学号
CMP AL,0AH;
JZ UNUSE
CMP AL,0CH;
JZ UNUSE
CMP AL,0DH;
JZ UNUSE
CMP AL,0EH;
JZ UNUSE

DROP_THE_BEAT : ;都没按下去音符
CMP AL,07H ;判断按键8是否按下
JZ JUMP_BEAT ;录音跳转
MOV NOTE_TIME,00H ;按键时长保存标志位
CALL YINFU_BUF ;不是就播放音符
JMP KON
;===跳转过渡
JUMP_BEAT: JMP BEAT ;跳转到播放录音
JUMP_ADIAO2: JMP ADIAO
JUMP_YOUYI: JMP YOUYI
JUMP_XUEHAO: JMP XUEHAO

UNUSE: MOV NOTE_TIME,01H
JMP KON

LQU:
CMP YINQU,00H
JNZ MQU ;不是L转到M
INC YINQU ;设置下一次是中
MOV AL,11H ;显示L
MOV AH,00H
CALL YINQIN_BUF
MOV NOTE_TIME,01H ;按键不保存
JMP KON

MQU:
CMP YINQU,01H
JNZ HQU ;不是M转到H
INC YINQU ;设置下一次是高
MOV AL,12H ;显示M
MOV AH,31H
CALL YINQIN_BUF
MOV NOTE_TIME,01H ;按键不保存
JMP KON

HQU:
CMP YINQU,02H
JNZ LQU ;不是H转到L
MOV YINQU,00H ;设置下一次是低
MOV AL,13H ;显示H
MOV AH,62H
CALL YINQIN_BUF
MOV NOTE_TIME,01H ;按键不保存
JMP KON

ADIAO:
CMP YINDIAO,00H ;检测是否为A调
JNZ BDIAO ;不是则去B
INC YINDIAO ;下一次按键B调
MOV AL,0AH ;数码管显示A
MOV AH,00H ;A区音调地址
CALL YINDIAO_BUF
MOV NOTE_TIME,01H ;不保存按键时间
JMP KON
BDIAO:
CMP YINDIAO,01H ;检测是否为b调
JNZ CDIAO ;不是则去C
INC YINDIAO ;下一次按键去C调
MOV AL,0BH ;数码管显示B
MOV AH,07H ;B区音调地址
CALL YINDIAO_BUF
MOV NOTE_TIME,01H ;不保存按键时间
JMP KON
CDIAO:
CMP YINDIAO,02H ;检测是否为C调
JNZ DDIAO ;不是则去D
INC YINDIAO ;下一次变D调
MOV AL,0CH ;数码管显示C
MOV AH,0EH ;C区音调地址
CALL YINDIAO_BUF
MOV NOTE_TIME,01H ;不保存按键时间
JMP KON
DDIAO:
CMP YINDIAO,03H ;检测是否为D调
JNZ EDIAO ;不是则去e
INC YINDIAO ;下一次去E
MOV AL,0DH ;数码管显示d
MOV AH,15H ;d区音调地址
CALL YINDIAO_BUF
MOV NOTE_TIME,01H ;不保存按键时间
JMP KON
EDIAO:
CMP YINDIAO,04H ;检测是否为E调
JNZ FDIAO ;不是则去F
INC YINDIAO ;下一次去F
MOV AL,0EH ;数码管显示e
MOV AH,1CH ;E区音调地址
CALL YINDIAO_BUF
MOV NOTE_TIME,01H ;不保存按键时间
JMP KON
FDIAO:
CMP YINDIAO,05H ;检测是否为F调
JNZ GDIAO ;不是则去G
INC YINDIAO ;下一次去G
MOV AL,0FH ;数码管显示F
MOV AH,23H ;F区音调地址
CALL YINDIAO_BUF
MOV NOTE_TIME,01H ;不保存按键时间
JMP KON
GDIAO:
CMP YINDIAO,06H ;检测是否为G调
JNZ JUMP_ADIAO ;不是则去A
MOV YINDIAO,00H ;下一次去A
MOV AL,09H ;数码管显示F
MOV AH,2AH ;F区音调地址
CALL YINDIAO_BUF
MOV NOTE_TIME,01H ;不保存按键时间
JMP KON

JUMP_ADIAO: JMP ADIAO
;=键盘扫描============
CCSCAN: MOV AL,00H
MOV DX,MY8255_A
OUT DX,AL
MOV DX,MY8255_C
IN AL,DX
NOT AL
AND AL,0FH
RET
;=清屏================
CLEAR: MOV DX,MY8255_B
MOV AL,00H
OUT DX,AL
RET
;=显示===============
DIS: PUSH AX
MOV SI,3000H
MOV DL,0DFH
MOV AL,DL
AGAIN: PUSH DX
MOV DX,MY8255_A
OUT DX,AL
MOV AL,[SI]
MOV BX,OFFSET DTABLE
AND AX,00FFH
ADD BX,AX
MOV AL,[BX]
MOV DX,MY8255_B
OUT DX,AL
CALL DALLY
INC SI
POP DX
MOV AL,DL
TEST AL,01H
JZ OUT1
ROR AL,1
MOV DL,AL
JMP AGAIN
OUT1: POP AX
RET

;====按键延时=
DALLY: PUSH CX
MOV CX,0006H
T1: MOV AX,009FH
T2: DEC AX
JNZ T2
LOOP T1
POP CX
RET

;===音区
YINQIN_BUF:
MOV SI,3004H ;初始化话音区缓冲区
MOV [SI],AL ;更新音区数码管
MOV SI,SI_YINQU
MOV [SI],AH
RET
;===音调
YINDIAO_BUF:
MOV SI,3002H ;初始化音调
MOV [SI],AL
MOV SI,SI_YINDIAO
MOV [SI],AH
RET
;===音符
YINFU_BUF:
CALL PLAYING
MOV SI,3000H ;初始化音符缓冲
INC AL
MOV [SI],AL
RET
;===发音
PLAYING:
PUSH AX ;AX进堆栈
MOV SI,SI_YINQU
MOV AL,[SI]
MOV SI,SI_YINDIAO
ADD AL,[SI] ;音调+音符
MOV BL,AL
POP AX;保护现场
PUSH AX
ADD AL,BL ;音符加音调
MOV BL,2
IMUL BL ;一个频率是16位的
MOV SI,OFFSET BASS ;装入频率表
ADD SI,AX
MOV DX,0FH;
MOV AX,4240H
DIV WORD PTR [SI] ;取出频率值计算初值
MOV SI,SAVE_SI_BUFF;
MOV [SI],AX
MOV DX,MY8254_COUNT0
OUT DX,AL
MOV AL,AH
OUT DX,AL
POP AX
RET

;=======播放录音
BEAT:
MOV SI,OFFSET REC_MUSIC ;装入频率表
MOV DI,OFFSET REC_TIME ;装入录音时间
; CMP WORD PTR [SI],0 ;判断是否到曲末
; JE JUMP_START
PLAY:
MOV AX,[SI] ;取频率
MOV DX,MY8254_COUNT0
OUT DX,AL ;把频率输入8254
MOV AL,AH
OUT DX,AL
MOV DL,[DI] ;取出演奏时间
CALL DELAYDL
CALL DELAYBU
CALL QUITE
CALL DELAYBU
CALL DELAYBU
CALL DELAYBU
CALL DELAYBU
ADD SI,2
INC DI
CMP WORD PTR [SI],0 ;判断是否到曲末
JE JUMP_START
JMP PLAY

JUMP_START: JMP START
;==不发声=
QUITE:
MOV DX,MY8254_MODE
MOV AL,36H
OUT DX,AL
ret
;===========播放友谊地久天长 ====
YOUYI:
YOUYIBEGIN: MOV SI,OFFSET FREQ_LIST ;装入频率表起始地址
MOV DI,OFFSET TIME_LIST ;装入时间表起始地址
YOUYI_PLAY: MOV DX,0FH ;输入时钟为1MHz,1M = 0F4240H
MOV AX,4240H
DIV WORD PTR [SI] ;取出频率值计算计数初值,0F4240H / 输出频率
MOV DX,MY8254_COUNT0
OUT DX,AL ;装入计数初值
MOV AL,AH
OUT DX,AL
MOV DL,[DI] ;取出演奏相对时间,调用延时子程序
CALL DELAY_PLAY
ADD SI,2
INC DI
CMP WORD PTR [SI],0 ;判断是否到曲末?
JE JUMP_START
JMP YOUYI_PLAY

;======学号=
XUEHAO:
XUEHAO_SHOW:
PUSH AX
MOV SI,3000H; ;初始化缓冲区
MOV AL,00H ;第六个数码管为0
MOV [SI+0],AL
MOV AL,07H ;第五个数码管显示7
MOV [SI+1],AL
MOV AL,07H ;第四个数码管显示7
MOV [SI+2],AL
MOV AL,07H ;第三个数码管显示7
MOV [SI+3],AL
MOV AL,07H ;第二个数码管显示7
MOV [SI+4],AL
MOV AL,07H ;第一个数码管显示7
MOV [SI+5],AL

	MOV SI,SI_YINQU
	MOV AL,31H
	MOV [SI],AL
	MOV SI,SI_YINDIAO
	MOV AL,00H
	MOV [SI],AL
	
	mov DX,MY8255_CON ;初始化8255
	mov AL,81H;写8255 芯片的控制字,实现工作在方式0,A 端口和B 端口输出,C 端口输入
	out DX,AL		
	MOV DX, MY8254_MODE			;初始化8254工作方式
	MOV AL, 36H					;定时器0、方式3
	OUT DX, AL
	POP AX
	JMP BEGIN

;延时1
DELAY1 PROC
PUSH CX ;保护
T00: MOV CX,0010H
T11: MOV AX,00F0H
T22: DEC AX
JNZ T22
LOOP T11
POP CX
RET
DELAY1 ENDP
;=根据DL延时=
DELAYDL PROC
DL0: MOV CX,0015H
DL1: MOV AX,00F5H
DL2: DEC AX
JNZ DL2
Loop DL1
DEC DL
JNZ DL0
RET
DELAYDL ENDP
;=延时补充=====
DELAYBU PROC
PUSH CX ;
BU0: MOV CX,0070H
BU1: MOV AX,00F0H
BU2: DEC AX
JNZ BU2
LOOP BU1
POP CX
RET
DELAYBU ENDP
;歌曲延时子程序=====
DELAY_PLAY PROC

P0: MOV CX,0010H
P1: MOV AX,0F00H
P2: DEC AX
JNZ P2
LOOP P1
DEC DL
JNZ P0

	RET

DELAY_PLAY ENDP

CODE ENDS
END START

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值