目录
- 基于单片机的声光电子琴
-
- 一、作品展示
-
- 1.1.作品实物图
- 1.2.焊接布局图
- 1.3、PCB原理图
- 1.4、PCB图
- 二、设计过程
-
- 2.1.系统基本设计理念
-
- 2.1.1、 各部分说明
- 2.1.2.系统工作过
- 2.2 单元电路方案论证
-
- 2.2.1 控制器模块
- 2.2.2 发声模块
- 2.2.3 编程软件模块
- 2.2.4 最终方案
- 2.3 、AT89C51 单片机
- 三、硬件电路设计
-
- 3.1.最小系统设计
- 3.2 时钟电路
- 3.3 复位电路
- 3.4 按键控制模块
- 3.5 播放模块
- 四、程序流程
-
- 4.1 程序流程图
- 五、程序代码
- 六、资源获取
基于单片机的声光电子琴
注:本毕业资源可在微信公众号上:Kevin的学习站” 获取!有问题可以加我。QQ:643470489一起交流哦!
一、作品展示
1.1.作品实物图
1.2.焊接布局图
1.3、PCB原理图
1.4、PCB图
二、设计过程
2.1.系统基本设计理念
此设计是在LED小灯显示灯光的变换,扬声器播放音乐。电路包括:键盘、单片机和LED显示电路,声音电路。
2.1.1、 各部分说明
(1)键盘用于演奏音乐,8个按钮和8个音符。
(2)单片机通过输出各种电脉冲信号来控制正常工作。
(3)单片机发送的信号分别通过LED显示电路最终通过译码进行了解码LED通过扬声器显示小灯和声音电路。
2.1.2.系统工作过
单片机产生音频脉冲的主要处理过程是CPU中完成的,CPU会随时对音符输入信号进行读取数据的操作。在读取了相应的寄存器的值后,CPU处理读取值,然后通过I/O口通过扬声器播放音乐。
2.2 单元电路方案论证
根据设计要求,该系统主要由控制器模块、显示模块和输入模块组成。为了更好地实现每个模块的功能,我们分别设计了以下方案并进行了论证。
2.2.1 控制器模块
方案1:以凌阳系列单片机为系统的控制器
凌阳系列单片机可实现各种复杂的逻辑功能,模块大,密度高,集成芯片上的所有设备,减少体积,提高稳定性。凌阳系列单片机提高了系统的处理速度,适用于大型实时系统的控制核心。
方案2:系统控制器采用51系列
单片机算术操作功能强,软件编程灵活,自由度大,可用于软件编程,实现各种算法和逻辑控制。由于其功耗低、体积小、技术成熟、成本低,广泛应用于各个领域。而且抗干扰性好。
由于51台单片机的价格远低于凌阳系列,且本设计不需要很高的处理速度,从经济和使用方便的角度来看,本设计选择了方案2。
2.2.2 发声模块
声音模块是本设计的主要组成部分。
基本方案:发生电路是设计电路中最重要的组成部分。它在放大和输出单片机产生的声音信号方面起着重要作用,我设计的声音电路主要由两个组成CS9013组成。CS9013是一种小功率放大管,属于NPN型三极管,判断三极管引脚的方法如下。
1.判断三极管的基极。对于NPN型号的三极管,用黑色表笔连接一个电极,红色表笔连接另外两个电极。如果测量电阻值较小,更换表笔后测量的电阻值较大,则可以判断黑色表笔在第一次测量中连接基极;如果测量值大小,差异很大,则黑色表笔不是基极,应更换其他电极进行重测。
2.测量三极管发射极E和集电极c。确定三极管基极后,通过交换表笔测量两次e,c极间电阻,如果两次测量结果不相等,其中测量电阻值较小的一次是e极黑表笔连接c极。对于PNP型号的三极管,方法与NPN相似,但红黑表笔的作用相反,在测量中e,c注意极间电阻,因为三极管V(BR)CEO很小,很容易击穿发射结。
当我们判断三极管的管脚时,我们可以用两个三极管形成达林顿结构。首先,当单片机P1.0口输出一个高电平,由两个三极管组成的达林顿成能导通,可以在一定程度上放大电流,这样当信号传输到扬声器时,我们听到信号。
2.2.3 编程软件模块
方案1:汇编语言编程
汇编语言指令用一些具有相应意义的助记符来表达,因此比机器语言更容易掌握和使用,但另一方面,它应该直接使用CPU与高级程序设计语言相比,资源难以掌握。
方案2:C语言编程
C与其他高级语言相比,语言具有操作符的丰富性、语法表达的灵活性、软硬件操作的兼容性、输入输出模式的新颖性等主要特点.对这些特征的深入分析和研究可以加深对C语言的理解;正确运用这些特征可以灵活有效地解决各种实际问题.
因为大学期间对汇编语言没有深入的了解,编程时总是用C语言,所以选择了方案2。
2.2.4 最终方案
经过反复论证,最终确定了以下方案:
(1)采用STC89C51单片机作为主控制器。
(2)利用达林顿效应放大音乐信号
(3)C语言编程
2.3 、AT89C51 单片机
AT89S51功耗低,性能高CMOS 8位单片机,片位单片机k Bytes ISP(In-system programmable)可反复擦写1000次Flash只读程序存储器,使用设备ATMEL公司制造高密度、非易失性存储技术,与标准兼容MCS -51指令系统及80C51引脚结构,芯片集成了8个通用的中央处理器和ISP Flash存储单元,功能强大的微型计算机AT89S51可为许多嵌入式控制应用系统提供高性价比的解决方案。 AT89S51具有以下特点:40个引脚,4个引脚k Bytes Flash128 bytes数据存储器的随机存取(RAM),外部双向输入/输出32(I/O)2层中断嵌套中断5个中断优先级,2个16个可编程定时计数器,2个 全双工串行通信口,看门狗(WDT)电路,片内时钟振荡器。 AT89S51引脚图 此外,AT89S51设计配置振荡频率0Hz省电模式可以通过软件设置。在空闲模式下,CPU暂停工作RAM定时计数器,串行口,外中断 该系统可以继续工作,并在断电模式下冷冻振荡器RAM在外部中断激活或硬件复位之前,停止芯片的其他功能。芯片也有PDIP、TQFP和PLCC等三 适应不同产品需求的各种封装形式。 主要功能特点: · 兼容MCS-51指令系统 · 4k可反复擦写(>1000次)ISP Flash ROM · 32个双向I/O口 · 4.5-5.5V工作电压 · 可编程定时/计数器 · 时钟频率0-33MHz · 全双工UART串行中断线 · 128x8bit内部RAM · 两个外部中断源 · 低功耗空闲和省电模式 · 中断唤醒省电模式 · 3级加密位 · 看门狗(WDT)电路 · 软件设置空闲和省电 · 灵活的ISP字节和分页编程 · 双数据寄存器指针
STC89C51是一种带8K字节可编程可以去除只读存储器的低电压和高性能COMOS8位微处理,俗称单片机。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。
单片机引脚图如图所示
图1 STC89C51单片机引脚图
三、硬件电路设计
3.1、最小系统设计
最小系统包括单片机及其所需的必要的电源、时钟、复位等部件,能使单片机始终处于正常的运行状态。电源、时钟等电路是使单片机能运行的必备条件,可以将最小系统作为应用系统的核心部分,通过对其进行存储器扩展、A/D扩展等,使单片机完成较复杂的功能。
3.2 时钟电路
STC89C51内部有一个用于构成振荡器的高增益反相放大器,引脚RXD和TXD分别是此放大器的输入端和输出端。时钟可以由内部方式产生或外部方式产生。内部时钟在此不做详细介绍。外部方式的时钟电路如图3所示,RXD接地,TXD接外部振荡器。对外部振荡信号无特殊要求,只要求保证脉冲宽度,一般采用频率在12MHz左右的方波信号。
图2 89c51内部时钟电路
3.3 复位电路
当在89C51单片机的RST引脚引入高电平并保持2个机器周期时,单片机内部就执行复位操作(若该引脚持续保持高电平,单片机就处于循环复位状态)。
复位电路通常采用上电自动复位和按钮复位两种方式。
最简单的上电自动复位电路中上电自动复位是通过外部复位电路的电容充放电来实现的。只要Vcc的上升时间不超过1ms,就可以实现自动上电复位。
除了上电复位外,有时还需要按键手动复位。本设计就是用的按键手动复位。按键手动复位有电平方式和脉冲方式两种。其中电平复位是通过RST(9)端与电源Vcc接通而实现的。按键手动复位电路见图4。时钟频率用11.0592MHZ时C取10uF,R取10kΩ。
图3 89C51 复位电路
3.4 按键控制模块
电子琴设有11个按键,其中8个作为音符输入。8个按键分别代表8个音符,包括中音段的全部音符,通过软硬件设计。另外3个分别是控制复位、流水灯的转换、自动播放音乐。
如下图:
3.5 播放模块
播放模块是由2个三极管构成,三级管将信号放大,然后传输到喇叭,喇叭它几乎不存在噪声,音响效果较好。
下图是该模块电路:
四、程序流程
4.1 程序流程图
该设计方案是通过按键随意按下所要表达的音符,作为电平送给主体电路,中央处理器通过识别,解码输出音符,在扬声器中发出有效的声音。通过这样可以不断的弹奏我们想要的音符或者是音调,电路由复位电路,指示灯电路,和功能按键电路组成,通过功能键可以选择播放音乐或者弹奏音节,硬件主要有下面几个部分组成。
五、程序代码
/* 8个按键发出8个基本音, 能播放内置音乐,音乐跟随灯光闪烁 */
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit speaker=P1^4;//喇叭接30脚
sbit key1=P1^0;//流水灯按键(暂时)
sbit key2=P1^1;//播放音乐按键(暂定)
uchar a,b,num1,s1num,n1,n2;
uchar qushu=0;
char num;//定义num为可以负数
uchar code yinfu[]={
0xfb,0xe9, //Do
0xfc,0x5c, //Re
0xfc,0xc1, //Mi
0xfc,0xef, //Fa
0xfd,0x45, //So
0xfd,0x92, //La
0xfd,0xd0, //Si
0xfd,0xee, //Do#
0x00,0x00, //间隔
};
uchar code shengri_tone[]={
1,0,1,2,1,4,3,0, //生日快乐音调
1,0,1,2,1,5,4,0,
1,0,1,8,6,4,3,2,0,
7,0,7,6,4,5,4,0 //0代表不发声,即停顿;数字即为音调
};
uchar code laohu_tone[]={
1,2,3,1,0,1,2, //两只老虎乐谱 40个音符
3,1,0,3,4,5,0,3,
4,5,0,5,6,5,4,3,
1,0,5,6,5,4,3,1,
0,3,2,1,0,3,2,1,0
};
uchar code yishan_tone[]={
1,1,5,5,6,6,5, //星星乐谱 54个音符
0,4,4,3,3,2,2,
1,0,5,5,4,4,3,
3,2,0,5,5,4,4,
3,3,2,0,1,1,5,5,
6,6,5,0,4,4,3,
3,2,2,1,0
};
uchar code shengri_beat[]={
24,1,24,48,48,48,72,5,//节拍
24,1,24,48,48,48,72,5,
24,1,24,48,48,48,48,72,5,
24,1,24,48,48,48,72,5 //节拍,即tone表各音调的延时
};
uchar code laohu_beat[]={
24,24,24,48,5,24,24,//节拍
24,48,5,24,24,48,5,24,
24,72,5,24,24,24,24,//节拍
24,48,5,24,24,24,24,24,72,
5,24,24,48,5,24,24,//节拍
72,5//节拍 //节拍,即tone表各音调的延时
};
uchar code yishan_beat[]={
24,24,24,24,24,24,48,//节拍
5,24,24,24,24,24,24,72,
5,24,24,24,24,24,24,//节拍
48,5,24,24,24,24,24,24,72,
5,24,24,24,24,24,24,//节拍
48,5,24,24,24,24,24,24,72,5//节拍,即tone表各音调的延时
};
uchar code ledtable[]={
0x7f,0xbf,0xdf,0xef, //取反
0xf7,0xfb,0xfd,0xfe};//P0组口的发光二极管代码(焊接过程可能会相反,具体更改)
uchar code ledtable2[]={
0x7f,0xbf,0xdf,0xef, //取反
0xf7,0xfb,0xfd,0xfe};//P2组口发光二极管代码,相反!
void check_key();//改为P3组为按键
void keyscan();
void turn();//顺时针流动
void back();
void qianhou();
void dangshuang();
void delay(uint z);//延时函数声明
void delay1(void);//声明第二个延时函数
void play1(void);//播放生日快乐
void main()
{
s1num=0;//流水灯种类标志
key1=1;
key2=1;
TMOD=0x01;
TH0=a;
TL0=b;
ET0=1;//打开定时器,但是未允许中断
TR0=1;
while(1)
{
check_key();
keyscan();
}
}
void time0() interrupt 1
{
TH0=a;
TL0=b;
speaker=~speaker;
}
void check_key()
{
P3=0xff;//先赋给P2组口高电平
switch(P3)//按下一个键相应4个灯亮
{
case 0xfe:P0=0xee;P2=0x77;a=0xfb;b=0xe9;EA=1;break;//P0,P2组为发光二极管组
case 0xfd:P0=0xdd;P2=0xbb;a=0xfc;b=0x5c;EA=1;break;//注意:EA不能改为TR0
case 0xfb:P0=0xbb;P2=0xdd;a=0xfc;b=0xc1;EA=1;break;
case 0xf7:P0=0x77;P2=0xee;a=0xfc;b=0xef;EA=1;break;
case 0xef:P0=0xee;P2=0x77;a=0xfd;b=0x45;EA=1;break;
case 0xdf:P0=0xdd;P2=0xbb;a=0xfd;b=0x92;EA=1;break;
case 0xbf:P0=0xbb;P2=0xdd;a=0xfd;b=0xd0;EA=1;break;
case 0x7f:P0=0x77;P2=0xee;a=0xfd;b=0xee;EA=1;break;
default:EA=0;speaker=0;//P0=0xff;P2=0xff ;
}
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void keyscan()
{
if(key1==0)
{
delay(5);
if(key1==0)
{
s1num++;
while(!key1);
if(s1num==1)
{
turn();
}
}
if(s1num==2)
{
back();
}
if(s1num==3)
{
qianhou();
}
if(s1num==4)
{
dangshuang();
}
if(s1num==5)
s1num=1;
}
if(key2==0)
{
delay(5);
if(key2==0)
{
qushu++;
if(qushu==4)
{
qushu=1;
}
while(~key2);
play1();
}
}
}
void delay1(void)//第二个延时函数
{
uchar n=15;
while(n--)
{
uchar i;
for(i=0;i<125;i++);
}
}
void play1(void)//播放生日快乐
{
uchar m=0;
uchar s;
uchar c=1;
P0=0xaa;
P2=0x55;
if(qushu==1)
{
while(1)
{
EA=0;
c=shengri_tone[m]; //取音符
s=shengri_beat[m]; //取节拍
a=yinfu[2*c-2];
b=yinfu[2*c-1];
EA=1;
while(s--)
{
delay1();
P0=~P0;
P2=~P2;
}
m++;
if(m>=33) return; //数值是shengri相关表中的元素数量
}
}
else if(qushu==2)
{