八音盒设计课程设计说明书

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1概述
设计一个八音盒,以扬声器作为发声装置,用16个LED小灯作为显示装置,以4x4键盘作为功能按键,八音盒中预存4首不同节拍的乐曲,用户可以选择播放模式。

播放时在单色LED显示器上显示出所播曲目的编号和曲目名称,16个小灯随着音乐节拍变化而变化。

1.1组员分工
张磊:软件编程
于海彬:软件编程,显示模块
彭彬:曲目乐谱编码,曲目播放模块以及实验报告
代涛:硬件焊接,以及实验报告
1.2操作说明
键1:播放曲目1
键2:播放曲目2
键3:播放曲目3
键4:播放曲目4
键0:暂停/恢复播放
键5:终止播放
键6:随机播放
2设计方案
2.2系统功能
播放分两种模式:随机播放和选择播放。

随机播放从4首预存曲目中随机选出一首曲目播放,选择播放模式由用户指定要播放的曲目。

播放时可以暂停播放或终止播放。

按下暂停/恢复键可暂停或恢复播放,按下终止键可以终止播放。

播放时在单色LED显示器上显示出所播曲目的编号和曲目名称。

播放时16个小灯随着音乐节拍变化而变化,小灯的具体亮灭模式自行设定。

2.2设计思路
首先确定4x4键盘的扫描程序,然后编写发声程序,将歌曲录入尝试播放,确定各按键功能,编写数码管程序显示歌曲名称,利用寄存器外拓接口,控制小灯随频率变化亮灭。

2.3键盘的识别
键盘的确定功能,就是判断键盘中的那一个键按下,确定所在行列位置。

通常采用逐行(或逐列)扫描查询识别。

具体过程是:依次轮流是列线中的一列输出低电平,其它三位为高电平,再在相应的顺次读行输出口的电平状态,如某行为低电平,则该行与置为低电平的列线相交叉处的按键即为闭合的按键,对应的在单片机内部进行调用播放歌的序号。

按键去抖动,通常采用软件延时的方法:在第一次检测到有键按下时,执行一段延时10ms的子程序后,再确认电平是否仍保持闭合状态电平,如果保持闭
合状态电平,则确认真正有键按下,进行相应处理工作,消除了抖动的影响。

2.4音乐盒显示部分
七段LED数码管构成“日”字形,还有一只发光二极管作为小数点。

因此,这种七段数码管又可称为八段数码管。

通过8个发光段的不同组合,可以显示0—9和A—F等十六个数字字母,从而可以实现十六进制整数和小数的显示。

LED 数码管显示器可以分为共阴极和共阳极两种接法。

(1)共阴极结构:如果所有的发光二极管的阴极接在一起,称之为共阴极结构,则数码管显示段输入高电平有效,当某段输入高电平该段便发光;使用时管子的上下端正中间的两个或者一个(内部公共端已经接在一起)接线端接低电平,其它的每段显示如上图所示,每段数码管都要加一个限流电阻为510欧。

(2)共阳极结构:如果所有的发光二极管的阳极接在一起,称之为共阳极结构,则数码管显示段输入低电平有效,当某段输入低电平该段便发光;使用时管子的上下端正中间的两个或者一个(内部公共端已经接在一起)接线端接高电平,其它的每段显示如上图所示每一段数码管同理也要加一个限流510欧的电阻。

需要显示时送入用不同电平组合代表的数据至数码管。

这种装入数码管中显示字形的数据称为字形码,又称段选码。

显示字符0—9和A—F与显示段选码的关系如下表所示。

通常显示段选码存放在程序存储器中的固定区域中,构成显示段选码表,当要显示某字符时,通过查表指令获取该字符所对应的段选码。

2.5硬件电路图
8254芯片:
8254芯片共有六种工作方式,分别对应与六种不同的用途。

2、方式0:计数到0结束输出正跃变信号方式。

2、方式1:硬件可重触发单稳方式。

3、方式2:频率发生器方式。

4、方式3:方波发生器。

5、方式4:软件触发选通方式。

6、方式5:硬件触发选通方式。

8255芯片:
8255有3个通道A、B、C与外设连接,每个通道又有8根线与外设连接,所以8255可以用24根线与外设连接,若进行开关量控制,则8255可同时控制24路开关。

各通道的引脚编号如下:
1、A口:编号为PA0~PA7,用于8255向外设输入输出8位并行数据。

2、B口:编号为PB0~PB7,用于8255向外设输入输出8位并行数据。

3、C口:编号为PC0~PC7,用于8255向外设输入输出8位并行数据,当8255工作于应答I/O方式时,C口用于应答信号的通信。

4x4键盘:
扬声器模块:
74ls273:
3 系统设计
3.1曲目编码
一般说来,单片机演奏音乐基本都是单音频率,它不包含相应幅度的谐波
频率,也就是说不能像电子琴那样能奏出多种音色的声音。

因此单片机奏乐只需弄清楚两个概念即可,也就是“音调”和节拍表示一个音符唱多长的时间。

