欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-03-23 22:41:34
...

一、实验要求

  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,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)两只老虎琴谱
汇编实验四——扬声器程序设计