基于51单片机音乐盒设计( proteus仿真+程序+原理图+PCB+报告+讲解视频)

音乐盒

  • 主要功能:
  • 仿真
  • 原理图PCB图
  • 程序设计:
  • 设计报告
  • 实物图
  • 资料清单(提供资料清单所有文件):
    • 资料下载链接:

基于51单片机音乐盒仿真设计( proteus仿真+程序+原理图+PCB+报告+讲解视频)

仿真图proteus 7.8及以上

程序编译器:keil 4/keil 5

编程语言:C语言

设计编号:S0030

主要功能:

本次课设是应用单片机原理和控制理论设计音乐演奏控制器的硬件电路,并利用C语言进行程序设计。通过控制单片机内部的定时器来产生不同频率的方波,驱动喇叭发出不同的音调的音乐,在利用延迟来控制发音时间的长短。把乐谱转化成相应的定时常数就可以从发音设备中演奏出悦耳的音乐。

2 设计说明

2.1设计要求

(1)利用I/O口产生一定频率的方波,驱动蜂鸣器,发出不同的音调,从而演奏乐曲

(2)可以实现歌曲顺序播放或单曲循环;

(3)存储三首以上歌曲

2.2 附加功能

(1)用数码管显示当前播放曲目;

(2) LED花样彩灯随播放音符变换;

(3)通过按键实现下一首歌的切换;

以下为本设计资料展示图:

仿真

img

开始仿真

开始仿真后,用数码管显示当前播放曲目, LED花样彩灯随播放音符变换,通过按键实现下一首歌的切换。通过拨动开关控制单循环还是全部循环。内置音乐《千年之恋》《寂寞沙洲冷》《七子之歌》《感恩的心》

原理图PCB图

img

程序设计:

img

sbit key1=P3^2;  /*暂停键 */
sbit key2=P3^3;  /* 切换歌曲键*/
sbit fm=P1^1;  /*蜂鸣器口*/
sbit P1_7=P1^7;
uchar count2=1; /*歌曲标志*/
uchar timeh,timel,i;

uchar code DSY_table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
						0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x70};  
uint code tone_delay_table[]={ 64021,64103,64260,64400,64524,64580,64684,
							64777,64820,64898,64968,65030,65058,65110,65157,65178};/*每个音符对应的延迟*/
uchar code huayang[]={0xff,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0x0f,0xf0,0x00};

void delay_ms(uchar x) /*延迟函数*/
{
	uchar i;
	while(x--)
	for(i=0;i<120;i++);
}