3.1.1音调的确定
不同音高的乐音是用C、D、E、F、G、A、B来表示,这7个字母就是音乐的音名,它们一般依次唱成DO、RE、MI、FA、SO、LA、SI,即唱成简谱的1、2、3、4、5、6、7,相当于汉字“多来米发梭拉西”的读音,这是唱曲时乐音的发音,所以叫“音调”,即Tone。

把C、D、E、F、G、A、B这一组音的距离分成12个等份,每一个等份叫一个“半音”。

两个音之间的距离有两个“半音”,就叫“全音”。

在钢琴等键盘乐器上,C–D、D–E、F–G、G–A、A–B两音之间隔着一个黑键,他们之间的距离就是全音;E–F、B–C两音之间没有黑键相隔,它们之间的距离就是半音。

通常唱成1、2、3、4、5、6、7的音叫自然音,那些在它们的左上角加上﹟号或者b号的叫变化音。

﹟叫升记号,表示把音在原来的基础上升高半音,b叫降记音,表示在原来的基础上降低半音。

3.1.2节拍的产生
节拍指强拍和弱拍的组合规律,具体是指在乐谱中每一小节的音符总长度,常见的1/4,2/4,3/4,4/4,3/8,6/8,7/8,9/8,12/8拍等等,每小节的长度是固定的。

一首乐曲的节拍是作曲时就固定的,不会改变。

一首乐曲可以是由若干种节拍相结合组成的。

音乐中的音符除了有高低之分外,当然还要表示长短之分。

这里引用一个基础的音乐术语----拍子。

拍子是表示音符长短的重要概念。

表示音乐的长短需要有一个相对固定的时间概念。

简谱里将音符分为全音符、二分音符、四分音符、十六分音符、三十二分音符等。

在这几个音符里面最重要的是四分音符,它是一个基本参照度量长度,即四分音符为一拍。

这里一拍的概念是一个相对时间度量单位。

一拍的长度没有限制,可以是1秒也可以市2秒或半秒。

假如一拍是一秒的长度,那么二拍就是两秒;一拍定为半秒的话,两拍就是一秒的长度。

一旦这个基础的一拍定下来,那么比一拍长或短的符号就相对容易了。

用一条横线“—”在四分音符的右面或下面来标注,以此来定义该音符的
标记的音符的时值也不同。

从表中可以发现一个规律,就是:要使音符时值延长,在四分音符右边加横线“—”,这时的横线叫延时线、延时线越多,音持续的时间(时值)越长。

相反,音符下面的横线越多,则该音符时间越短。

3.2 程序模块流程图
3.2.1主程序
随机播放从4首预存曲目中随机选出一首曲目播放,选择播放模式由用户指定要播放的曲目。

播放时可以暂停播放或终止播放。

按下暂停/恢复键可暂停或恢复播放,按下终止键可以终止播放。

播放时在单色LED显示器上显示出所播曲目的编号和曲目名称。

3.2.2随机数模块
赋值一个标志变量,设定一个让其加一的循环程序,加到五重置为一,用以产生一到四的随机数。

随机数流程图:
3.2.3扫描键盘
将8255A的C口高四位设为输入连接行信号,低四位设为输出,由于本设计8个按键足够,所以仅C0,C1接收第一、二列信号。

扫描时先将第一列输入低电平,扫描行信号是否有低电平判断键是否按下,再将第二列输入低电平,判断第二列按键。

形成键特征值,去抖动,根据键特征值判断程序的跳转。

扫描键盘流程图:
3.2.4播放模块
在扫描键盘之后呢,则根据按键执行播放程序,随机播放或者选择播放都根据按键确定。

随机播放流程图:
选择播放流程图:
播放曲目流程图:
3.2.5显示模块
在播放的同时,用LED显示播放曲目的编号和名称。

具体实现是先给LED 送位选,然后指针查表,再送段选,指针移位,这样就能实现了。

显示模块流程图:
3.3硬件连线
第五片8255芯片接线:C口高四位接P3~P0,低二位接Q1~Q0,其中C口低
四位的前两位用于接扬声器(PC3,PC2)
74ls273接口:两片都用B口作为输入 PA7为接左边小灯273的CP的接口;PA6为接右边小灯273的PC口 WR接口都接高电平(+5V电源)
4总结
本次课程设计我们小组经过共同努力终于顺利完成了设计要求,我们成功地设计了一简单音乐播放器,实现了通过按键播放多首音乐,数码管显示播放歌曲的信息,小灯随着美妙的乐曲而闪烁,效果良好。

硬件设计和软件设计都符合设计要求,调试结果符合任务要求,达到了预期的目标。

通过这次课程设计我们都学到了许多东西,更加明白团结、合作的重要意义,这对即将走上社会的我们来说是最好的收获。

温故而知新,可以为师矣!知识需要温习,这次的课程设计对我们来说是检验更是提高,我们相信我们在以后的学习生活中会做的更好。

