汇编实验四——扬声器程序设计
一、实验要求
- 通过8253和8255使扬声器发声
- 编写电子琴程序,要求程序能响应三个键,每个键对应不同频率的声音,按下发声,松开静音。
二、实现原理
8255的地址为:60H~63H;PB端口地址为61H,控制口为63H
8253的地址为:40H~43H;通道2地址42H,控制口地址43H
1、发声原理
人能听到的声音频率范围为20Hz~20000Hz。但是人耳最敏感声音频率范围是1000Hz-----3000Hz之间的声音。
扬声器可以产生不同频率、不同振幅的震动,振幅决定了音量,频率决定了音色、品质,本次实验就是改变电流输出频率从而发声。
2、8253计算初值
PC的扬声器以计数器2为核心。计数器8255的CLK2的输入频率为1.193182 MHz,工作于方式3,改变计数器初值可以由得到不同频率的方波输出。
fCLK频率:1.1931816*1000000=0012 34DE H
若要使扬声器输出600Hz频率信号,则8253计数初值为1983
若要使扬声器输出1000Hz频率信号,则8253计数初值为1193
对于600 Hz, N=计数初值=11931816/600=1983
对于1000 Hz,N=计数初值=11931816/1000=1193
改变8253的输出频率,即可改变扬声器输出声频信号频率。
3、8255控制开关
扬声器受8255A芯片B口的两个输出端线控制,8255工作于方式0输出。
PB0=1,即GATE2=1,计数器2正常计数
PB1=1,打开输出控制门,扬声器工作
三、代码及解释
1、任务一
(1)按下 a 键时:对8253定时器初始化,设置通道2,方式3;然后用该计数器,计数当输出1000Hz时的计数次数,以产生1000Hz频率的方波,并从42H(OUT2)端口输出。即该子程序功能为:初始化定时器,设置计数初值,并输出1KHz频率信号。
(2)按下 b 键时:使PB1=1,输出高电平,驱动扬声器,以开启扬声器。
(3)按下 c 键时:使PB1=0,关闭扬声器的驱动,使扬声器无法工作。
(4)按下 d 键时:使PB0=1,输出高电平,驱动8253定时器,以开启定时器。
(5)按下 e 键时:使PB0=0,关闭定时器驱动电压,使定时器无法工作。
(6)按下 ESC 键时:退出整个程序,回到DOS。
ASSUME CS:seg2,DS:seg1
seg1 SEGMENT
pstart DB 'Program start.',0DH,0AH,'$' ;0D回车,0A换行
pend DB 'Program will end when input',27H,'ESC',27H,'.',0DH,0AH,'$'
sec DB 10
seg1 ENDS
seg2 SEGMENT
start: MOV AX,seg1
MOV DS,AX
MOV DX,OFFSET pstart
MOV AH,09H
INT 21H
MOV DX,OFFSET pend
MOV AH,09H
INT 21H
;--------------键盘控制-------------------
wait1: MOV AH,01H ;输入一个字符=AL,DOS系统功能调用
INT 21H
CMP AL,1BH ;是否ESC键
JE keyESC
CMP AL,'a' ;是a键?
JE keya ;a键处理,初始化定时器8253
CMP AL,'b'
JE keyb ;b开启扬声器
CMP AL,'c'
JE keyc ;c关启扬声器
CMP AL,'d'
JE keyd ;d启动定时器
CMP AL,'e'
JE keye ;e停止定时器
JMP wait1
;-----‘a’键处理,定时器8253通道2初始化,将频率转为计数初值--------
keya: MOV AL,10110110B ;设定时器工作方式,方式3
OUT 43H,AL ;送8253的控制端口43H
MOV DX,0012H ;输入频率送DX,AX
MOV AX,34DEH
MOV DI,1000 ;将频率1000Hz转换为计数初值
DIV DI ;计数初值在AX中
OUT 42H,AL ;计数初值送定时器2,即送42H端口
MOV AL,AH
OUT 42H,AL ;输出频率为1000HZ信号
JMP wait1
;------‘b’键处理,并行接口8255,扬声器开启控制--------------
keyb: IN AL,61H ;读8255PB口
OR AL,00000010B ;并行接口8255,使得PB1=1
OUT 61H,AL ;置PB1=1,开扬声器
JMP wait1
;------‘c’键处理,扬声器关闭控制----------------------------
keyc: IN AL,61H
AND AL,11111101B ;并行接口8255,PB1=0,关扬声器
OUT 61H,AL
JMP wait1
;-------‘d’键处理,定时器开启控制---------------------------
keyd: IN AL,61H
OR AL,00000001B ;并行接口8255,启动定时器2,GATE=PB0=1
OUT 61H,AL
JMP wait1
;------‘e’键处理,定时器关闭控制----------------------------
keye: IN AL,61H
AND AL,11111110B ;并行接口8255,停止定时器2,GATE=PB0=0
OUT 61H,AL
JMP wait1
;------‘ESC’键处理,退出系统--------------------------------
keyESC: MOV AH,4CH
INT 21H
seg2 ENDS
END start
2、任务二
要求程序能响应三个键,每个键对应不同频率的声音,按下发声,松开静音。
(1)需要三种频率对应三个按键
(2)按下发声,松开静音:需要判断按键情况,持续按下、按一下、没按,可以短暂延时再次查看按键情况,如果延时后按键还有输入说明按键持续按下,否则说明只按了一下。
其实写两个延时程序更好(本人偷懒不想改)
发声应该延时长,人听到才不会因为太短而变声
检测按键状态应该延时短,电脑响应才不会延时(明明没按了,但是还是在响应)
为了更正式,可以改成两个延时程序
为什么又七个按键,因为网上有现成的且对应简单的七个音阶,稍微修改了下,如果只要三个可以自己去掉一些就可以了。
ASSUME DS:DATA,SS:STACK,CS:CODE
DATA SEGMENT
pstart DB 'Program start.',0DH,0AH,'$' ;0D回车,0A换行
pend DB 'Program will end when input',27H,'ESC',27H,'.',0DH,0AH,'$'
sec DB ?
TABLE DW 262 ;k1 发 do 的音,261.6HZ
DW 294 ;k2 发 re 的音,293.6HZ
DW 330 ;k3 发 mi 的音,329.6HZ
DW 349 ;k4 发 fa 的音,349.2HZ
DW 392 ;k5 发 sol 的音,392HZ
DW 440 ;k6 发 la 的音,440HZ
DW 494 ;k7 发 si 的音,493.8HZ
DATA ENDS
STACK SEGMENT PARA STACK 'STACK'
STA DB 48 DUP(?)
TOP EQU LENGTH STA
STACK ENDS
CODE SEGMENT
;--------------初始化-------------------
start: MOV AX,DATA
MOV DS,AX
MOV DX,OFFSET pstart
MOV AH,09H ;功能号09H,显示字符串
INT 21H
MOV DX,OFFSET pend
MOV AH,09H
INT 21H
MOV AX,STACK
MOV SS,AX
MOV AX,TOP
MOV SP,AX
;--------------键盘控制-------------------
key: MOV AH,01H ;功能号01H,键盘输入并回显
INT 21H
CMP AL,1BH ;ASCII表,1BH 是 ESC
JE keyESC
CMP AL,'1' ;分别对应 7 个音阶
JE key1
CMP AL,'2'
JE key2
CMP AL,'3'
JE key3
CMP AL,'4'
JE key4
CMP AL,'5'
JE key5
CMP AL,'6'
JE key6
CMP AL,'7'
JE key7
;--------------是否持续按下-----------------
always: MOV AH,0BH ;功能号0BH,检测键盘状态
INT 21H
AND AL,0FFH ;无按键按下 AL=00,有按键按下 AL=FF
CALL delay ;调用延时,判断按键是否持续按下
JNZ always ;是就继续发声
IN AL,61H
AND AL,11111100B ;否就关闭,PB1=PB0=0
OUT 61H,AL
JMP key
;--------------按键选择-------------------
keyESC: MOV AH,4CH
INT 21H
key1: MOV BX,TABLE ;TABLE对应频率
JMP TOSOUND
key2: MOV BX,TABLE+2
JMP TOSOUND
key3: MOV BX,TABLE+4
JMP TOSOUND
key4: MOV BX,TABLE+6
JMP TOSOUND
key5: MOV BX,TABLE+8
JMP TOSOUND
key6: MOV BX,TABLE+10
JMP TOSOUND
key7: MOV BX,TABLE+12
JMP TOSOUND
;--------------计算初值-------------------
TOSOUND:MOV DX,0012H
MOV AX,34DEH
DIV BX ;计算初值
CALL SOUND ;调用发音子程序
CALL delay ;调用延时
JMP always ;跳转判断按键是否持续按下
;--------------发声程序-------------------
SOUND PROC NEAR
PUSH AX
MOV AL,10110110B ;设定时器工作方式,方式3
OUT 43H,AL ;送8253的控制端口43H
POP AX
OUT 42H,AL ;计数初值送低8位定时器2,即送42H端口
MOV AL,AH
OUT 42H,AL ;计数初值送高8位定时器2,即送42H端口
IN AL,61H
OR AL,00000011B ;打开扬声器,PB1=PB0=1
OUT 61H,AL
RET
SOUND ENDP
;--------------延时程序-------------------
delay PROC NEAR
PUSH CX
PUSH AX
MOV AX,100H
for1: MOV CX,0FFH
for2: LOOP for2
DEC AX
JNZ for1
POP AX
POP CX
RET
delay ENDP
CODE ENDS
END start
四、结果
1、扬声器发声
a 是初始化
b 是扬声器开启
c 是扬声器关闭
d 是定时器开启
e 是定时器关闭
所以发声输入 abd
即可,不发声输入 ce
其中之一就可以了。
2、电子琴程序
(1)随便乱打
(2)两只老虎琴谱
上一篇: 《汇编语言》王爽 实验
下一篇: Runtime