uchar code qnzl[]={   /*千年之恋*/
0x12,0x22,0x34,0x84,0x74,0x54,0x38,0x42,0x32,0x22,0x42,0x34,0x84,0x72,0x82,0x94,0xA8,0x08,
0x32,0x31,0x21,0x32,0x52,0x32,0x31,0x21,0x32,0x62,
0x32,0x31,0x21,0x32,0x82,0x71,0x81,0x71,0x51,0x32,0x22,
0x32,0x31,0x21,0x32,0x52,0x32,0x31,0x21,0x32,0x62,
0x32,0x31,0x21,0x32,0x83,0x82,0x71,0x72,0x02,
0x63,0xA1,0xA2,0x62,0x92,0x82,0x52,
0x31,0x51,0x63,0x51,0x63,0x51,0x63,0x51,0x62,0x82,0x7C,0x02,
0x61,0x71,0x82,0x71,0x62,0xA2,0x71,0x76,
0x61,0x71,0x82,0x71,0x62,0x52,0x31,0x36,
0x61,0x71,0x82,0x71,0x62,0xA3,0x73,0x62,0x53,
0x42,0x63,0x83,0x83,0x91,0x91,
0x61,0x71,0x82,0x71,0x62,0x0A2,0x71,0x76,
0x61,0x71,0x82,0x71,0x62,0x52,0x31,0x36,
0x61,0x71,0x82,0x71,0x62,0xA3,0x73,0x62,0x53,
0x42,0x82,0x88,0x02,0x74,0x93,0x89,0xff	  /*结束标志*/
};
uchar code jmszl[]={ /*寂寞沙洲冷*/
0x12,0x12,0x22,0x32,0x31,0x22,0x21,0x22,
0x21,0x31,0x51,0x52,0x31,0x52,0x61,0x15,0x14,
0x51,0x52,0x31,0x52,0x62,0x13,0x11,0x13,0x32,0x28,0x08,0x28,
0x31,0x32,0x31,0x32,0x11,0x21,0x51,0x52,0x51,0x52,
0x51,0x51,0x31,0x32,0x31,0x32,0x81,0x72,0x63,
0x62,0x71,0x81,0x72,0x61,0x61,0x52,0x31,0x21,0x32,0x51,0x54,
0x22,0x12,0x11,0x12,0x11,0x12,0x12,0x14,0x26,0x32,0x26,
0x32,0x61,0x51,0x51,0x31,0x31,0x21,0x31,0x51,0x61,0x51,0x31,0x51,
0x02,0x32,0x81,0x81,0x81,0x81,0x62,0x52,0x34,
0x31,0x81,0x81,0x81,0x61,0x91,0x82,
0x51,0x51,0x51,0x51,0x31,0x61,0x53,
0x21,0x11,0x21,0x11,0x22,0x11,0x21,0x26,
0x32,0x61,0x51,0x51,0x31,0x31,0x21,0x31,0x51,0x61,0x51,0x31,0x51,0x52,
0x31,0x31,0x81,0x81,0x81,0x61,0x91,0x81,0x61,0x31,0x56,
0x32,0x32,0x81,0x81,0x81,0x81,0x91,0x81,0x61,0x81,0x61,0x51,0x31,0x51,0x34,
0x21,0x31,0x51,0x31,0x21,0x11,0x61,0x21,0x16,0xff  /*结束标志*/
};
uchar code qizige[]={  /*七子之歌*/
0x54,0x32,0x52,0x32,0x54,0x62,0x52,0x32,0x62,0x54,
0x14,0x12,0x22,0x34,0x52,0x32,0x02,0x32,0x58,
0x52,0x52,0x62,0x52,0x32,0x54,0x52,0x62,0x52,0x82,0x62,0x58,
0x14,0x52,0x32,0x22,0x12,0x24,0x32,0x54,0x2,0x22,0x34,0x1f,0x18,
0x04,0x54,0xa4,0x92,0x81,0x62,0x52,0x54,0x62,0x64,0x52,0x62,0x81,0xa2,0x82,0x9c,
0x02,0x52,0xa4,0x92,0x81,0x62,0x52,0x54,0x62,0x64,0x52,0x64,0xa2,0x92,0x9f,
0xa4,0x92,0x81,0x62,0x52,0x54,0x84,0x62,0x52,0x32,0x22,0x14,
0x04,0x22,0x32,0x58,0x58,0x04,0x52,0x62,0x8f,
0xff /*结束标志*/
};
uchar code ganen[]={ /*感恩的心*/
0x12,0x14,0x22,0x32,0x54,0x32,0x84,0x72,0x62,0x54,
0x02,0x62,0x62,0x52,0x54,0x12,0x22,0x32,0x28,
0x12,0x14,0x22,0x32,0x54,0x32,0x84,0x92,0x82,0x54,
0x32,0x24,0x21,0x61,0x54,0x22,0x32,0x12,0x18,
0x22,0x24,0x12,0x24,0x11,0x21,0x34,0x32,0x21,0x31,0x34,
0x12,0x22,0x22,0x22,0x11,0x21,0x22,0x64,0x52,0x52,0x32,0x38,
0x31,0x52,0x51,0x52,0x31,0x51,0x58,0x31,0x82,0x81,0x82,0x31,0x61,0x68,
0x62,0x62,0x62,0x51,0x61,0x64,0x61,0x82,0x61,0x9c,
0x52,0xa4,0x92,0xa4,0x32,0x84,0x72,0x64,0x62,0x94,0x82,0x94,
0x61,0x81,0x92,0x91,0x91,0x92,0x81,0xa1,0xa2,0x92,0x94,
0x52,0xa4,0x92,0xa4,0x32,0x84,0x72,0x64,
0x52,0x62,0x81,0x81,0x82,0x92,0xa2,0x94,0x82,0x72,0x82,0x88,
0xff  /*结束标志*/
};
/*简谱音调对应的定时器初值*/
/*适合11.0592M的晶振*/
uchar code cuzhi[]={
					0xff,0xff,  /*占位*/
					0xFC,0x8E,  /*中央C调1~7*/
					0xFC,0xED,
					0xFD,0x43,
					0xFD,0x6A,
					0xFD,0xB3,
					0xFD,0xF3,
					0xFE,0x2D,
					0xFE,0x47,  /*高八度1~7*/
					0xFE,0x76,
					0xFE,0xA1,
					0xFE,0xC7,
					0xFE,0xD9,
					0xFE,0xF9,
					0xFF,0x16
					};
