基于51单片机的简易电子琴系统

2024-02-29 02:59

本文主要是介绍基于51单片机的简易电子琴系统,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

具体实现功能

设计介绍

51单片机简介

设计思路

设计内容

原理图(AD19)

程序(Keil5)

仿真实现(protues8.7)

全部资料


具体实现功能

系统由STC89C52单片机+数码管+电源电路+音符按键+乐曲切换按键+蜂鸣器构成。

具体功能:

1、数码管显示所按的音符

2、从左到右的按键实现的音符分别是:do、re、mi、fa、so、la、si、do(高音);

3、三个按键可实现三首歌的切换:A是《挥着翅膀的女孩》,B是《同一首歌》,C是《两只蝴蝶》。

设计介绍

51单片机简介

51单片是一种低功耗、高性能CMOS-8位微控制器,具有8K可编程Flash存储器,使得其为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。

51系列单片机具有以下标准功能:

8k字节Flash,512字节RAM,

32位I/O口线,看门狗定时器,

内置4KB EEPROM,

MAX810复位电路,

三个16位定时器/计数器,

一个6向量2级中断结构,

全双工串行口。

另外, 51系列在空闲模式下,CPU停止工作,允许RAM、定时器/计数器、串口、中断继续工作。掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机停止工作,直到下一个中断或硬件复位为止。本设计所使用的芯片可兼容以下所有的51系列单片机(包括AT系列和STC系列)。

设计思路

文献研究法:搜集整理相关研究资料,阅读文献,为研究做准备;

调查研究法:通过调查、分析、具体实验等方法,发现相关存在问题和解决办法;

比较分析法:比较不同设计的具体原理,以及同一类传感器性能的区别,分析系统的研究现状与发展前景;

软硬件设计法:通过软硬件设计实现硬件,最后测试各项功能是否满足要求。

设计内容

原理图(AD19)

本系统原理图设计采用Altium Designer19,具体如图。

程序(Keil5)

本设计利用KEIL5软件实现程序设计,主函数如下:

