基于51单片机的电子琴设计【附原理图、PCB和程序】

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

课程设计说明书

题目:基于单片机的电子琴设计院(系):电子工程与自动化学院专业:测控技术与仪器(卓越) 学生姓名:

学号:

指导教师:

2013 年9 月21 日

目录

1 摘要 (1)

2 关键字 (1)

3 设计任务及要求 (1)

4 方案可行性论证 (1)

5 程序框图 (2)

6 关键单元电路与程序介绍 (3)

6.1 复位与震荡电路 (3)

6.2 4x4矩阵键盘 (3)

6.3数码管与LED灯 (4)

6.4 蜂鸣器 (6)

6.5 音乐相关知识 (7)

7 调试过程 (11)

8 总结与体会 (11)

9 参考文献 (11)

10 附录 (12)

10.1 设备与仪器 (12)

10.2 软件 (12)

10.3 原件清单 (12)

10.4原理图与PCB图 (13)

10.5 总程序 (14)

10.6 实物图 (31)

【摘要】:

打造一个多功能电子琴,核心是一块单片机。单片机读取键值,为内置定时器赋初值,定时器每溢出一次,驱动蜂鸣器的引脚电平就取反一次,产生相应频率的方波,即音调;设好键值与数码管段码表的对应关系,键按下时,数码管显示对应音调。

一首音乐储存在一个表中,表中的数据是音调与节拍,单片机读取音符的音调与节拍,根据音调赋予定时器初值,根据节拍决定定时器工作的时间,也就是蜂鸣器响的时间,一个接一个地读取音符,即可播放一首歌曲。

节拍用led灯的点亮个数表示。单片机读取音乐表中的节拍,控制led 灯的点亮个数,达到显示节拍的效果。

特别要注意的是:该方案采用了两个定时器,T0、T1。T0作为驱动蜂鸣器的定时器,要给予高优先级,不然会被T1干扰,音质变差。

【关键字】:单片机、stc89c52、电子琴、C51、keil。

【设计任务及要求】:

1.通过按键能够发出相应的音符并播放产生乐音,实现演奏;

2.演奏的同时可数字显示当前的音调,利于培养乐感

3.可以选定播放固定乐曲自动演奏,演奏时LED进行节拍指示;

4.在自动演奏和奏乐的过程中按停止键则中断演奏;

5.可以选择调节音或小。

【方案可行性论证】:

本课题采用stc89c52单片机作为核心器件,实现基本的音乐弹奏、音乐播放、音调显示和音乐节拍指示的功能。

1.音乐弹奏:通过程序识别4x4矩阵键盘中按下的键的坐标(x,y),

然后根据(x,y)从计数初值表中读取对应的计数初值,赋值给定时器0,定时器产生对应频率的方波,达到播放对应音调的功能。

2.音乐播放:先建立一个包含一首音乐的音调与节拍的表。其中,音调

就是0x01(低音、do)、0x12(中音、re)、0x23(高音、mi)之类的数;节拍就是0x02(半拍),0x04(一拍)之类的数。然后,根据音调读取计数初值,再将计数初值赋给定时器T0 -> 开启定时器T0 -> 读取节拍并延时 -> 关闭定时器T0 。这样就发出了一个音,然后再读下一个音的初值与节拍,重复上一个操作即可。(具体实现方法见附录总程序)

3.数码管显示音调:

①按键:读出按键坐标(x,y),用if语句来判断(x,y)该给数码管赋什

么值,然后从uchar code nu m[] 表中读取这个值赋给数码管(例如P0)。

②播放歌曲时:读入音调,根据音调的值来判断num[i]这个表中的i,再把num[i]赋给P0口。

4.led灯的节拍指示:采用定时器1来控制,作为节拍指示。

①按键时:根据按下的时长来控制led的点亮个数,并且是按一定

的时间间隔逐个点亮;释放按键时,led灯按一定的时间间隔逐个熄灭,从而达到一种比较简单的节拍指示效果。

②播放音乐时:根据音符的节拍,控制点亮到哪一个灯,在点亮那

个灯之前,前面的灯逐个等时距点亮。音符结束后,led灯全部一起熄

灭。这样,达到了一个精确显示节拍的效果。

【复位与震荡电路】:

原件的参数如图所示。

C1,C2 可采用30pF 无极

性陶瓷电容;C3可采用10µF

记性电解质电容。

值得注意的是,晶振不能

随便摸!尤其在通电工作的时

候,触摸容易损坏。自从摸过

一次后,震荡频率变得不稳

定,蜂鸣器声音时好时坏。

【4x4矩阵键盘】:

键盘扫描的基本思路是:先得出触发按键的“行”,即横坐标x,再得出他的“列”,即纵坐标y。

以下是获取横坐标x的代码:

uchar key_x() /*P1口高位接纵坐标(P1.7 - P1.4)低位接横坐标(P1.3 - P1.0)*/

{

uchar i;

P1 = 0x0f; /*有按键按下后对应按键的横坐标电位被拉低(注意低电位引脚不能被高电位引脚抬高,只能是低电位拉低高电位)*/

if(P1_0 == 0)

{ delayms(5); //延时5ms 去抖动

if(P1_0 == 0)

i = 1;

}

else if(P1_1 == 0)

{ delayms(5);

if(P1_1 == 0)

i = 2;

}

else if(P1_2 == 0)

{ delayms(5);

if(P1_2 == 0)

i = 3;

}

else if(P1_3 == 0)

{ delayms(5);

if(P1_3 == 0)

i = 4;

}

else

i = 0;

return (i); //0表示按键未按下

}

获取y的方法与获取x的方法类似,具体可以参考附件总程序。

得到触发按键的坐标(x,y)之后,可以通过x,y的值来确定按键的功能。例如x==1,y==1时(S1按下),可以让数码管显示1:

if(x == 1 && y == 1)

P0 = led_table[1];

或者更方便一点:if(x == 1)

P0 = led_table[y];

就能显示第一行的所有的数了。

【数码管与LED灯】:

数码管:

相关文档
最新文档