参考文献
[1]、黄勤,计算机硬件技术基础[M],重庆大学出版社,2002年9月
[2]、黄勤,计算机硬件技术基础实验教程[M],重庆大学出版社,2002年3月
附录一:
1 程序清单
.486
;第五片8255芯片端口地址,接线:C口高四位接P3~P0,低四位接Q3~Q0,其中C口第四位的前两位用于接扬声器(PC3,PC2)
PORTA EQU 300H
PORTB EQU 304H
PORTC EQU 308H
CTRL EQU 30CH
TIME2 EQU 348H
CTRL1 EQU 34CH
;;;;;8个按键特征值; ;;;;
K0 EQU 0EEH ;暂停与恢复
K1 EQU 0EDH ;
K2 EQU 0EBH
K3 EQU 0E7H
K4 EQU 0DEH
K5 EQU 0DDH ;终止按键
K6 EQU 0DBH
K7 EQU 0D7H
CODE SEGMENT USE16
ASSUME CS:CODE
ORG 1000H
;;;;;;;;;;主程序;;;;;;;;;;;;;;
START:
JMP BEG
;;;;;;定义变量;;;;;;;;
;欢乐颂
FREQ1 DW 330,330,349,392,392,349,330,294 ;第一首音乐
DW 262,262,294,330,330,294,294
DW 330,330,349,392,392,349,330,294
DW 262,262,294,330,294,262,262
DW 294,294,330,262,294,330,349,330,262
DW 294,330,349,330,294,262,294,196,330
DW 330,330,349,392,392,349,330,349,294
DW 262,262,294,330,294,262,262,0
T1 DW 8 DUP(50)
DW 5 DUP(50),25,100
DW 8 DUP(50)
DW 5 DUP(50),25,100
DW 5 DUP(50),2 DUP(25),2 DUP(50)
DW 50,2 DUP(25),6 DUP(50)
DW 8 DUP(50)
DW 3 DUP(50),2 DUP(25),5 DUP(50),25,100
;灵儿叮当响
FREQ2 DW 196,196,330,294,262,196,196,196,196,330,296,262,220 ;第二首音乐
DW 220,220,349,330,294,220,220,392,392,349,294,330
DW 262,196,196,330,294,262,196,196,196,330,294,262,220
DW 220,220,349,330,294,392,392,392,392,440,392,394,294,262
DW 330,330,330,330,330,330,330,392,262,294,330
DW 349,349,349,349,349,330,330,330,330,330,294,294,262,294,392 DW 392,392,349,294,262,0
T2 DW 5 DUP(25),50,2 DUP(13),4 DUP(25),50
DW 5 DUP(25),50,5 DUP(25),50
DW 6 DUP(25),50,5 DUP(25),50
DW 13 DUP(25),50
DW 2 DUP(25),50,2 DUP(25),50,4 DUP(25),50
DW 3 DUP(25),13,3 DUP(25),2 DUP(13),5 DUP(25),50
DW 4 DUP(25),50
;摇篮曲
FREQ3 DW 330,392,294,330,349,330,330,294,262,247,262,294,196
DW 330,392,294,330,349,330,330,294,330,349,294,262
DW 294,294,330,294,262,392,349,330,294,196
DW 330,392,294,330,349,330,330,294,330,349,294,262,0
T3 DW 2 DUP(50),25,13,50,2 DUP(25),4 DUP(13),2 DUP(50)
DW 2 DUP(50),25,13,50,2 DUP(25),4 DUP(13),50
DW 50,2 DUP(25),13,2 DUP(50),2 DUP(25),2 DUP(50)
DW 2 DUP(50),25,13,50,2 DUP(25),4 DUP(13),50
;生日歌
FREQ4 DW 196,196,220,196,262,247
DW 196,196,220,196,294,262
DW 196,196,392,330,262,247,440
DW 349,349,330,262,294,330
DW 196,196,220,196,262,247
DW 196,196,220,196,294,262
DW 196,196,392,330,262,247,440
DW 349,349,330,262,294,330,0
T4 DW 2 DUP(25),3 DUP(50),100
DW 2 DUP(25),3 DUP(50),100
DW 2 DUP(25),5 DUP(50)
DW 2 DUP(25),3 DUP(50),100
DW 2 DUP(25),3 DUP(50),100
DW 2 DUP(25),3 DUP(50),100
DW 2 DUP(25),5 DUP(50)
DW 2 DUP(25),3 DUP(50),100
KEY DB 00H
FRE DW 00H ;用于保存当前发生的频率值
FLAG DB 00H ;用于判断现在播放的是第几首歌
SHUMA DB 00H ;用于存数码管特征值
XUN DB 00H ;用于保存动态扫描数码管的位选号
SUIJI DB 2
NUM DB 00H
DSP1 DB 06H,76H,38H,6DH
DSP2 DB 5BH,38H,79H,5EH
DSP3 DB 4FH,76H,38H,6FH
DSP4 DB 66H,6DH,77H,6FH
BEG: ;初始化8255
MOV DX,CTRL
MOV AL,88H ;A、B口为输出,高4位C口为输入,接按键行信号
OUT DX,AL
;;;;;;初始化LED灯;;;;;;;;;;
MOV DX,PORTB
MOV AL,0FFH
OUT DX,AL
KS:
CALL RAND
CALL SCANF_KEY
MOV DX,PORTC ;音乐结束后将扬声器PC3与PC2为置0,使扬声器不发生
MOV AL,00H
OUT DX,AL
KS1: CMP KEY,K1
JZ KEY1
CMP KEY,K2
JZ KEY2
CMP KEY,K3
JZ KEY3
CMP KEY,K4
JZ KEY4
CMP KEY,K5 ;终止键
JZ KS
CMP KEY,K6
JZ KEY6
JMP KS
KEY1:
CALL KEY_1
KEY2:
CALL KEY_2
KEY3:
CALL KEY_3
KEY4:
CALL KEY_4
KEY6:
CMP SUIJI,1
JZ KEY1
CMP SUIJI,2
JZ KEY2
CMP SUIJI,3
JZ KEY3
CMP SUIJI,4
JZ KEY4
JMP KS
;;;;;;;;;;;产生随机数子函数;;;;;;;;
RAND PROC
PUSHA
ADD SUIJI,1
CMP SUIJI,5
JZ TL
JMP TT1 ;如果随机数值大于4则直接先先变为1 TL: MOV SUIJI,1
TT1: NOP
POPA
RET
RAND ENDP
;;;;;;;;;;;按键1子程序;;;;;;;;按下1键播第一首歌;;;;;;;;;;;;;;;;;; KEY_1 PROC
PUSHA
MOV FLAG,1
LEA SI,FREQ1 ;建立频率表指针
LEA BP,T1 ;建立节拍表指针
MUSIC1:
MOV DX,PORTB ;送段选和位选,显示2 ,数字3对应码值为:1100 1111B 数字4对应为:1110 0110B
MOV AL,86H ;PB7为位选,应为1,PB6~PB0对应G~A,为000,0110 OUT DX,AL
MOV DI,[SI] ;取1个音符对应的频率
MOV FRE,DI
CMP DI,0 ;频率值是否为0
JE END_MUSIC1 ;是0,结束程序
MOV BX,DS:[BP] ;不是0,取音符对应的节拍
CALL SOUND ;调用SOUND过程
CALL SCANF_KEY
CMP KEY,K0
JZ WT1
CMP KEY,K1
JZ KK1
CMP KEY,K2
JZ KK1
CMP KEY,K3
JZ KK1
CMP KEY,K4
JZ KK1
CMP KEY,K5
JZ END_MUSIC1 ;按下5健,终止播放
CMP KEY,K6
JZ KEY6
JMP K11
KK1:
JMP KS1
WT1:
MOV DX,PORTC ;音乐结束后将扬声器PC3与PC2为置0,使扬声器不发生
OUT DX,AL
CALL DISP1
CALL SCANF_KEY ;如果无健按下,则KEY为0,若不是0健按下,则KEY不为K0
CMP KEY,K0 ;只有按下0健,才能继续播放
JZ K11
JMP WT1
K11: ADD SI,2
ADD BP,2
JMP MUSIC1
END_MUSIC1:
MOV DX,PORTC ;音乐结束后将扬声器PC3与PC2为置0,使扬声器不发生
MOV AL,00H
OUT DX,AL
JMP KS
POPA
RET
KEY_1 ENDP
;;;;;;;;;;第一首歌数码管扫描子程序;;;;;;;
DISP1 PROC
PUSHA
LEA SI,DSP1
MOV BL,4
MOV AL,08H
NXTB1:
MOV XUN,AL
MOV AH,[SI]
MOV SHUMA,AH
MOV DX,PORTA ;位选
IN AL,DX
AND AL,0F0H
ADD AL,XUN
MOV DX,PORTA
OUT DX,AL
MOV AH,XUN
MOV DX,PORTB
OUT DX,AL
CALL DLYS
MOV AL,AH
ADD SI,1
SHR AL,1
DEC BL
JNZ NXTB1
POPA
RET
DISP1 ENDP
;;;;;;;;;;;按键2子程序;;;;;;;;按下2键播第二首歌;;;;;;;;;;;;;;;;;; KEY_2 PROC
PUSHA
MOV FLAG,2
LEA SI,FREQ2 ;建立频率表指针
LEA BP,T2 ;建立节拍表指针
MUSIC2:
MOV DX,PORTB ;送段选和位选,显示2 ,数字3对应码值为:1100 1111B 数字4对应为:1110 0110B
MOV AL,11011011B ;PB7为位选,应为1,PB6~PB0对应G~A,为000,0110
OUT DX,AL
MOV DI,[SI] ;取1个音符对应的频率
MOV FRE,DI
CMP DI,0 ;频率值是否为0
JE END_MUSIC2 ;是0,结束程序
MOV BX,DS:[BP] ;不是0,取音符对应的节拍
CALL SOUND ;调用SOUND过程
CALL SCANF_KEY
CMP KEY,K0
JZ WT2
CMP KEY,K1
JZ KK2
CMP KEY,K2
JZ KK2
CMP KEY,K3
JZ KK2
CMP KEY,K4
JZ KK2
CMP KEY,K5
JZ END_MUSIC2 ;按下5健,终止播放
CMP KEY,K6
JZ KEY6
JMP K12
KK2:
JMP KS1
WT2:
MOV DX,PORTC ;音乐结束后将扬声器PC3与PC2为置0,使扬声器不发生
MOV AL,00H
OUT DX,AL
CALL DISP2
CALL SCANF_KEY ;如果无健按下,则KEY为0,若不是0健按下,则KEY不为K0
CMP KEY,K0 ;只有按下0健,才能继续播放
JZ K12
JMP WT2
K12: ADD SI,2
ADD BP,2
JMP MUSIC2
POPA
END_MUSIC2:
MOV DX,PORTC ;音乐结束后将扬声器PC3与PC2为置0,使扬声器不发生
MOV AL,00H
OUT DX,AL
JMP KS
RET
KEY_2 ENDP
;;;;;;;;;;第2首歌数码管扫描子程序;;;;;;;
DISP2 PROC
PUSHA
LEA SI,DSP2
MOV BL,4
MOV AL,08H
NXTB2:
MOV XUN,AL
MOV AH,[SI]
MOV SHUMA,AH
MOV DX,PORTA ;位选
IN AL,DX
AND AL,0F0H
ADD AL,XUN
MOV DX,PORTA
OUT DX,AL
MOV AH,XUN
MOV DX,PORTB
MOV AL,SHUMA
OUT DX,AL
CALL DLYS
MOV AL,AH
ADD SI,1
SHR AL,1
DEC BL
JNZ NXTB2
POPA
RET
DISP2 ENDP
;;;;;;;;;;;按键3子程序;;;;;;;;按下3键播第三首歌;;;;;;;;;;;;;;;;;; KEY_3 PROC
PUSHA
MOV FLAG,3
LEA SI,FREQ3 ;建立频率表指针
LEA BP,T3 ;建立节拍表指针
MUSIC3:
MOV DX,PORTB ;送段选和位选,显示2 ,数字3对应码值为:1100 1111B 数字4对应为:1110 0110B
MOV AL,11001111B ;PB7为位选,应为1,PB6~PB0对应G~A,为000,0110
OUT DX,AL
MOV DI,[SI] ;取1个音符对应的频率
MOV FRE,DI
CMP DI,0 ;频率值是否为0
JE END_MUSIC3 ;是0,结束程序
MOV BX,DS:[BP] ;不是0,取音符对应的节拍
CALL SOUND ;调用SOUND过程
CALL SCANF_KEY
CMP KEY,K0
JZ WT3
CMP KEY,K1
JZ KK3
CMP KEY,K2
JZ KK3
CMP KEY,K3
JZ KK3
CMP KEY,K4
JZ KK3
CMP KEY,K5
JZ END_MUSIC3 ;按下5健,终止播放
CMP KEY,K6
JZ KEY6
JMP K13
KK3:
JMP KS1
WT3:
MOV DX,PORTC ;音乐结束后将扬声器PC3与PC2为置0,使扬声器不发生
MOV AL,00H
OUT DX,AL
CALL DISP3
CALL SCANF_KEY ;如果无健按下,则KEY为0,若不是0健按下,则KEY不为K0
CMP KEY,K0 ;只有按下0健,才能继续播放
JZ K13
JMP WT3
K13: ADD SI,2
ADD BP,2
JMP MUSIC3
END_MUSIC3:
MOV DX,PORTC ;音乐结束后将扬声器PC3与PC2为置0,使扬声器不发生
MOV AL,00H
OUT DX,AL
JMP KS
POPA
RET
KEY_3 ENDP
;;;;;;;;;;第3首歌数码管扫描子程序;;;;;;;
DISP3 PROC
PUSHA
LEA SI,DSP3
MOV BL,4
MOV AL,08H
NXTB3:
MOV XUN,AL
MOV AH,[SI]
MOV SHUMA,AH
MOV DX,PORTA ;位选
IN AL,DX
AND AL,0F0H
ADD AL,XUN
MOV DX,PORTA
OUT DX,AL
MOV AH,XUN
MOV DX,PORTB
MOV AL,SHUMA
OUT DX,AL
CALL DLYS
MOV AL,AH
ADD SI,1
SHR AL,1
DEC BL
JNZ NXTB3
POPA
RET
DISP3 ENDP
;;;;;;;;;;;按键4子程序;;;;;;;;按下4键播第四首歌;;;;;;;;;;;;;;;;;; KEY_4 PROC
PUSHA
MOV FLAG,4
LEA SI,FREQ4 ;建立频率表指针
LEA BP,T4 ;建立节拍表指针
MUSIC4:
MOV DX,PORTB ;送段选和位选,显示2 ,数字3对应码值为:1100 1111B 数字4对应为:1110 0110B
MOV AL,11100110B ;PB7为位选,应为1,PB6~PB0对应G~A,为000,0110
OUT DX,AL
MOV DI,[SI] ;取1个音符对应的频率
MOV FRE,DI
CMP DI,0 ;频率值是否为0
JE END_MUSIC4 ;是0,结束程序
MOV BX,DS:[BP] ;不是0,取音符对应的节拍
CALL SOUND ;调用SOUND过程
CALL SCANF_KEY
CMP KEY,K0
JZ WT4
CMP KEY,K1
JZ KK4
CMP KEY,K2
JZ KK4
CMP KEY,K3
JZ KK4
CMP KEY,K4
JZ KK4
CMP KEY,K5
JZ END_MUSIC4 ;按下5健,终止播放
CMP KEY,K6
JZ KEY6
JMP K14
KK4:
JMP KS1
WT4:
MOV DX,PORTC ;音乐结束后将扬声器PC3与PC2为置0,使扬声器不发生
MOV AL,00H
OUT DX,AL
CALL DISP4
CALL SCANF_KEY ;如果无健按下,则KEY为0,若不是0健按下,则
KEY不为K0
CMP KEY,K0 ;只有按下0健,才能继续播放
JZ K14
JMP WT4
K14: ADD SI,2
ADD BP,2
JMP MUSIC4
END_MUSIC4:
MOV DX,PORTC ;音乐结束后将扬声器PC3与PC2为置0,使扬声器不发生
MOV AL,00H
OUT DX,AL
JMP KS
POPA
RET
KEY_4 ENDP
;;;;;;;;;;第4首歌数码管扫描子程序;;;;;;;
DISP4 PROC
PUSHA
LEA SI,DSP4
MOV BL,4
MOV AL,08H
NXTB4:
MOV XUN,AL
MOV AH,[SI]
MOV SHUMA,AH
MOV DX,PORTA ;位选
IN AL,DX
AND AL,0F0H
ADD AL,XUN
MOV DX,PORTA
OUT DX,AL
MOV AH,XUN
MOV DX,PORTB
MOV AL,SHUMA
OUT DX,AL
CALL DLYS
MOV AL,AH
ADD SI,1
SHR AL,1
DEC BL
JNZ NXTB4
POPA
RET
DISP4 ENDP
;;;;;;;;;;键盘扫描程序;;;;;;;;;;;;;;
SCANF_KEY PROC
PUSHA ;保护相关寄存器
KSCAN:MOV BL,0FDH ;从Q1列开始扫描,Q2与Q3必须为1,才能和书上键值一一对应
NXTCOL:
MOV KEY,0 ;扫描前先将key置0
MOV AL,BL ;送出列信号,即C口低4位
MOV DX,PORTC
OUT DX,AL
MOV DX,PORTC ;读入行信号,C口高4位,P3到P0口值
IN AL,DX
AND AL,0F0H ;判断行信号(P3-P0)有无键按下
CMP AL,0F0H
JNZ FNDKEY ;有键按下,跳转
ROR BL,1 ;无的话,调整列信号
JC NXTCOL ;CF=1才转
JMP KKEY ;扫描完一次则退出扫描
;JMP KSCAN ;所有列信号扫描完一遍,无键按下,重新扫描
FNDKEY: ;以列信号第四位,行信号高四位,形成键特征值
SHL BL,4
SHR AL,4
OR BL,AL
;CALL DLYS
KEYUP: ;等待按键松开
MOV AL,0
MOV DX,PORTC
OUT DX,AL
MOV DX,PORTC ;看行信号有无按下为0的键
IN AL,DX
AND AL,0F0H ;若有则高四位与1111 0000B一定不相等
CMP AL,0F0H
JNZ KEYUP ;若不相等,则表示有键正在被按下
KKEY:
MOV KEY,BL ;KEY用来接收按键值定义变量时要有KEY DB 00H
POPA
RET
SCANF_KEY ENDP
;;;;;;;;;;;;;;;;扬声器发声程序;;;;;;;;;;;;;;
;FREQ表表示音符频率,T表表示节拍,DI指向音符频率,BX指向节拍,SI指向FREQ表,BP指向T表,以0为结束标志。

