可存储电子琴.docx
- 文档编号:4962570
- 上传时间:2022-12-12
- 格式:DOCX
- 页数:15
- 大小:587.92KB
可存储电子琴.docx
《可存储电子琴.docx》由会员分享,可在线阅读,更多相关《可存储电子琴.docx(15页珍藏版)》请在冰豆网上搜索。
可存储电子琴
计算机科学与技术学院
硬件课程设计报告
姓名:
学号:
专业:
计算机
班级:
计算机
设计题目:
可存储电子琴
指导教师:
职称:
副教授
2013年12月徐州
课程设计指导教师评阅书
指导教师评语:
成绩:
指导教师签字:
年月日
摘要
本实验为可存储电子琴,报告内容包含了总体设计方案,详细的设计思路流程图,对芯片的地址与工作方式进行了说明,并附上了所用芯片的详细介绍与程序代码,报告最后是我在这次实验中的体会与收获。
关键词:
总体电路;总体设计流程图;芯片地址;芯片介绍;程序代码;实验体会。
1设计任务与要求………………………………………………………………………5
2总体方案…………………………………………………………………………5
2.1设计电路与说明…………………………………………………………………5
2.2芯片与按键说明………………………………………………………………5
2.2.1芯片地址与控制字……………………………………………………………………5
2.2.2按键说明……………………………………………………………………………5
2.3总体设计流程图……………………………………………………………………7
2.4实物连线图…………………………………………………………………………8
3硬件方案…………………………………………………………………………8
3.18255A芯片介绍…………………………………………………………………8
3.28253芯片介绍……………………………………………………………………10
4软件方案………………………………………………………………………………13
4.1程序代码…………………………………………………………………………13
5收获与体会……………………………………………………………………………17
参考文献………………………………………………………………………………17
1设计任务与要求
利用8255A、8253芯片和4×4键盘、喇叭等器件设计硬件可存储式电子琴,并且具备如下功能:
当按下琴键时,扬声器发出该琴键相对应的音阶,同时可以通过按键录制所发出的音节并播放出来。
2.总体方案
2.1设计电路与说明
图2.1设计电路
说明:
键盘扫描,把扫描到的值给8255A,8255A再把信号给8253,不同的按键,赋给不同的初始计数,然后产生不同频率的方波,输出端给喇叭,并控制喇叭的放音的开关,既可以发出不同的声音。
2.2芯片与按键说明
2.2.1芯片地址与控制字
(1)8253芯片控制字地址为283H,控制字00010110
(2)8255A芯片A口地址为288H,B口地址为289H,
C口地址为28aH,控制口地址为28bH,
控制字为10000000。
2.2.2按键说明
1
发dou音
6
发la音
2
发rai音
7
发xi音
3
发mi音
8
播放预存曲
4
发fa音
A
开始录音
5
发sou音
B
播放录音
2.3总体设计流程图
N
Y
Y
N
Y
N
Y
N
N
Y
2.4实物连线图
3硬件方案
3.1.8255A芯片介绍
8255可编程外围接口芯片是Intel公司生产的通用并行I/O接口芯片,它具有A、B、C三个并行接口,并行接口是以数据的字节为单位与I/O设备或被控制对象之间传递信息。
CPU和接口之间的数据传送总是并行的,即可以同时传递8位、16位、32位等。
用+5V单电源供电,能在以下三种方式下工作:
方式0--基本输入/出方式、方式1--选通输入/出方式、方式2--双向选通工作方式。
8255的内部结构及引脚如图3.1
图3.1内部结构及引脚
为读信号线,与其他信号线一起实现对8255接口的读操作。
通常接系统总线的
信号。
为写信号线,与其他信号一起实现对8255的写操作,通常接系统总线的
。
为片选信号线,当它为低电平时,才能选中该8255芯片,也才能对8255进行操作。
D0~D7:
三态双向数据总线,8255与CPU数据传送的通道,当CPU执行输入输出指令时,通过它实现8位数据的读/写操作,控制字和状态信息也通过数据总线传送。
PA0~PA7:
端口A输入输出线,一个8位的数据输出锁存器/缓冲器,一个8位的数据输入锁存器。
PB0~PB7:
端口B输入输出线,一个8位的I/O锁存器,一个8位的输入输出缓冲器。
PC0~PC7:
端口C输入输出线,一个8位的数据输出锁存器/缓冲器,一个8位的数据输入缓冲器。
端口C可以通过工作方式设定而分成2个4位的端口,每个4位的端口包含一个4位的锁存器,分别与端口A和端口B配合使用,可作为控制信号输出或状态信号输入端口。
这里的8255接口所占地址范围为0680H~0686H。
当对8255接口进行写操作时,各信号线的状态如表5.1所示
表3.1
CS
A1
A0
IOR
IOW
操作
0
0
0
1
0
写A口
0
0
1
1
0
写B口
0
1
0
1
0
写控制寄存器
0
1
1
1
0
写C口
8255在应用过程中,将不同的控制字装入芯片中控制寄存器,即可确定8255的工作方式。
8255的控制字由8位二进制数构成,各位的控制功能如图3.2所示:
图3.28255控制字
基于以上,本硬件实验(电子琴)用到的控制字为10000000,工作于方式0,基本输入输出,B口输出,C口位输出。
3.28253芯片介绍
图5.38253芯片引脚图
8253是可编程计数器/定时器,内部有三个计数器,分别为计数器
0、计数器1和计数器2,一个时钟输入端CLK,一个为门控信号输入端GATE,另一个为输出端OUT。
每个计数器内部有一个8位的控制寄存器。
8253的通道:
8253有3个通道,分别为通道0、通道1和通道2。
8253中各通道可有6种可供选择的工作方式,以完成定时、计数或脉冲发生器等多种功能。
8253的各种工作方式如下:
(1)方式0:
计数结束则中断
工作方式0被称为计数结束中断方式。
当任一通道被定义为工作方式0时,OUT输出为低电平;若门控信号GATE为高电平,当CPU利用输出指令向该通道写入计数值WR#有效时,OUT仍保持低电平,然后计数器开始减“1”计数,直到计数值为“0”,此刻OUT将输出由低电平向高电平跳变,可用它向CPU发出中断请求,OUT端输出的高电平一直维持到下次再写入计数值为止。
在工作方式0情况下,门控信号GATE用来控制减“1”计数操作是否进行。
当GATE=1时,允许减“1”计数;GATE=0时,禁止减“1”计数;计数值将保持GATE有效时的数值不变,待GATE重新有效后,减“1”计数继续进行。
显然,利用工作方式0既可完成计数功能,也可完成定时功能。
当用作计数器时,应将要求计数的次数预置到计数器中,将要求计数的事件以脉冲方式从CLK端输入,由它对计数器进行减“1”计数,直到计数值为0,此刻OUT输出正跳变,表示计数次数到。
当用作定时器时,应把根据要求定时的时间和CLK的周期计算出定时系数,预置到计数器中。
从CLK,输入的应是一定频率的时钟脉冲,由它对计数器进行减“1”计数,定时时间从写入计数值开始,到计数值计到“0”为止,这时OUT输出正跳变,表示定时时间到。
有一点需要说明,任一通道工作在方式0情况下,计数器初值一次有效,经过一次计数或定时后如果需要继续完成计数或定时功能,必须重新写入计数器的初值。
(2)方式1:
单脉冲发生器
工作方式1被称作可编程单脉冲发生器。
进入这种工作方式,CPU装入计数值n后OUT输出高电平,不管此时的GATE输入是高电平还是低电平,都不开始减“1”计数,必须等到GATE由低电平向高电平跳变形成一个上升沿后,计数过程才会开始。
与此同时,OUT输出由高电平向低电平跳变,形成了输出单脉冲的前沿,待计数值计到“0”,OUT输出由低电平向高电平跳变,形成输出单脉冲的后沿,因此,由方式l所能输出单脉冲的宽度为CLK周期的n倍。
如果在减“1”计数过程中,GATE由高电平跳变为低电乎,这并不影响计数过程,仍继续计数;但若重新遇到GATE的上升沿,则从初值开始重新计数,其效果会使输出的单脉冲加宽,如教材图9-22(b)中的第2个单脉冲。
这种工作方式下,计数值也是一次有效,每输入一次计数值,只产生一个负极性单脉冲。
(3)方式2:
速率波发生器
工作方式2被称作速率波发生器。
进入这种工作方式,OUT输出高电平,装入计数值n后如果GATE为高电平,则立即开始计数,OUT保持为高电平不变;待计数值减到“1”和“0”之间,OUT将输出宽度为一个CLK周期的负脉冲,计数值为“0”时,自动重新装入计数初值n,实现循环计数,OUT将输出一定频率的负脉冲序列,其脉冲宽度固定为一个CLK周期,重复周期为CLK周期的n倍。
如果在减“1”计数过程中,GATE变为无效(输入0电平),则暂停减“1”计数,待GATE恢复有效后,从初值n开始重新计数。
这样会改变输出脉冲的速率。
如果在操作过程中要求改变输出脉冲的速率,CPU可在任何时候,重新写人新的计数值,它不会影响正在进行的减“1”计数过程,而是从下一个计数操作用期开始按新的计数值改变输出脉冲的速率。
(4)方式3:
方波发生器
工作方式3被称作方波发生器。
任一通道工作在方式3,只在计数值n为偶数,则可输出重复周期为n、占空比为1:
1的方波。
进入工作方式3,OUT输出低电平,装入计数值后,OUT立即跳变为高电平。
如果当GATE为高电平,则立即开始减“1”计数,OUT保持为高电平,若n为偶数,则当计数值减到n/2时,OUT跳变为低电平,一直保持到计数值为“0”,系统才自动重新置入计数值n,实现循环计数。
这时OUT端输出的周期为n×CLK周期,占空比为1:
1的方波序列;若n为奇数,则OUT端输出周期为n×CLK周期,占空比为((n+1)/2)/((n-1)/2)的近似方波序列。
如果在操作过程中,GATE变为无效,则暂停减“1”计数过程,直到GATE再次有效,重新从初值n开始减“l”计数。
如果要求改变输出方波的速率,则CPU可在任何时候重新装入新的计数初值n,并从下一个计数操作周期开始改变输出方波的速率。
(5)方式4:
软件触发方式计数
工作方式4被称作软件触发方式。
进入工作方式4,OUT输出高电平。
装入计数值n后,如果GATE为高电平,则立即开始减“1”计数,直到计数值减到“0”为止,OUT输出宽度为一个CLK周期的负脉冲。
由软件装入的计数值只有一次有效,如果要继续操作,必须重新置入计数初值n。
如果在操作的过程中,GATE变为无效,则停止减“1”计数,到GATE再次有效时,重新从初值开始减“1”计数。
这种工作方式下,当计数值计到“0”后,系统将自动重新装入计数值n,但并不开始计数,一定要等到由GATE端引入的正跳沿,才会开始进行减“1”计数,因此这是一种完全由GATE端引入的触发信号控制下的计数或定时功能。
如果由CLK输入的是一定频率的时钟脉冲,那么可完成定时功能,定时时间从GATE上升沿开始,到OUT端输出负脉冲结束。
如果从CLK端输入的是要求计数的事件,则可完成计数功能,计数过程从GATE上升沿开始,到OUT输出负脉冲结束。
GATE可由外部电路或控制现场产生,故硬件触发方式由此而得名。
如果需要改变计数初值,CPU可在任何时候用输出指令装入新的计数初值m,它将不影响正在进行的操作过程,而是到下一个计数操作周期才会按新的计数值进行操作。
从上述各工作方式可看出,GATE作为各通道的门控信号,对于各种不同的工作方式,它所起的作用各不相同。
在8253的应用中,必须正确使用GATE信号,才能保证各通道的正常操作。
8253的控制字:
图5.48253控制字
基于以上,本硬件实验(电子琴)用到的控制字为:
00010110,即通道0计数,只读写低8位,方式3,2进制计数。
4软件方案
4.1程序代码
/*******************************/
/*电子琴*/
/*******************************/
////8253OUT0接与门输入端A,CS接Y0,GATE0接8255PB1,CLK0接2MHZ时钟,8255PB0接与门输入端B,CS接Y1,PC7~PC0用排线接键盘行3~列0
#include
#include
#include
#include
#include"ApiExusb.h"
#pragmacomment(lib,"ApiExusb.lib")
constintd5a=0x288;
constintd5b=0x289;
constintd5c=0x28a;
constintd5r=0x28b;
unsignedshorttime[]={0x0,0x4c,0xd9,0x2f,0xf7,0xe0,0xe8,0x99};//计数值的低位
unsignedshorttime1[]={0x0,0x0d,0x0b,0x0b,0x9,0x8,0x7,0x7};//计数值的高位
//{3829,3404,3033,2863,2551,2272,2024,1945};//*8253发不同音的计数器初值,将其换算为以上16进制
//1000000/各音阶标称频率值=计数初值
voidde_lay(unsignedshorti,unsignedshortj);//unsigned
voidsound(int);
voidsong(char*);
voidbsave();
voidbplay();
/************************/
/*键盘显示*/
/************************/
charled[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
/*上面为从0-f对应的段码表*/
char*hls="1155665004433221005540332055443320135067504433221";
charsongs[100]="";
intsave=-1;
voidmain()
{
bytedata;
bytei,j;
printf("Pressanykeytobegin!
\n\n");
getch();
if(!
Startup())/*打开设备*/
{
printf("ERROR:
OpenDeviceError!
\n");
return;
}
printf("pressanykeytoexit");
j=16;
while(!
kbhit())
{
PortWriteByte(0x28b,0x81);/*设置8255的A口C口均为输出*/
//PortWriteByte(0x288,led[j]);
PortWriteByte(0x28a,0x0f);
PortReadByte(0x28a,&data);
i=data;
if(i!
=0x0f)
{
i=data;
Sleep(50);
PortWriteByte(0x28b,0x88);
PortWriteByte(0x28a,0xf0);
PortReadByte(0x28a,&data);
i=i|data;
if(i==0x77)j=0;
elseif(i==0x7b)j=1;
elseif(i==0x7d)j=2;
elseif(i==0x7e)j=3;
elseif(i==0xb7)j=4;
elseif(i==0xbb)j=5;
elseif(i==0xbd)j=6;
elseif(i==0xbe)j=7;
elseif(i==0xd7)j=8;
elseif(i==0xdb)j=9;
elseif(i==0xdd)j=10;
elseif(i==0xde)j=11;
else;
cout<<(int)j< if(save>=0)songs[save++]=j+'0'; if(j==8)song(hls); elseif(j==10)bsave(); elseif(j==11)bplay(); elsesound(j); } } Cleanup();/*关闭设备*/ } voidsong(char*s) { intl=strlen(s); for(inti=0;i } voidsound(intk) { if(k==0){ Sleep(100); return; } PortWriteByte(0x283,0x36);//00010110,8254控制字,分高低位传送 Sleep(10); de_lay(time[k],time1[k]); Sleep(10); PortWriteByte(d5r,0x80);//10000000,8255控制字 Sleep(10); PortWriteByte(d5b,0x03);//设置8255C口,开扬声器 Sleep(120);/*延时*/ PortWriteByte(d5b,0x00);//设置8255C口,关扬声器 //Cleanup();/*关闭设备*/ } voidde_lay(unsignedshorti,unsignedshortj) { PortWriteByte(0x280,i);/*输出计数值低位*/ Sleep(50); PortWriteByte(0x280,j);/*输出计数值高位*/ } voidbsave() { cout<<"开始录制: \n"; save=0; } voidbplay() { songs[save-1]='\0'; cout<<"开始播放: \n"; song(songs); save=-1; } 5收获与体会 选到这个实验后,刚拿到手时一点思路都没有,也在犹豫到底是用C++写还是用汇编语言写,汇编写虽然麻烦,但是思路清晰,而C++的有点则是简洁明了,程序简单,因为毕竟以后要用到C++的时候多于汇编语言,所以这次实验我决定用C++来写,演示实验中给出的只是实现喇叭发声的代码,里目标功能的实现还差许多,于是我先研究了演示实验的代码,也采用了演示实验中的发声频率,但我将时钟改为2M赫兹,这样便可用低音频率发出中音音调。 因为自己在程序这方面学得不是很好,所以只能在模仿中改进。 实验中存储功能的函数,自己实在是写不出来,只好请教了同学,从中也学习了一些技巧。 通过这次实验,我有了一定的信心,这次实验的成果,也为我今后对于编程的学习奠定了基础。 参考文献: C++程序设计题解与上机指导谭浩强清华大学出版社
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 存储 电子琴
![提示](https://static.bdocx.com/images/bang_tan.gif)