void delay1(uint z); /*	 延时1MS*/
void delay(uint z);  /*延时165ms,既16分音符*/
void song();
void beep(); /*蜂鸣器叫一声*/
void main()
{
	P0=0xbf;
//	KK=0;

	EA=1;
	EX0=1;
	IT0=1;
	EX1=1;
	IT1=1;
	TMOD=0x01;
	TH0=0;
	TL0=0;
	ET0=1;
	while(1)
	{
	    if(P1_7==1)
		{
			count2++;//歌曲递增
		if(count2==5)
			count2=0;
		}
		if(count2!=0)
		{
			song();
			delay1(1000);
		}
	
	}
}

void int0() interrupt 0 
{
	EA=0;
	delay1(1); 
	if(key1==0)
	{
		count2=0;/*暂停音乐*/
		TR0=0;
	}
	EA=1;
} 

void int1() interrupt 2 
{
	TR0 = 0;	
	delay1(1);  /*去抖*/
	if(key2==0)
	{
		i=0;/*从头开始唱*/
		count2++;
		TR0=~TR0;
		if(count2==5)
		count2=0;
	}
}

void timer0() interrupt 1/*用于产生各种音调*/
{
/*	if(count2==0)	
	{
		TH0 = tone_delay_table[keynum]/256;
		TL0 = tone_delay_table[keynum]%256;
		fm = ~fm;
	}	*/

	
	if(count2!=0) //放音乐
	{
		TH0=timeh;
		TL0=timel;
		fm=~fm;
	}
}

void song()
{
	uint temp;
	uchar jp;
	i=0;
	while(1)
	{

		
		if(count2==0)
		{
			break;
		}
		if(count2==1)  //选曲
		temp=jmszl[i];
		if(count2==2)
		temp=qnzl[i];
		if(count2==3)
		temp=qizige[i];
		if(count2==4)
		temp=ganen[i];
		if(temp==0xff)
		break;
		jp=temp/16;
		P2 = huayang[jp];
		P0=DSY_table[count2];
		if(jp!=0)
		{
			timeh=cuzhi[jp*2];
			timel=cuzhi[jp*2+1];
		}
		else
		{
			TR0=0;
			fm=1;
		}
		delay(temp%16);
		TR0=0;
	
		fm=1;
		delay1(10);
		TR0=1;
		i++;
	}
	TR0=0;
	fm=1;
}

设计报告

报告

系统组成框图

img

本设计采用STC89C516RD+作为主控芯片(仿真可替换为STC89C51,STC89C52,AT89C51,AT89C52D等51单片机),蜂鸣器作为输出设备产生音乐,通过MOD键能实现播放模式的控制,数码管(LED)能够实时的显示当前的歌曲号。其中P3.3外接按键,P0口用作数码管输出数据端口,P2口作LED输出数据端口P1.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叫降记音,表示在原来的基础上降低半音。例如高音DO的频率(1046Hz)刚好是中音DO的频率(523Hz)的一倍,中音DO的频率(523Hz)刚好是低音DO频率(266 Hz)的一倍;同样的,高音RE的频率(1175Hz)刚好是中音RE的频率(587Hz)的一倍,中音RE的频率(587Hz)刚好是低音RE频率(294 Hz)的一倍。

要产生音频脉冲,只要算出某一音频的周期(1/频率),然后将此周期除以2,即为半周期的时间。利用定时器计时这半个周期时间,每当计时到后就将输出脉冲的I/O反相,然后重复计时此半周期时间再对I/O反相,就可在I/O脚上得到此频率的脉冲。利用AT89C51的内部定时器使其工作在计数器模式MODE1下,改变计数值TH0及TL0。此外结束符和休止符可以分别用代码00H和FFH来表示,若查表结果为00H,则表示曲子终了;若查表结果为FFH,则产生相应的停顿效果。例如频率为523Hz,其周期T=1/523=1912us,因此只要令计数器计时956us/1us=956,在每次技术956次时将I/O反相,就可得到中音DO(523Hz)。

节拍的确定

若要构成音乐,光有音调是不够的,还需要节拍,让音乐具有旋律(固定的律动),而且可以调节各个音的快满度。“节拍”,即Beat,简单说就是打拍子,就像我们听音乐不自主的随之拍手或跺脚。若1拍实0.5s,则1/4 拍为0.125s。至于1拍多少s,并没有严格规定,就像人的心跳一样,大部分人的心跳是每分钟72下,有些人快一点,有些人慢一点,只要听的悦耳就好。音持续时间的长短即时值,一般用拍数表示。休止符表示暂停发音。