SOUND PROC
PUSHA ;保护相关寄存器
MOV AL,0B6H ;写8254的控制字
MOV DX,CTRL1
OUT DX,AL
MOV DX,12H ;计算通道2的计数初值 ;;;;;计数初值需要根据实际信号频率计算,此处值来自例程;;;;;;
MOV AX,3A98H
DIV DI ;DI中保存频率值
MOV DX,TIME2 ;送初值到8254通道2
OUT DX,AL
MOV AL,AH
MOV DX,TIME2
OUT DX,AL
MOV DX,PORTC ;读取C口状态
IN AL,DX
MOV AH,AL ;保存原来的PC口状态
OR AL,00001100B ; 使PC3及PC2置1
OUT DX,AL
CMP FRE,131 ;查询当前播放的频率,低音
JZ L1
CMP FRE,147
JZ L2
CMP FRE,165
JZ L3
CMP FRE,175
JZ L4
CMP FRE,196
JZ L5
CMP FRE,220
JZ L6
CMP FRE,247
JZ L7
CMP FRE,262 ;查询当前播放的频率,中音
JZ L12
CMP FRE,294
JZ L22
CMP FRE,330
JZ L32
CMP FRE,349
JZ L42
CMP FRE,392
JZ L52
CMP FRE,440
JZ L62
CMP FRE,494
JZ L72
CMP FRE,523
JZ L8
JMP DELAY1
L1:
MOV AL,01111111B ;第一个灯亮 PA7接左边第一个灯,后面依次 MOV NUM,AL
CALL LED1
JMP DELAY1
L2:
MOV AL,10111111B ;第二个灯亮
MOV NUM,AL
CALL LED1
JMP DELAY1
L3:
MOV AL,11011111B ;第三个灯亮
MOV NUM,AL
CALL LED1
JMP DELAY1
L4:
MOV AL,11101111B ;第四个灯亮
MOV NUM,AL
CALL LED1
JMP DELAY1
L5:
MOV AL,11110111B ;第五个灯亮
MOV NUM,AL
CALL LED1
JMP DELAY1
L6:
MOV AL,11111011B ;第六个灯亮
MOV NUM,AL
CALL LED1
JMP DELAY1
L7:
MOV AL,11111101B ;第七个灯亮
MOV NUM,AL
CALL LED1
JMP DELAY1
L8:
MOV AL,11111110B ;第八个灯亮
MOV NUM,AL
CALL LED1
JMP DELAY1
L12:
MOV AL,01111111B ;第一个灯亮 PA7接左边第一个灯,后面依次 MOV NUM,AL
CALL LED1
L22:
MOV AL,10111111B ;第二个灯亮 MOV NUM,AL
CALL LED1
JMP DELAY1
L32:
MOV AL,11011111B ;第三个灯亮 MOV NUM,AL
CALL LED1
JMP DELAY1
L42:
MOV AL,11101111B ;第四个灯亮 MOV NUM,AL
CALL LED1
JMP DELAY1
L52:
MOV AL,11110111B ;第五个灯亮 MOV NUM,AL
CALL LED1
JMP DELAY1
L62:
MOV AL,11111011B ;第六个灯亮 MOV NUM,AL
CALL LED1
JMP DELAY1
L72:
MOV AL,11111101B ;第七个灯亮 MOV NUM,AL
CALL LED1
JMP DELAY1
DELAY1:
CMP FLAG,1
JZ SHUMA1
CMP FLAG,2
JZ SHUMA2
JZ SHUMA3
CMP FLAG,4
JZ SHUMA4
JMP SE
SHUMA1:
CALL DISP1
CALL DLYS
JMP SE
SHUMA2:
CALL DISP2
CALL DLYS
JMP SE
SHUMA3:
CALL DISP3
CALL DLYS
JMP SE
SHUMA4:
CALL DISP4
CALL DLYS
JMP SE
SE:
DEC BX ;BX中保存着节拍
JNZ DELAY1 ;只要BX不为0,就转移到DELAY1,直到为0,执行下一条语句
CALL RAND
MOV AL,AH ;回复PC口的状态
MOV DX,PORTC
OUT DX,AL
POPA ;恢复相关寄存器
RET
SOUND ENDP
;;;;;;;;;;;;;;;;;LED1亮程序;;;;;;;;273接口:两片都用B口作为输入 PA7为接左边小灯273的CP的接口
LED1 PROC ;PA6为接右边小灯273的PC口 WR接口都接高电平(+5V电源)
PUSHA
MOV DX,PORTB
MOV AL,NUM
OUT DX,AL
MOV DX,PORTA
IN AL,DX
AND AL,0FH
SUB AL,80H
OUT DX,AL
MOV AL,0FH
OUT DX,AL
MOV DX,PORTB
MOV AL,NUM
OUT DX,AL
MOV DX,PORTA
IN AL,DX
AND AL,0FH
SUB AL,40H
OUT DX,AL
MOV AL,0FH
OUT DX,AL
POPA
RET
LED1 ENDP
;;;;;;;;;;;;;;;;;延时程序;;;;;;;;;;;;;;;;;;;; DLYS PROC
PUSH ECX
MOV ECX,450
DLYS_AGN:NOP
LOOPD DLYS_AGN
POP ECX
RET
DLYS ENDP
CODE ENDS
END START
附录二:心得体会
张磊:
本次课程设计,本小组承担的任务是八音盒的设计,在这次项目设计中,用到了模拟电路,数字电路,汇编语言,计算机硬件技术基础等一系列知识,是一次知识综合能力的考验。