void main() 	//主函数入口
{Time0_Init();	//定时器T0初始化Speak=1;		//蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)while(1)	//无限循环	{switch(P1)		//switch语句判断检测 P1按键状态{  case 0xfe:	//P1=0xfe    "do"按键按下 			delay_ms(10);	//延时去抖	if(P1==0xfe)	//再判断"do"按键是否按下{				SMG=table[1];	//数码管显示"1"	i=0;			//i置0TR0=0;  		//关闭定时器T0sth=Music_Code[2*i];	//定时器高八位赋值 "do"stl=Music_Code[2*i+1];	//定时器低八位赋值 "do"TR0=1;			//启动定时器T0for(j=0;j<=1000;j++)	//软件延时,在一定时间里检测{							 				delay_ms(10);		//延时一下if(P1==0xfe) continue;	//"do"按键按下,跳出(继续发音)else break;			//松开了,则返回}SMG=0xff;	//关闭数码管显示Speak=1;	//蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)TR0=0;		//关闭定时器T0for(;;)	{while(P1==0xfe);	//等待按键松开									 				delay_ms(10);		//延时去抖if(P1==0xfe) continue;	else break;			//确定松开,退出}TR0=0;		//关闭定时器T0}break;			//返回case 0xfd:	//P1=0xfd	"re"按键按下 		delay_ms(10);	//延时去抖if(P1==0xfd)	//再判断"re"按键是否按下{SMG=table[2];	//数码管显示"2"i=1;			//i置1TR0=0;  		//关闭定时器T0sth=Music_Code[2*i];	//定时器高八位赋值 "re"stl=Music_Code[2*i+1];	//定时器低八位赋值 "re"TR0=1;			//启动定时器T0		for(j=0;j<=1000;j++)	//软件延时,在一定时间里检测{									 				delay_ms(10);	//延时一下	if(P1==0xfd) continue;	//"re"按键按下,跳出(继续发音)	else break;		//松开了,则返回}SMG=0xff;	//关闭数码管显示Speak=1;	//蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)TR0=0;		//关闭定时器T0for(;;){while(P1==0xfd);	//等待按键松开delay_ms(10);		//延时去抖if(P1==0xfd) continue;	else break;			//确定松开,退出}}TR0=0;			//关闭定时器T0break;			//返回case 0xef:	//P1=0xef	"mi"按键按下 delay_ms(10);	//延时去抖			if(P1==0xef)	//再判断"mi"按键是否按下{SMG=table[3];	//数码管显示"3"i=2;			//i置2	TR0=0;  		//关闭定时器T0	sth=Music_Code[2*i];	//定时器高八位赋值 "mi"	stl=Music_Code[2*i+1];	//定时器低八位赋值 "mi"TR0=1;			//启动定时器T0	for(j=0;j<=1000;j++)	//软件延时,在一定时间里检测{							 				delay_ms(10);	//延时一下if(P1==0xef) continue;	//"mi"按键按下,跳出(继续发音)else break;		//松开了,则返回}SMG=0xff;	//关闭数码管显示Speak=1;	//蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)TR0=0;		//关闭定时器T0for(;;){while(P1==0xef);	//等待按键松开	delay_ms(10);		//延时去抖if(P1==0xef) continue;else break;			//确定松开,退出}}TR0=0;			//关闭定时器T0break;			//返回		default: 	break;			//没有P1没有按键按下,返回}switch(P3)		//switch语句判断检测 P3按键状态{case 0xfe:	//P3=0xfe	"fa"按键按下 delay_ms(10);	//延时去抖	if(P3==0xfe)	//再判断"fa"按键是否按下{SMG=table[4];	//数码管显示"4"i=3;			//i置3TR0=0;  		//关闭定时器T0	sth=Music_Code[2*i];	//定时器高八位赋值 "fa"	stl=Music_Code[2*i+1];	//定时器低八位赋值 "fa"TR0=1;			//启动定时器T0	for(j=0;j<=1000;j++)	//软件延时,在一定时间里检测	{							 				delay_ms(10);	//延时一下if(P3==0xfe) continue;	//"fa"按键按下,跳出(继续发音)else break;		//松开了,则返回}SMG=0xff;	//关闭数码管显示Speak=1;	//蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)TR0=0;		//关闭定时器T0for(;;){while(P3==0xfe);	//等待按键松开delay_ms(10);		//延时去抖if(P3==0xfe) continue;else break;			//确定松开,退出}}TR0=0;		//关闭定时器T0	break;		//返回case 0xf7: 	//P3=0xf7	"so"按键按下 delay_ms(10);	//延时去抖			if(P3==0xf7)	//再判断"so"按键是否按下{SMG=table[5];	//数码管显示"5"	i=4;			//i置4			TR0=0;  		//关闭定时器T0		sth=Music_Code[2*i];	//定时器高八位赋值 "so"stl=Music_Code[2*i+1];	//定时器低八位赋值 "so"TR0=1;			//启动定时器T0		for(j=0;j<=1000;j++)	//软件延时,在一定时间里检测	{									 				delay_ms(10);		//延时一下if(P3==0xf7) continue;	//"so"按键按下,跳出(继续发音)else break;			//松开了,则返回}SMG=0xff;	//关闭数码管显示Speak=1;	//蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)TR0=0;		//关闭定时器T0for(;;){while(P3==0xf7);	//等待按键松开		delay_ms(10);		//延时去抖if(P3==0xf7) continue;else break;			//确定松开,退出}}TR0=0;		//关闭定时器T0break;		//返回case 0xef: 	//P3=0xef	"la"按键按下delay_ms(10);	//延时去抖if(P3==0xef)	//再判断"la"按键是否按下{SMG=table[6];	//数码管显示"6"i=5;			//i置5TR0=0;  		//关闭定时器T0sth=Music_Code[2*i];	//定时器高八位赋值 "la"stl=Music_Code[2*i+1];	//定时器低八位赋值 "la"TR0=1;			//启动定时器T0		for(j=0;j<=1000;j++)	//软件延时,在一定时间里检测	{							 				delay_ms(10);		//延时一下if(P3==0xef) continue;	//"la"按键按下,跳出(继续发音)else break;			//松开了,则返回}SMG=0xff;	//关闭数码管显示Speak=1;	//蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)TR0=0;		//关闭定时器T0for(;;){while(P3==0xef);	//等待按键松开	delay_ms(10);		//延时去抖if(P3==0xef) continue;else break;			//确定松开,退出}	}TR0=0;		//关闭定时器T0	break;		//返回case 0xdf: 	//P3=0xdf	"si"按键按下delay_ms(10);	//延时去抖if(P3==0xdf)	//再判断"si"按键是否按下{SMG=table[7];	//数码管显示"7"	i=6;			//i置6TR0=0;  		//关闭定时器T0sth=Music_Code[2*i];	//定时器高八位赋值 "si"stl=Music_Code[2*i+1];	//定时器低八位赋值 "si"TR0=1;			//启动定时器T0	for(j=0;j<=1000;j++)	//软件延时,在一定时间里检测	{							 				delay_ms(10);		//延时一下if(P3==0xdf) continue;	//"si"按键按下,跳出(继续发音)else break;			//松开了,则返回}SMG=0xff;	//关闭数码管显示Speak=1;	//蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)TR0=0;		//关闭定时器T0for(;;){while(P3==0xdf);	//等待按键松开delay_ms(10);		//延时去抖if(P3==0xdf) continue;else break;			//确定松开,退出}}TR0=0;		//关闭定时器T0break;		//返回case 0xbf:	//P3=0xbf	"高音do"按键按下delay_ms(10);	//延时去抖	if(P3==0xbf)	//再判断"高音do"按键是否按下{SMG=table[1]&0x7f;  //数码管显示"1"带小数点(1.)i=7;		//i置7		TR0=0;  	//关闭定时器T0sth=Music_Code[2*i];	//定时器高八位赋值 "高音do"stl=Music_Code[2*i+1];	//定时器低八位赋值 "高音do"TR0=1;		//启动定时器T0			for(j=0;j<=1000;j++)	//软件延时,在一定时间里检测		{							 				delay_ms(10);		//延时一下if(P3==0xbf) continue;	//"高音do"按键按下,跳出(继续发音)else break;			//松开了,则返回}SMG=0xff;	//关闭数码管显示Speak=1;	//蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)TR0=0;		//关闭定时器T0for(;;){while(P3==0xbf);	//等待按键松开delay_ms(10);		//延时去抖if(P3==0xbf) continue;else break;			//确定松开,退出}}TR0=0;		//关闭定时器T0break;		//返回default: 	break;		//没有P3没有按键按下,返回}if(Key1==0)			//按键1按下(播放 "挥着翅膀的女孩"){delay_ms(10);	//延时去抖if(Key1==0)		//再判断按键1是否按下{SMG=table[10];	//数码管显示"A"for(i=0;Music_hzcb[i]!=0xff;i++)	//for循环语句			{				//Music_hzcb[]=0ff时,跳出for循环语句,停止播放音乐sth=yinfu1[(Music_hzcb[i]%100)/10-1][((Music_hzcb[i]%10)-1)*2];	 //定时器高八位赋值stl=yinfu1[(Music_hzcb[i]%100)/10-1][((Music_hzcb[i]%10)-1)*2+1];//定时器低八位赋值i++;		//i加1TR0=1;		//启动定时器T0delay_ms(4*500/length[Music_hzcb[i]%10]);	//确定几分音符(节拍)		TR0=0;		//节拍结束,关闭定时器T0				 }SMG=0xff;	//关闭数码管显示Speak=1;	//蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)for(;;){while(Key1==0);		//等待按键松开	delay_ms(10);		//延时去抖if(Key1==0) continue;else break;			//确定松开,退出	}}}if(Key2==0)			//按键2按下(播放 "同一首歌")	{delay_ms(10);	//延时去抖if(Key2==0)		//再判断按键2是否按下{SMG=table[11];	//数码管显示"B"for(i=0;Music_tyshg[i]!=0xff;i++)	//for循环语句{				//Music_tyshg[]=0ff时,跳出for循环语句,停止播放音乐sth=yinfu1[(Music_tyshg[i]%100)/10-1][((Music_tyshg[i]%10)-1)*2];  //定时器高八位赋值stl=yinfu1[(Music_tyshg[i]%100)/10-1][((Music_tyshg[i]%10)-1)*2+1];//定时器低八位赋值i++;		//i加1TR0=1;		//启动定时器T0delay_ms(4*500/length[Music_tyshg[i]%10]);	//确定几分音符(节拍)TR0=0;		//节拍结束,关闭定时器T0						 }SMG=0xff;	//关闭数码管显示Speak=1;	//蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)for(;;)	{while(Key2==0);		//等待按键松开	delay_ms(10);		//延时去抖if(Key2==0) continue;else break;			//确定松开,退出}}}if(Key3==0)			//按键3按下(播放 "两只蝴蝶"){		delay_ms(10);	//延时去抖	if(Key3==0)		//再判断按键3是否按下{SMG=table[12];	//数码管显示"C"		for(i=0;Music_lzhhd[i]!=0xff;i++)	//for循环语句{				//Music_lzhhd[]=0ff时,跳出for循环语句,停止播放音乐sth=yinfu1[(Music_lzhhd[i]%100)/10-1][((Music_lzhhd[i]%10)-1)*2];  //定时器高八位赋值stl=yinfu1[(Music_lzhhd[i]%100)/10-1][((Music_lzhhd[i]%10)-1)*2+1];//定时器低八位赋值i++;		//i加1	TR0=1;		//启动定时器T0delay_ms(4*500/length[Music_lzhhd[i]%10]);	//确定几分音符(节拍)TR0=0;		//节拍结束,关闭定时器T0					 }SMG=0xff;	//关闭数码管显示Speak=1;	//蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)for(;;){while(Key3==0);		//等待按键松开delay_ms(10);		//延时去抖if(Key3==0) continue;else break;			//确定松开,退出}}}}
}

