proteus 基于8086实现的音乐盒仿真(参考的csdn博主啥也不会净瞎扯的先生) 代码用的是汇编 没有报错,但是点击开关运行没有声音,应该是仿真电路我接的有问题,这种仿真问题对于我说实在是太难啦
我连的图

参考的原图


MY8255_A EQU 0C400H+00H*4 ;8255的A口地址
MY8255_B EQU 0C400H+01H*4 ;8255的B口地址
MY8255_C EQU 0C400H+02H*4 ;8255的C口地址
MY8255_MODE EQU 0C400H+03H*4 ;8255的控制寄存器地址
MY8253_COUNT0 EQU 0c440H+00H*4 ;8253计数器0端口地址
MY8253_COUNT1 EQU 0c440H+01H*4 ;8253计数器1端口地址
MY8253_COUNT2 EQU 0c440H+02H*4 ;8253计数器2端口地址
MY8253_MODE EQU 0c440H+03H*4 ;8253控制寄存器端口地址
STACK SEGMENT STACK
DW 256 DUP(0)
STACK ENDS
DATA SEGMENT
FREQ_LIST DW 330,330,330,350,393,330,294 ;频率表
DW 262,262,262,294,330,330,248,248
DW 221,330,294,221,330,294
DW 221,330,294,262
DW 262,0 ; 时间表
TIME_LIST DB 4,2,2,4,4,8,8
DB 4,2,2,4,4,6,2,8
DB 4,4,8,4,4,8
DB 4,4,6,2
DB 16
FREQ_LIST1 DW 495,556,495,441,393,350,330,248
DW 330,393,661,624,556,393,495,495
DW 556,624,556,495,441,393,393,278
DW 312,278,248,495,330,350,393,393,0
TIME_LIST1 DB 4,2,2,4,2,2,8,8
DB 3,3,3,3,3,3,8,8
DB 3,3,3,3,3,3,8,8
DB 3,3,3,3,3,3,8,8
FREQ_LIST2 DW 495,495,495,624,742,742,742,742,833
DW 833,833,990,742,661,661,833,833,624
DW 624,624,624,556,556,556,556,742,65535,742
DW 495,495,495,624,742,742,742,742,833
DW 833,833,990,742,661,6661,661,833,624
DW 624,624,624,624,556,556,556,624,495
DW 0
TIME_LIST2 DB 4,4,4,4,4,4,4,4,4
DB 4,4,4,16,4,4,4,4,4
DB 4,4,4,4,4,4,4,10,2,4
DB 4,4,4,4,4,4,4,4,4
DB 4,4,4,16,4,4,4,4,4
DB 2,2,4,4,4,4,4,4,16
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
START:
;DS SS DP寄存器写入对应的数值
MOV AX,DATA
MOV DS,AX
MOV AX,STACK
MOV SS,AX
MOV AX,256
MOV SP,AX
;8255初始化,A输出,b输入
MOV DX,MY8255_MODE
MOV AL,82h
OUT DX,AL
;初始化8254工作方式
MOV DX,MY8253_MODE
MOV AL,36h
OUT DX,AL ;定时器0,方式3
main:
MOV DX,MY8255_B;检测开关信号
IN AL,DX
TEST AL,01H;检测按键1是否被按下
JZ BEGIN0
TEST AL,02H;检测开关2是否被按下
JZ BEGIN1
TEST AL,04H;检测按键3是否被按下
JZ BEGIN2
;无有效按键时输出关蜂鸣器
MOV DX,MY8255_A
MOV AL,0H
OUT DX,AL
JMP MAIN
BEGIN0:
MOV DX,MY8255_A
MOV AL,1H
OUT DX,AL
MOV SI,OFFSET FREQ_LIST ;装入频率表起始地址
MOV DI,OFFSET TIME_LIST ;装入时间表起始地址
PLAY0:
MOV DX,0FH
MOV AX,0E502H
DIV WORD PTR [SI]
MOV DX,MY8253_COUNT0
OUT DX,AL
MOV AL,AH
OUT DX,AL
;取出演奏相对时间,调用延时子程序
MOV BX,0
MOV Bl,[DI]
CALL DALLY
ADD SI,2
INC DI
CMP WORD PTR [SI],0
JE BEGIN0
MOV DX,MY8255_B
IN AL,DX
TEST AL,01H
jnz main
Jmp PLAY0
BEGIN1:
MOV DX,MY8255_A
MOV AL,1H
OUT DX,AL
MOV SI,OFFSET FREQ_LIST1
MOV DI,OFFSET TIME_LIST1
PLAY1:
MOV DX,0FH
MOV AX,0E502H
DIV WORD PTR [SI]
MOV DX,MY8253_COUNT0
OUT DX,AL
MOV AL,AH
OUT DX,AL
;取出演奏相对时间,调用延时子程序
MOV BX,0
MOV Bl,[DI]
CALL DALLY
ADD SI,2
INC DI
CMP WORD PTR [SI],0
JE BEGIN1
MOV DX,MY8255_B
IN AL,DX
TEST AL,02H
jnz main
Jmp PLAY1
BEGIN2:
MOV DX,MY8255_A
MOV AL,1H
OUT DX,AL
MOV SI,OFFSET FREQ_LIST2
MOV DI,OFFSET TIME_LIST2
PLAY2:
MOV DX,0FH
MOV AX,0E502H
DIV WORD PTR [SI]
MOV DX,MY8253_COUNT0
OUT DX,AL
MOV AL,AH
OUT DX,AL
;取出演奏相对时间,调用延时子程序
MOV BX,0
MOV Bl,[DI]
CALL DALLY
ADD SI,2
INC DI
CMP WORD PTR [SI],0
JE BEGIN2
MOV DX,MY8255_B
IN AL,DX
TEST AL,04H
jnz main
Jmp PLAY2
;延时函数
DALLY PROC
PUSH CX
DELAY1:
MOV CX,08800H
LOOP $
DEC BX
JNZ DELAY1
POP CX
RET
DALLY ENDP
CODE ENDS
END START