在这次两周的项目任务中,本人不仅巩固了专业知识,也获得了很多经验,懂得了很多道理。

关于这次获得的经验,就从开始做到结束这个顺序来讲。

最开始写的是键盘扫描序程序,在这个模块中,考虑的问题是怎么用8255的一个口来控制4×4键盘,刚开始用整个B口做,高四位接键盘上的Q端,第四位接P端,可是我们的程序是接Q端的为输出口,接P端的为输入口,没考虑到B口要么做输出,要么做输入,不能分开做,在这个问题上耽误半天后才恍然大悟,用C口可以高四位做输入,低四位做输出,考虑到只用两列按键,就用了PC0和PC2两个端口做输出。

在写数码管动态扫描程序的时候,刚开始是在按键子程序中先调用播放子程序,再调用动态扫描子程序,这就造成动态扫描的第四个数码管显示之后,要等比前几个数码管轮流显示时间更长的时间才能再次显示第一个数码管,因为调用数码管动态扫描程序一次之后,中间要执行多条指令后才再一次调用动态扫描子程序,再加上每一个音调播放的时间很短,就造成了数码管上只能看到第四位数码管显示的字符,而看不到三个的字符。

解决办法是在播音子程序中调用数码管动态扫描子程序,使播音和数码管显示同步进行,且公用一个延时程序,即播音和数码显示的时间间隔是大致一样的。