代码运行截图:

仿真实现(protues8.7)

本设计利用protues8.7软件实现仿真设计。

全部资料

全部资料包括程序(KEIL5)、AD原理图(AD19)、protues仿真(protues8.7)、参考论文(仅供参考)、开题报告、任务书、实物图、讲解视频、软硬件设计框图等,具体如图,全网最全!!

资料获取:
https://docs.qq.com/doc/DSXZnZHl4cVhkTk5p

这篇关于基于51单片机的简易电子琴系统的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/757383

相关文章

在不同系统间迁移Python程序的方法与教程

《在不同系统间迁移Python程序的方法与教程》本文介绍了几种将Windows上编写的Python程序迁移到Linux服务器上的方法,包括使用虚拟环境和依赖冻结、容器化技术(如Docker)、使用An... 目录使用虚拟环境和依赖冻结1. 创建虚拟环境2. 冻结依赖使用容器化技术(如 docker)1. 创

CentOS系统Maven安装教程分享

《CentOS系统Maven安装教程分享》本文介绍了如何在CentOS系统中安装Maven,并提供了一个简单的实际应用案例,安装Maven需要先安装Java和设置环境变量,Maven可以自动管理项目的... 目录准备工作下载并安装Maven常见问题及解决方法实际应用案例总结Maven是一个流行的项目管理工具

