四川大学微机原理实验报告(4)

2018-12-04 21:35

42H 选中计数器2:用来控制扬声器发声 43H 公用的控制器:分别对三个寄存器和控制器寻址

那么,如何触动扬声器发出声音呢?原来PC机的主音箱上装有一只小喇叭,由定时器8253和并行接口芯片8255(可编程外围接口芯片)控制其发声,8255包括三个8位寄存器,两个用于输入功能,一个用于输出功能。输入寄存器分配的I/O端口地址为60H和62H,输出寄存器分配的I/O端口地址为61H。8253定时器计数器2连接到扬声器,其电路如下:

8253 DRIVER 1.9318MHZ CLK 喇叭 OUT2 与门 8255

PB0 GATE2 PB1

装入计数器2的计数初值为533H(1.19318MHz/896Hz=1331=533H),这样,得到的控制字为10110110B=0B6H,即选中计数器2,读/写,工作方式三(方波发声器),二进制。

计数器2的初始化程序为: MOV AL,0B6H OUT 43H,AL

1)计算计数值程序段: MOV DI, 给定频率 MOV DX, 12H MOV AX, 34DCH DIV DI

AX中即为计数值。

2)打开扬声器发声,8255PB0,PBI送出高电平: IN AL , 61H OR AL , 3 OUT 61H , AL

3)关闭扬声器,停止发声: IN AL ,61H AND AL , 0FCH OUT 61H, AL

两只老虎的音频表定义在数据段中,如下:

STACK SEGMENT

DW 100 DUP(?) STACK ENDS

DATA SEGMENT

MUSIC DW 2 DUP(262,294,330,262) ; 频率表,1231;1231 DW 2 DUP(330,349,392) ;345;345;

DW 2 DUP(392,440,392,349,330,262) ;565431;565431 dw 2 dup(294,196,262),0 ;251;251,0表示结束

TIME DW 10 DUP(250*50),500*50,250*50,250*50,500*50 ;节拍表 DW 2 DUP(120*50,120*50,120*50,120*50,250*50,250*50) DW 2 DUP(250*50,250*50,500*50)

N EQU 32 ;32个音符 DATA ENDS

二.实验目的:

学习8253计数器2输出方波信号用以驱动扬声器发声的原理,通过程序设置计数器2的输出波形的频率和延续时间,控制扬声器的音调和发生长短。

三.实验内容:

1.设计程序让微机演奏一段两只老虎的乐曲。

2.思考如何让PC机演奏一遍,两遍以及数遍这段两只老虎的乐曲,并修改程序实现。

四.实验报告:

整理出运行正确的源程序清单(加以中文注释),并给出详细程序流程图。

三.程序代码 DATAS SEGMENT

BG DB 0AH,0DH,”TWO TIGER:$” FREQ DW 2 DUP(262,294,330,262) DW 2 DUP(330,349,392)

DW 2 DUP(392,440,392,349,330,262)

DW 2 DUP(294,196,262),0 ;频率表 TIME DW 10 DUP(250*50),500*50,250*50,250*50,500*50 DW 2 DUP(120*50,120*50,120*50,120*50,250*50,250*50) DW 2 DUP(250*50,250*50,500*50) NUM DB 3 DATAS ENDS

STACK SEGMENT PARA STACK 'STACK'

DB 200 DUP(?) ;堆栈段定义并分配存储空间 STACK ENDS

ASSUME CS:CODE,DS:DATA,SS:STACK STAT PROC FAR

PUSH DS ;DS中包含的是程序段前缀的起始地址 MOV AX,0 PUSH AX MOV AX ,DATA MOV DS,AX MOV DX,OFFSET BG MOV AH,09

INT 21H ; 输出字符串“TWO TIGER” LP0: MOV SI,OFFSET FREQ MOV BP,OFFSET TIME

CALL SING ;调用子程序,开始演奏 DEC NUM

CMP NUM,0 JNZ LP0 RET STAT ENDP

SING PROC NEAR ;演奏子程序 PUSH DI PUSH SI PUSH BP PUSH BX

REPTO: MOV DI,[SI] CMP DI,0

JE END_SING MOV BX,DS:[BP] CALL SOUND ADD SI,2 ADD BP,2 JMP REPTO

END_SING:POP BX POP BP POP SI POP DI RET SING ENDP SOUND PROC NEAR PUSH AX PUSH BX PUSH CX PUSH DX PUSH DI

MOV AL,0B6H DI指向频率表首地址 若DI=0,则演奏结束;扬声器发声子程序 ;开始计算计数值

; OUT 43H,AL MOV DX,12H MOV AX 34DCH DIV DI OUT 42H,AL MOV AL,AH OUT 42H,AL

IN AL,61H ;打开扬声器发声 MOV AH,AL OR AL,3 OUT 61H,AL

DELAY: MOV CX,20000 ;延时10MS DL 10MS:LOOP DL10MS DEC BX JNZ DELAY MOV AL,AH

OUT 61H,AL ;关闭扬声器 POP DI POP DX POP CX POP BX POP AX RET SOUND ENDP CODE ENDS END STAT

四.实验感想和收获

这个程序最初一直存在输出乱码的情况,后来经过单步调试,发现是通用子程序时没有进行现场的保护,几个存储器被多次赋值,导致最后不能输出正确的结果。因此我之后增加了堆栈段的定义,对几个寄存器进行了入栈保护,对子程

序的调用进行了现场保护。计数器2的计数初值为533H,控制字为10110110B=0B6H,这个控制字切记不能搞错,同时也要清楚地区分各个计数器的端口地址以及控制口的端口地址。在播放音乐的子程序中,应当将数值传到端口42H,打开扬声器,延时,关闭扬声器的顺序执行,最初我在编程时漏掉了延时的过程,导致无法得到正确的结果。另外,在SOUND子程序末尾一定要记住返回中断点,因为这是一个循环,不是只出现一个音符,而是要一直播放整个音乐。

通过这个试验,我对子程序调用,堆栈段使用有了更深的理解,通过自己编译,调试,一步步找到自己的不足,这是一个学习的过程,也是对知识的探求。这次试验老师给了我们很多的资料和一些源代码,我要做的不仅是将他们拼接起来,是要根据自己的设计对他们加以运用,并补充很多的子程序,现场保护代码等,将其完善,变为自己的程序。子程序调用必须先进行现场保护,这是非常重要的,也是汇编语言和高级语言一大不同所决定的。

编程需要耐心和决心,只有一步步检查,才能使程序正确,达到想要的结果,正因为这样,当程序编译成功,电脑开始播放音乐时,那种成功地满足感不是用语言形容的,这让我对这门课程有了更多地兴趣。


四川大学微机原理实验报告(4).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:农村小学校长汇报材料

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: