汇编实验四——扬声器程序设计

一、实验要求

  1. 通过8253和8255使扬声器发声
  2. 编写电子琴程序,要求程序能响应三个键,每个键对应不同频率的声音,按下发声,松开静音。

二、实现原理

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,0FFFH
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)两只老虎琴谱
在这里插入图片描述

发布了113 篇原创文章 · 获赞 109 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/weixin_42109012/article/details/103212517
今日推荐