python实现简易SSL的项目实践

《python实现简易SSL的项目实践》本文主要介绍了python实现简易SSL的项目实践,包括CA.py、server.py和client.py三个模块,文中通过示例代码介绍的非常详细,对大家的学习... 目录运行环境运行前准备程序实现与流程说明运行截图代码CA.pyclient.pyserver.py参

使用PyQt实现简易文本编辑器

《使用PyQt实现简易文本编辑器》这篇文章主要为大家详细介绍了如何使用PyQt5框架构建一个简单的文本编辑器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录分析主窗口类 (MyWindow)菜单操作语法高亮 (SyntaxHighlighter)运行程序主要组件代码图示分析实现

5分钟获取deepseek api并搭建简易问答应用

《5分钟获取deepseekapi并搭建简易问答应用》本文主要介绍了5分钟获取deepseekapi并搭建简易问答应用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需... 目录1、获取api2、获取base_url和chat_model3、配置模型参数方法一:终端中临时将加

C#实现系统信息监控与获取功能

《C#实现系统信息监控与获取功能》在C#开发的众多应用场景中,获取系统信息以及监控用户操作有着广泛的用途,比如在系统性能优化工具中,需要实时读取CPU、GPU资源信息,本文将详细介绍如何使用C#来实现... 目录前言一、C# 监控键盘1. 原理与实现思路2. 代码实现二、读取 CPU、GPU 资源信息1.

在C#中获取端口号与系统信息的高效实践

《在C#中获取端口号与系统信息的高效实践》在现代软件开发中,尤其是系统管理、运维、监控和性能优化等场景中,了解计算机硬件和网络的状态至关重要,C#作为一种广泛应用的编程语言,提供了丰富的API来帮助开... 目录引言1. 获取端口号信息1.1 获取活动的 TCP 和 UDP 连接说明:应用场景:2. 获取硬

JAVA系统中Spring Boot应用程序的配置文件application.yml使用详解

《JAVA系统中SpringBoot应用程序的配置文件application.yml使用详解》:本文主要介绍JAVA系统中SpringBoot应用程序的配置文件application.yml的... 目录文件路径文件内容解释1. Server 配置2. Spring 配置3. Logging 配置4. Ma

2.1/5.1和7.1声道系统有什么区别? 音频声道的专业知识科普

《2.1/5.1和7.1声道系统有什么区别?音频声道的专业知识科普》当设置环绕声系统时,会遇到2.1、5.1、7.1、7.1.2、9.1等数字,当一遍又一遍地看到它们时,可能想知道它们是什... 想要把智能电视自带的音响升级成专业级的家庭影院系统吗?那么你将面临一个重要的选择——使用 2.1、5.1 还是

高效管理你的Linux系统: Debian操作系统常用命令指南

《高效管理你的Linux系统:Debian操作系统常用命令指南》在Debian操作系统中,了解和掌握常用命令对于提高工作效率和系统管理至关重要,本文将详细介绍Debian的常用命令,帮助读者更好地使... Debian是一个流行的linux发行版,它以其稳定性、强大的软件包管理和丰富的社区资源而闻名。在使用