则每一个数码管显示的时间都是一样的且很短,就产生了四个数码管同时显示的功能。

在写随机播放的程序中,由于不是很了解8086产生随机数的方法,且时间有限,于是就自己编写了一个伪随机子程序,其道理是在主程序中等待按键扫描的时候,让数字1,2,3,4在不断的按顺序变化,且其时间间隔很短,另外在播放子程序中也调用随机子程序,每播放一个音调,就随机数在一到四之间变化两到三次(由标志位控制变化两次还是三次),当按下随机播放按键的时候,判断现在的随机数是几,就播放第几首歌。

由于不知道什么时候按下随机播放键,1—4之间的变化时间也很短,这就造成了在按下随机播放键播放歌的时候就是一个随机事件,符合随机事件这样一个定义。

在用74LS273扩展端口的时候,由于用了两片74LS273,所在在控制两组16个小灯随音调和节拍变化的时候,要先写一片,送出端口值后再写另外一片,送出相应端口值。

刚开始本人将两片锁存器的CP分别接在PA7和PA6上,然后屏蔽第四位,同时对PA7和PA6写高电平,这就造成了只能有一个锁存器能用,解决办法是分别送高电平,分别送端口值,因为在分别写两片锁存器时,其间隔只有不到10条程序,时间是微秒级,这就可以产生两组灯的相应LED同时亮灭的效果,当然也可以让其分别点亮。