一首音乐是由许多不同的音符组成的,而每个音符对应着不同频率,这样就可以利用不同的频率的组合,加以与拍数对应的延时,构成音乐。了解音乐的一些基础知识,我们可知产生不同频率的音频脉冲即能产生音乐。对于单片机来说,产生不同频率的脉冲是非常方便的,利用单片机的定时/计数器来产生这样的方波频率信号。因此,需要弄清楚音乐中的音符和对应的频率,以及单片机定时计数的关系。

音符编码

do re mi fa so la si分别编码为1~7,重音do编为8,重音re编为9,停顿编为0。播放长度以十六分音符为单位(在本程序中为165ms),一拍即四分音符等于4个十六分音符,编为4,其它的播放时间以此类推。音调作为编码的高4位,而播放时间作为低4位,如此音调和节拍就构成了一个编码。以0xff作为曲谱的结束标志。比如,音调do,发音长度为两拍,即二分音符,将其编码为0x18。

歌曲播放的设计。先将歌曲的简谱进行编码,储存在一个数据类型为unsigned char 的数组中。程序从数组中取出一个数,然后分离出高4位得到音调,接着找出相应的值赋给定时器0,使之定时操作蜂鸣器,得出相应的音调;接着分离出该数的低4位,得到延时时间,接着调用软件延时。

主程序流程图

img

实物图

img

资料清单(提供资料清单所有文件):

仿真+代码+原理图PCB+设计报告+讲解视频
img

资料下载链接:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/183096.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【LeetCode刷题】--67.二进制求和

67.二进制求和 方法&#xff1a;模拟计算 class Solution {public String addBinary(String a, String b) {StringBuilder ans new StringBuilder();int carry 0;for(int ia.length()-1,jb.length()-1;i>0||j>0;i--,j--){int sum carry;sum i >0 ? a.charAt(i) …

web:[WUSTCTF2020]朴实无华

题目 点开页面显示如下 页面显示了一行报错&#xff1a;Cannot modify header information - headers already sent by (output started at /var/www/html/index.php:3) in /var/www/html/index.php on line 4 意思为不能修改报头信息-报头已经发送(输出开始于/var/www/html/i…

深度学习之基于Pytorch照片图像转漫画风格网络系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 以下是一个基本的设计介绍&#xff1a; 数据准备&#xff1a;收集足够的真实照片和漫画图像&#xff0c;用于训练模…

富士康转移产线和中国手机海外设厂,中国手机出口减少超5亿部

富士康和苹果转移生产线对中国手机制造造成了巨大的影响&#xff0c;除此之外&#xff0c;中国手机企业纷纷在海外设厂也在减少中国手机的出口&#xff0c;2022年中国的手机出口较高峰期减少了5.2亿部。 手机是中国的大宗出口商品&#xff0c;不过公开的数据显示2022年中国的手…

ElementUI table+dialog实现一个简单的可编辑的表格

table组件如何实现可编辑呢&#xff1f; 我的需求是把table组件那样的表格&#xff0c;实现它点击可以弹出一个框&#xff0c;然后在这个框里面输入你的东西&#xff0c;然后将他回显回去&#xff0c;当然&#xff0c;输入的有可能是时间啥的。 为什么要弹出弹层不在框上直接…

缓存雪崩、击穿、穿透及解决方案_保证缓存和数据库一致性

文章目录 缓存雪崩、击穿、穿透1.缓存雪崩造成缓存雪崩解决缓存雪崩 2. 缓存击穿造成缓存击穿解决缓存击穿 3.缓存穿透造成缓存穿透解决缓存穿透 更新数据时&#xff0c;如何保证数据库和缓存的一致性&#xff1f;1. 先更新数据库&#xff1f;先更新缓存&#xff1f;解决方案 2…

C语言函数练习(超基础超详细)

