电子琴的原理及设计Word文件下载.docx
《电子琴的原理及设计Word文件下载.docx》由会员分享,可在线阅读,更多相关《电子琴的原理及设计Word文件下载.docx(19页珍藏版)》请在冰豆网上搜索。
●简单电子琴主程序
结合实验指导书的两程序,将其分为5个子程序,实现简单的播放和显示音阶的功能。
●录音子程序
实现记录弹奏曲目并播放的功能。
首先由9触发,将输入的音阶存入缓存区song中,输入的同时可以发声和显示。
当再次按9时录制完成。
●放音子程序
本子程序实现放音功能。
首先从8279键盘读出键码,判断,如果键码不是1-8即回到程序开始,如果是,即求出相应的时间常数的序号,取60次32个正弦波数据,播放32个数据,组成一个正弦波。
播放60次后,从PORT1中取出值到AL,和1相与,判断是否有按键,如果有就进入死循环,直到下次按键为止。
●放歌子程序
调用放音子程序。
●暂停子程序
在乐曲播放过程中,每调用一次MUSIC,就从PORT1中取出AL,检测AL个数,即每次发音后按键盘的次数。
当检测到AL为1时,即按了一次任意就使程序进入一个死循环,不发音,到此实现了暂停,然后再次按动任意键时,AL就为2,不为1,所以程序跳出死循环,继续从断开处调用乐曲,继续播放。
●源程序整体
程序开始,显示提示信息,对缓存区、8279初始化。
接着调用发音子程序,键盘子程序,在把AL送缓存区,实现发音和显示。
接着对9键、0键、f键、r键进行逐个判断,当9按下时,调用录音子程序。
当按下0时,播放录制的曲目。
当按下f键时,播放程序中预设的曲目。
当检测到r时,退出到DOS状态。
当每一个都检测不到时,退回到调用发音子程序,继续发音显示。
从而实现有扩展功能的电子琴。
5.模块连接,形成完整的程序
6.编写程序文档
4.流程图
以下用主程序与子程序配合流程图其进行说明。
(1)主程序流程图
(2)发音子程序流程图
(3)键盘显示子程序流程图(4)显示子程序流程图
(5)录音子程序流程图(6)放录音子程序流程图
四、源程序
DATASEGMENT
IOPORTEQU0C400H-0280H
PORT0EQUIOPORT+2B0H;
8279DATAPORT
PORT1EQUIOPORT+2B1H;
8279CTRLPORT
SEC1DB0;
HOURHIGHT
SEC2DB0;
HOUPLOW
MIN1DB0;
MINHIGHT
MIN2DB0;
MINLOW
HOUR1DB0;
SECHIGHT
HOUR2DB0;
SECLOW
LEDDB3FH,06,5BH,4FH,66H,6DH,7DH,07,7FH,6FH,77H,7CH,39H,5EH,79H,71H;
7段管对应的显示码
DB67H,37H,73H,31H,3EH,36H,66H
IO8253AEQUIOPORT+280H
IO8253BEQUIOPORT+283H
IO8255AEQUIOPORT+288H
IO8255BEQUIOPORT+28BH
IO0832AEQUIOPORT+290H
DATA1DB80H,96H,0AEH,0C5H,0D8H,0E9H,0F5H,0FDH
DB0FFH,0FDH,0F5H,0E9H,0D8H,0C5H,0AEH,96H
DB80H,66H,4EH,38H,25H,15H,09H,04H
DB00H,04H,09H,15H,25H,38H,4EH,66H;
正弦波数据
TIMEDB120,106,94,89,79,70,63,59;
发不同音时8253的计数器初值
MSGDB’************************************************’,0DH,0AH
DB’THISISOURWORK,PLEASESUPPORTUS,THANKYOU’,0DH,0AH
DB'
1.PRESS1~8TOPLAY'
0DH,0AH,0DH,0AH
DB'
2.PRESS9TORECORD'
3.PRESS0TOPLAYTHERECORD'
4.PRESSFTOPLAYTHESONG'
5.PRESSANYKEYTOPAUSE/STARTWHENPLAYTHERECORD'
6.PRESSRTOEXIT'
DB’COPYRIGHT@MR.LI&
MR.HUANG’,0DH,0AH
DB’**********************************’,0DH,0AH,'
$'
NUMDB?
;
NUM为8253计数器初值的序号
SONGDB50DUP(?
)
SONG1DB1,2,3,4,5,6,7,8,8,7,6,5,4,3,2,1,-1
MSGPLAYDB0DH,0AH,0DH,0AH,'
RECORDING......PLESS9TOEND'
0DH,0AH,0DH,0AH,'
MSGENDDB'
RECORDFINISHED.'
0DH,0AH,0DH,0AH,0DH,0AH,0DH,0AH,'
MSGPLAY1DB0DH,0AH,0DH,0AH,'
PLAYING......PRESSANYKEYTOPAUSE.'
MSGEND1DB'
PLAYINGFINISHED.'
DATAENDS
STACK1SEGMENTPARASTACK'
STACK'
DB50DUP(0)
STACK1ENDS
CODESEGMENT
MAINPROCFAR
ASSUMECS:
CODE,DS:
DATA
START:
MOVAX,DATA
MOVDS,AX
MOVDX,OFFSETMSG
MOVAH,9
INT21H;
显示提示信息
CLI
MOVSEC1,0
MOVSEC2,0
MOVMIN1,0
MOVMIN2,0
MOVHOUR1,0
MOVHOUR2,0;
显示缓存区初始化
MOVAX,CS
MOVDX,PORT1
MOVAL,0D3H;
11010011清除命令特征位
OUTDX,AL;
8279CLEAR
MOVAL,2AH;
0010101042分频,内部使用1MHZ/42的频率
8279CLOCK
MOVAL,40H
READFIFORAMCOMMAND
MOVAL,00H;
8个字符显示,左入口。
编码扫描键盘,双键锁定。
KEYBORDDISPLYMODE
MOVAL,80H;
写入的存储单元地址为0000
WRITERAMCOMMAND
KEY1:
CALLMUSIC;
发音
CALLKEYBORD;
CALLKEYBORDANDDISPLY
NEXT2:
MOVHOUR2,AL
MOVHOUR1,AL
MOVMIN2,AL
MOVMIN1,AL
MOVSEC2,AL
MOVSEC1,AL;
键盘码存入显示缓冲区
LP0:
CMPAL,9H
JZRE
CMPAL,0H
JZOUTPUT
CMPAL,15
JZFU
CMPAL,13H;
'
R'
COMMAND
JNZLP1
MOVAX,4C00H;
QUITTODOS
INT21H
LP1:
JMPKEY1
RE:
CALLRE0;
录音
JMPLP1
OUTPUT:
CALLOUTPUT0;
放录音
FU:
CALLOUTPUT1
MAINENDP
RE0PROCNEAR;
录音子程序
MOVDX,OFFSETMSGPLAY
显示录音提示信息
LEASI,SONG
R:
CALLKEYBORD
CALLMUSIC
CALLDISP
MOV[SI],AH
CMPAH,9
JZQRE0
INCSI
JMPR
QRE0:
MOVDX,OFFSETMSGEND
RET
RE0ENDP
OUTPUT0PROCNEAR;
放录音子程序
MOVDX,OFFSETMSGPLAY1
显示PLAY提示信息
OU:
MOVAL,[SI]
CMPAL,9
JZQRE1
MOVAL,AH
NEXT:
JMPOU
QRE1:
MOVDX,OFFSETMSGEND1
显示PLAYEND提示信息
OUTPUT0ENDP
OUTPUT1PROCNEAR;
放歌子程序
LEASI,SONG1
OU1:
CMPAL,-1
JZQRE2
NEXT1:
JMPOU1
QRE2:
OUTPUT1ENDP
KEYBORDPROCNEAR;
键盘子程序
MOVAL,0D1H
CLEARDISPLAY
WREP:
INAL,DX;
读状态
ANDAL,07H;
判断是否有按键
JZWREP
KEYN:
下一次的按键
MOVDX,PORT0
读数据
MOVBL,AL
ANDAL,07H
ANDBL,38H
MOVCL,03
SHRBL,CL
CMPBL,00H
JNZLINE1
ADDAL,08H
JMPQUIT1
LINE1:
CMPBL,01H
JNZLINE2
LINE2:
ADDAL,10H
QUIT1:
KEYBORDENDP
DISPPROCNEAR;
显示子程序
PUSHSI
PUSHCX
PUSHDX
MOVAL,90H
写地址为0000的显示缓存区命令,每次写入后地址自动加1指向下一次写入地址
MOVSI,OFFSETSEC1
MOVCX,0001
MOVBX,OFFSETLED
DISP1:
CLD
LODSB
MOVAH,AL
XLAT;
键盘码转显示码
显示
LOOPDISP1
POPDX
POPCX
POPSI
Q:
DISPENDP
MUSICPROCNEAR;
发音子程序
CMPAL,1
JLQUIT
CMPAL,8
JGQUIT;
若不在'
1'
-'
8'
之间转QUIT,不发音
MOVNUM,AL;
求出相应的时间常数的序号
MOVCX,60;
取60次32个正弦波数据
DDD:
MOVSI,0
LLL:
MOVAL,DATA1[SI];
取正弦波数据
MOVDX,IO0832A
放音
CALLDELAY;
调延时子程序
CMPSI,32;
是否取完32个数据
JLLLL;
若没有,则继续
LOOPDDD;
总循环次数60是否完,没有,则继续
D:
MOVDX,PORT1;
扫描实现任意键暂停
INAL,DX;
ANDAL,01H;
JNZFFF;
按键延时
JMPQUIT
FFF:
MOVCX,60
JMPD
QUIT:
MUSICENDP
DELAYPROCNEAR;
延时子程序
CCC:
MOVBX,OFFSETTIME
MOVDX,IO8253B;
置8253通道0为方式0工作
MOVAL,10H
OUTDX,AL
MOVDX,IO8255B;
设8255A口输入
MOVAL,9BH
MOVAL,NUM;
取相应的时间常数
XLAT
MOVDX,IO8253A
向8253通道0输出
KKK:
MOVDX,IO8255A
从8255A口读一字节
TESTAL,01;
判PA0口是否为1
JZKKK;
若不为1,则转KKK
RET;
子程序返回
DELAYENDP
CODEENDS
ENDSTART
五、调试情况及其分析
源程序完成后,进行子程序与程序的调试工作,程序调试过程、完成情况及其分析按以下顺序进行:
1.主程序简单电子琴功能
主程序要求完成的功能有:
电子琴简单功能实现以及利用由8279芯片控制的小键盘(含数码管、键盘阵列)实现控制电子琴。
主程序由电子琴实验和键盘控制实验的两个程序有机组成,两个程序简单拼凑在一齐是不能实现的。
经过实际调试和修改,将原电子琴程序改为2个子程序:
music(实现播放音阶)和delay(实现播放音阶时延时);
将原键盘控制程序改为1个主程序:
key1、keybord(键盘扫描及输入)和disp(显示)。
各个子程序通过寄存器al通信,al存有当前输入的键盘码,同时为music、disp两子程序服务。
调试后,主程序能实现课程设计要求的功能,并且界面清晰、操作容易。
2.子程序录音功能
这是其中一个扩展功能,实现即时播放并录音。
(具体功能可见前面的设计思路)
录音功能刚写好时,只能实现录音时播放音阶但不能实现录音时显示音阶。
程序中依次调用keybord、music、disp子程序,即在disp子程序不能实现,观察键盘控制的原始程序,发现keybord扫描键盘之后,将当前输入的键盘码存入寄存器al中,而disp显示功能是从显示缓存区中读取键盘码。
将keybord扫描存储在al中的键盘码存入显示缓冲区,使得disp显示子程序能在显示缓冲区中读取键盘码并加以显示,使得两个子程序有效通信。
3.子程序放录音功能
这是与录音相配套的扩展功能,实现任何时候(录音的数据已存入录音缓存区song)播放录音缓存区所记录的最近一次录音。
由于录音功能成功调试,此子程序与录音功能相当类似,注意加上两子程序通信语句,调试十分顺利,成功实现放音功能。
4.子程序放歌(已预存)功能
此功能将一首预存的歌曲播放,此功能可以调用放录音的子程序实现,唯一不同就是根据键盘的输入控制,选择播放的缓存区是录音缓存区或是预存歌缓存区。
5.子程序暂停功能
程序中,实现的扩展功能中包括在播放录音曲目和预设曲目时,可以按任意键暂停,然后再按任意键继续从断开处播放。
按任意键后,AL置1,进入CALLMUSIC的死循环,于是我们想到了让死循环不跳转到MUSIC,只在本身程序处循环,即不发音。
当在次按下任意键时,由于AL变成2,所以跳出了循环,回到了放歌和放录音的程序中,继续播放。
从而实现了放录音和放预设歌时的暂停和重起。
6.源程序整体功能
将各子程序调试完成后,进行最后的源程序整体功能调试。
调试过程中我们注意到:
a.程序模块化(功能分为若干子程序)能使源程序清晰,调试简单,因此在调试中我们还将源程序进一步模块化。
b.注意子程序之间的通信方式,这里基本用到的是寄存器al(内含键盘码),所以对al的使用应十分谨慎。
c.调用子程序前,使用push/pop保护了一些子程序会用到的主程序同时会用到的寄存器,保证调用之后主程序的顺利执行。
在调试过程中出现的一些小问题,我们都根据以上3点总结出的经验作为原则进行调试,调试过程十分顺利。
最后根据电子琴的实际用途加上了一些必要清晰的提示性语句,使界面更加友好。
六、实验总结:
经过这个课程设计,虽然时间比较短,完成任务的效果不是很理想,但是既然自己尝试
过,就肯定学到了不少东西,也真正体会到做电子设计行业工作的辛苦,不过自己收获还是挺大的。
这次课程设计对我综合运用所学知识的能力的提高有不小的帮助,之前做的实验都是很简单的编程,跟硬件结合也没有这么复杂,实现的功能都比较简单,可是这次要实现的功能相对来说比较复杂,要求掌握的知识比较综合。
经过短短一周的课程设计,我认识到,课程设计能真正让人学到实际应用的东西的一门课程。
收获比上几星期课还多。
首先,要实现题目要求的功能并有所创新,我们必须全心地投入其中,养成一种敢于钻研敢于创新的习惯。
在把课程要求实现到实际中来的过程中,首先必须清楚明白地了解几个参考程序的每一行的意思,这就需要敢于静心钻研。
为了把使得程序更加完整,就必须进行创新,这就需要敢于创新。
其次,通过课程设计,让我在课本的基础上,更深入的了解了各种芯片的用法和程序的完成过程,调试方法及技巧。
为了了解键盘,查找了不少8279芯片的资料,了解了键盘的初始化,存取缓存,扫描键盘,读取键码以及键码和显示码之间的转换。
为了实现基本功能,认真研究了参考程序的意义,了解了电子琴的不同音阶放音功能的实现,长短音的实现,更深入了解了8253计时器的使用方法。
编写程序的过程中,体会最深的是子程序的调用和程序的条理问题,一个程序就算功能实现了,但是也要使主程序和子程序的条理分明,易读性高,才能算一个比较好的程序。
调试程序中,学习了DEBUG的使用,DEBUG对检查程序的错误作用很大。
同时,也要灵活使用各种调试方法,来缩小寻找错误的范围。
检查程序过程中,在充分思考的基础上多次实验是检查改正程序的良方。
在设计扩展功能的过程中,大胆想像并且用多种思路来求解实现目标是必备的武器。