在这次任务中,充分的锻炼了自己的综合能力,比如扬声器的放大电路设计,查找74LS273芯片的资料,大致看懂了其英文手册,锻炼了自己一步步调试程序的能力,并且查找出了很多的程序逻辑错误,比如在子程序中先写了RET再写POPA恢复相应寄存器。

这就在子程序嵌套中造成了被调用的子程序不能返回的情况。

解决办法是要先写POPA再写RET,这虽然是个小问题,但是却是在程序
一步步调试了很多次之后才找出来的逻辑问题,调试时应考虑程序是怎么执行的,执行结果对不对,执行完之后程序又走向了哪里,回到哪儿去了,通过这样的方法找到逻辑错误。

此外在车次设计任务中的到的最大的收获是要学会把复杂的问题分块解决,分成很多模块,细化问题,找到正确的思路,思路决定出路,没有好的思路,那么一个任务再怎么努力,也不会有一个好的结果。

于海滨:
经过两周的努力,我们终于完成了课程设计——八音盒的制作。

在这里,我要感谢和我同组的同学,是大家的精诚合作,让制作顺利完成,要感谢那些帮助过我们的同学,是他们帮助我们克服那些疑惑困难,要感谢指导老师,是她帮我们指引了正确的设计方向。

说实话,在刚接到这个设计题的时候,我们陷入过短暂的迷茫,根本不知道从何处着手,汇编虽然学过,但当时理解的并不扎实,很多问题模棱两可,做题时经常按葫芦画瓢,从来没有独立做过这么繁复的编程设计。