ps:题目来源于pta平台。 1. int sum(int m, int n) {int sum0;for(int im; i<n; i){sumi;}return sum; } 2. int max(int a, int b) {if(a>b)return a;else return b; } 3. double dist( double x1, double y1, double x2, double y2 ) {return sqrt((x1-x2)*(x1…

【Flink】Standalone运行模式

独立模式是独立运行的&#xff0c;不依赖任何外部的资源管理平台&#xff1b;当然独立也是有代价的&#xff1a;如果资源不足&#xff0c;或者出现故障&#xff0c;没有自动扩展或重分配资源的保证&#xff0c;必须手动处理。所以独立模式一般只用在开发测试或作业非常少的场景…

Docker+ Jenkins+Maven+git自动化部署

环境&#xff1a;Centos7 JDK1.8 Maven3.3.9 Git 2.40 Docker 20.10.17 准备工作&#xff1a; 安装Docker Centos7默认的yum安装的docker是1.13&#xff0c;版本太低&#xff0c;很多镜像都要Docker版本要求&#xff0c;升级Docker版本。 卸载已安装Docker: yum …

NeurIPS 2023 | RGIB:对抗双边图噪声的鲁棒图学习

▐ 摘要 链接预测[1,2]是图学习的一种基础任务&#xff0c;用于判断图中的两个节点是否可能相连&#xff0c;被广泛应用于药物发现、知识图谱补全和在线问答等实际场景。尽管图神经网络&#xff08;Graph Neural Network&#xff0c;GNN&#xff09;在该问题的性能上取得了显著…

我做了一个世界杯数据可视化网站······

感兴趣的小伙伴可以进去看看&#xff1a;主页https://messimeimei.github.io/world-cup-visualization.github.io/&#xff0c;可能会比较卡 经过2个月的工作&#xff0c;我完成了80%的工作量&#xff0c;并成功将静态网站进行了部署。并对页面进行了更新。不过当前虽然完成了…

ESP32之避障

ESP32之避障 图片 程序 int Led27;//定义LED 接口 int buttonpin4; //定义光遮断传感器接口 int val;//定义数字变量val void setup() { pinMode(Led,OUTPUT);//定义LED 为输出接口 pinMode(buttonpin,INPUT);//定义避障传感器为输出接口 } void loop() {Serial.begin(9600);…

性能相关的闪存特性

一、多Plane操作 上章提到若干个Plane组成Die或者叫LUN,即一个Die上有多个Plane 每次进行写操作时&#xff0c;控制器先将数据写入页缓存中&#xff0c;等同一个Die上另一个Plane也写数据的时候&#xff0c;再同时写入&#xff0c;原来单独操作一个Plane的时间变成了可以同时做…

UDP客户端使用connect与UDP服务器使用send函数和recv函数收发数据

服务器代码编译运行 服务器udpconnectToServer.c的代码如下&#xff1a; #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<arpa/inet.h> #include<sys/socket.h> #include<errno.h> #inclu…

【Spring进阶系列丨第四篇】学习Spring中的Bean管理(基于xml配置)

前言 在之前的学习中我们知道&#xff0c;容器是一个空间的概念&#xff0c;一般理解为可盛放物体的地方。在Spring容器通常理解为BeanFactory或者ApplicationContext。我们知道spring的IOC容器能够帮我们创建对象&#xff0c;对象交给spring管理之后我们就不用手动去new对象。…

操作系统发展过程--单道批处理系统、多道批处理系统、分时系统、实时系统

一、单道批处理系统 计算机早期&#xff0c;为了能提高利用率&#xff0c;需要尽量保持系统的连续运行&#xff0c;即在处理完一个作业之后&#xff0c;紧接着处理下一个作业&#xff0c;以减少机器的空闲等待时间 1.单道批处理系统的处理过程 为了实现对作业的连续处理&…

EPT-Net:用于3D医学图像分割的边缘感知转换器

EPT-Net: Edge Perception Transformer for 3D Medical Image Segmentation EPT-Net&#xff1a;用于3D医学图像分割的边缘感知转换器背景贡献实验方法Dual Positional Transformer&#xff08;双位置Transformer&#xff09;Learnable Patch EmbeddingVoxel Spacial Positiona…

OpenCV实现图像噪声、去噪基本方法

一、噪声分类 1、高斯噪声 指服从高斯分布&#xff08;正态分布&#xff09;的一类噪声&#xff0c;其产生的主要原因是由于相机在拍摄时视场较暗且亮度不均匀造成的&#xff0c;同时相机长时间工作使得温度过高也会引起高斯噪声&#xff0c;另外电路元器件白身噪声和互相影响…

土地利用数据技术服务

一、背景介绍 土地是人类赖以生存与发展的重要资源和物质保障&#xff0c;在“人口&#xff0d;资源&#xff0d;环境&#xff0d;发展&#xff08;PRED&#xff09;”复合系统 中&#xff0c;土地资源处于基础地位。随着现代社会人口的不断增长以及工业化、城市化进程的加速&a…

nvm切换版本之后npm用不了

原因是 nvm只给你安了对应的node没给你安装对应的node版本的npm 解决办法如下 1找到你安装的node版本号 然后去官网下载对应的版本包 这个网址就是node官网的版本列表 Index of /download/release/ 2下载后解压 把根目录这俩复制到自己的nvm安装目录下 还有那个node_modul…