后来,我们对这个问题进行了仔细的分析,发现其实所有的复杂程序,都是由简单程序组合而成的,我们把它分为扫描按键、发声、LED显示等小模块,分别进行编程。

其中我负责LED显示模块,这方面我们曾经学过,并没有花太多力气,但是当我们组合在一起调试程序时却出现了问题,LED只有最后一位能平稳地显示,其他三位均闪烁,时隐时现,怎么改变延迟时间也不行,我们在LED数码管前四位输入位选段选后的延迟时间相同,为什么会出现这种情况呢,我经过分析发现,显示程序在发声的前面,显示一遍数码管,发一个音调,但音调本身也有延迟程序,那么最后一位数码管的延迟时间就变为了,数码管延迟时间和音调延迟时间之和了,远远多于其余三位,所以会出现上述现象。

在其他同学的建议下,我们将显示程序编入了音调的延时程序里,将音调的延迟时间化为4个数码管延迟时间与另一个延迟时间之和,大大减少了数码管最后一位与前三位的延迟时间之差,达到了数码管稳定显示歌曲编号、歌曲名称的目的。

我们还曾被随机数的产生等问题所困扰,这里不再一一赘述。

经过这次课程设计,我意识到了很多问题,像这种内容比较多,过程比较久的编程设计问题,最重要的是要保持冷静、耐心,冲动和急躁并不能解决问题,还有,我们的些微疏忽,或者是机器有些老化,都可能会造成很大的困扰,浪费大量的时间去调试解决。

面对这种情况,当然,我们应该保持严谨认真的做学问态度,以及认真检查机器,但同时我们也应该做好面对这种情况的心理准备,这是在设计过程中容易发生,可以减少但无法避免的情况,设计不仅是编写功能,也要查漏补缺,要保持一颗平和的心,只要肯花时间,这种问题总能解决。

经此一役,我与小组的其他成员建立了深厚的友谊,深刻体会到了团结互助的重要性,在当今的工作学习中,不可能有人仅凭借自己的力量就能解决一切问题。

人心齐,泰山移,只有精诚合作,才能取长补短,取得更高的成就。

相关文档
最新文档