课程设计题十:简易电子琴设计

要求:

1、设置三种音阶:低音、中音、高音控制按键;

2、设计1、2、3、4、5、6、7音(哆来咪法搜拉稀);

3、能弹奏一首简单的儿歌。

获取该程序的方式:

1、CSDN下载:

https://download.csdn.net/download/qq_38351824/11391320
2、关注微信公众号下载:

     ① 关注微信公众号:Tech云  

     ②

3、可以关注点赞并在下方评论,我给你邮箱发过去。


一、Protues仿真图:

课程设计题十:简易电子琴设计_第1张图片

课程设计题十:简易电子琴设计_第2张图片

课程设计题十:简易电子琴设计_第3张图片

课程设计题十:简易电子琴设计_第4张图片

二、程序源码:

因为注释非常的全,这里就不再进行讲解了。

/*******************************************************************************
================================================================================
【平    台】STC89C51_sumjess平台
【编    写】sumjess
【E-mail  】[email protected]
【软件版本】V2.0
【最后更新】2019年06月10日
【相关信息参考下列地址】
【网    站】
           https://blog.csdn.net/qq_38351824
           http://www.51hei.com/bbs/mcu-2-1.html
---------------------------------------------------------------------------------
【dev.env.】MDK4.02及以上版本
【Target  】STC89C51
第一次修订:2019/05/09
第二次修订:2019/05/21
第三次修订:2019/06/10
【problem 】
    (1)库内补充的不全面;
    (2)库内解释部分不全面;
    (3)库内还存在一定的bug;
【direction】
      下一步的目标就是把库继续集成!
【explain 】
      为了方便使用,我也自己写了很多的库,和优化了算法和表示方式!
【warning】
      目前程序中暂无错误 !   
---------------------------------------------------------------------------------
没有完美的代码,只有不断的奉献,大家一起努力;
赠人玫瑰手留余香,欢迎大家反馈bug!
================================================================================
********************************************************************************/	

#include
#include

#define uchar unsigned char  //无符号字符型 宏定义	变量范围0~255
#define uint  unsigned int	 //无符号整型   宏定义  变量范围0~65535

sbit SDA1=P0^2;//串行数据输入,对应595的14脚SER
sbit SCL1=P0^1;//移位寄存器时钟输入,对应595的11脚SCK
sbit SCL2=P0^0;//存储寄存器时钟输入,对应595的12脚RCK
sbit W1=P0^3;
sbit W2=P0^4;
sbit k1=P1^0;  //哆1 啦2 咪3 发4 嗦5 啦6 西7 哆
sbit k2=P1^1;  //哆1 啦2 咪3 发4 嗦5 啦6 西7 哆
sbit k3=P1^2;  //哆1 啦2 咪3 发4 嗦5 啦6 西7 哆
sbit k4=P1^3;  //哆1 啦2 咪3 发4 嗦5 啦6 西7 哆
sbit k5=P1^4;  //哆1 啦2 咪3 发4 嗦5 啦6 西7 哆
sbit k6=P1^5;  //哆1 啦2 咪3 发4 嗦5 啦6 西7 哆
sbit k7=P1^6;  //哆1 啦2 咪3 发4 嗦5 啦6 西7 哆
sbit D1=P2^6;  //播放音乐模式
sbit D2=P2^7;  //弹奏模式 
sbit k8=P3^2;  //功能切换键
sbit k9=P3^3;  //低音
sbit k10=P3^4; //中音
sbit k11=P3^5; //高音
sbit beep=P2^2;//蜂鸣器接口

uchar code table1[]={   //共阴极数码管
						0x3F,/*0*/
						0x06,/*1*/
						0x5B,/*2*/
						0x4F,/*3*/
						0x66,/*4*/
						0x6D,/*5*/
						0x7D,/*6*/
						0x07,/*7*/
						0x7F,/*8*/
						0x6F,/*9*/
						0x37,/*N*///中音	
						0x38,/*L*///低音
						0x76,/*H*///高音
						0x79 /*E*/
					};
/格式为: 频率常数, 节拍常数, 频率常数, 节拍常数///
uchar code table2[]={	//音阶频率表 低八位	 
						0xFC,0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,//中音
						0xF9,0xF9,0xFA,0xFA,0xFB,0xFB,0xFC,//低音的高8位
						0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,
                	};
uchar code table3[]={		
						0x8E,0xED,0x44,0x6B,0xB4,0xF4,0x2D,//中音
						0x21,0xDB,0x87,0xD7,0x68,0xE8,0x5B,//低音的低8位
						0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16,
					};
uchar code table4[]={
						1,2,3,1,      
						1,2,3,1,      
						3,4,5,    
						3,4,5,     
						5,6,5,4,3,1,    
						5,6,5,4,3,1,   
						1,12/*低音5*/,1,     
						1,12,1
					}; 
uchar code table5[]={	//演奏歌曲延时表
						4,4,4,4,   
						4,4,4,4,     
						4,4,8,    
						4,4,8,     
						2,1,2,1,4,4,    
						2,1,2,1,4,4,   
						4,4,6,      
						4,4,6
					};

uchar i;
uchar key,aa=0;
uchar bb,cc;
bit flag=0;

//延时子函数
void delay(uint z)
{
	uint x,y;
	for(x=z;x>0;x--)
		for(y=340;y>0;y--);		
}

void in(uchar Data)
{
	uchar i;
	for(i=0;i<8;i++)   //循环8次,刚好移完8位
	{
      	Data<<=1;
	  	SCL1=CY;
	  	SDA1=1;        //先将移位寄存器控制引脚置为低    
      	_nop_();
	  	_nop_();
      	SDA1=0;
	}
}
void out()
{
	SCL2=0;   //先将存储寄存器引脚置为低
	_nop_(); 
	SCL2=1;    //再置为高,产生移位时钟上升沿,上升沿时移位寄存器的数据进入数据存储寄存器,更新显示数据。
	_nop_(); 
	SCL2=0;
}
//初始化子函数
void init()
{
	beep=0;	   //蜂鸣器关闭
	D1=1;	   //开始演奏音乐
	D2=0;	   //关闭弹奏功能
	EA=1;      //开总中断
	TCON=0x01; //外部中断0设置为边沿触发
/*	 以下是D7~D0 ,0x01=0000 0001  所以该函数相当于 IT0=1
TF1:定时器T1溢出标志位。当定时器T1溢出时,由硬件自动使TF1置1,并向CPU申请中断。CPU响应中断后,自动对TF1清零。TF1也可以用软件清零。 
TR1:定时器T 1运行控制位。可由软件置1(或清零)来启动(或关闭)定时器T1,使定时器T1开始计数。用指令SETB TR1(或CLR TR1)使TR1置1(或清零)。 
TF0:定时器T0溢出标志位。其功能与TF1相同。 
TR0:定时器T0运行控制位。其功能与TR1相同。 
IE1:外部中断1请求标志位。 
IT1:外部中断1触发方式控制位。 
IE0:外部中断0请求标志位。 
IT0:外部中断0触发方式控制位。
*/ 
	EX0=1;     //开外部中断0
	ET0=1;	   //定时器0的中断打开
	ET1=1;	   //定时器1的中断打开
	TMOD=0x11; //定时器0,1工作在定时状态,均为方式1
}
//数码管显示子函数
void display1()
{
	in(table1[aa]);  //再传段码
	out();
	W1=0;;
	delay(1);             //延迟时间2ms以内
	W1=1;
	in(table1[cc+1]);  //再传段码
	out();
	W2=0;
	delay(1);             //延迟时间2ms以内
	W2=1; 
}
//高低音选择子函数
void yinjie()
{
	if(k10==0)
	{	
		delay(5);
		if(k10==0)
		{   
			aa=10;
			bb=0;//返回10为seg[10]显示C
		}
	}
	if(k9==0)
	{	
		delay(5);
		if(k9==0)
		{	
			aa=11;
			bb=1;//返回11为seg[11]显示L
		}
	}
	if(k11==0)
	{	
		delay(5);
		if(k11==0)
		{	
			aa=12;
			bb=2;//返回12为seg[12]显示H
		}
	}
	if(aa==0)
	{
		aa=13;
	}
}
//播放音乐子函数
void display_music()
{	
	TH0=table2[table4[i]-1];	//取频率常数 和 节拍常数  
	TL0=table3[table4[i]-1];
	while(flag==0)
	{	
		if(i<32)
		{
			TR0=1;
			delay(57*table5[i]);
			i++;
		 }
		if(i==32) i=0;
	}	
}
//演奏模式子函数
void display_play()
{
	TR0=0;
	TR1=0;
	yinjie();
	in(table1[aa]);  //再传段码
	out();
	W1=0;;
	delay(1);             //延迟时间2ms以内
	W1=1;
	if(aa!=13&&flag==1)
	{	
		if(k1==0)
		{	
			TH1=table2[7*bb+cc];	   //取频率常数 和 节拍常数  
			TL1=table3[7*bb+cc];
			TR1=1;	
			while(k1==0)
			{	
				cc=0;
				display1();
			}
		}
		if(k2==0)
		{	
			TH1=table2[7*bb+cc];	  //取频率常数 和 节拍常数  
			TL1=table3[7*bb+cc];
			TR1=1;
			while(k2==0)
			{	
				cc=1;
				display1();
			}
		}	
		if(k3==0)
		{		
			TH1=table2[7*bb+cc];	 //取频率常数 和 节拍常数  
			TL1=table3[7*bb+cc];
			TR1=1;
			while(k3==0)
			{	
				cc=2;
				display1();
			}
		}
		if(k4==0)
		{							  //取频率常数 和 节拍常数  
			TH1=table2[7*bb+cc];
			TL1=table3[7*bb+cc];
			TR1=1;
			while(k4==0)
			{	
				cc=3;
				display1();		
			}
		}
		if(k5==0)
		{	
			TH1=table2[7*bb+cc];	//取频率常数 和 节拍常数  
			TL1=table3[7*bb+cc];
			TR1=1;
			while(k5==0)
			{
				cc=4;
				display1();
			}
		}
		if(k6==0)
		{	
			TH1=table2[7*bb+cc];	 //取频率常数 和 节拍常数  
			TL1=table3[7*bb+cc];
			TR1=1;
			while(k6==0)
			{
				cc=5;
				display1();							
			}
		}
		if(k7==0)
		{		
			TH1=table2[7*bb+cc];	  //取频率常数 和 节拍常数  
			TL1=table3[7*bb+cc];
			TR1=1;	
			while(k7==0)
			{
				cc=6;
				display1();	
			}
		}		
	}
}
//主函数
void main()
{
	init();	  //初始化子函数
	while(1)
	{	
		if(flag==0) display_music();	//演奏音乐
		else display_play();			//弹奏音乐
	 }
}
//外部0中断子函数
void wb0() interrupt 0 
{
	if(k8==0)
	{
		delay(5);
		while(k8==0);
		flag=~flag;
		D1=~D1;
		D2=~D2;
	}		
}
//定时器0中断子函数
void t0() interrupt 1
{	
	TR0=0;
	TH0=table2[table4[i]-1];  //取频率常数 和 节拍常数  
	TL0=table3[table4[i]-1];
	beep=~beep;
	TR0=1;
}
//定时器1中断子函数
void t1() interrupt 3
{	
	TR1=0;
	TH1=table2[7*bb+cc];	//取频率常数 和 节拍常数  
	TL1=table3[7*bb+cc];
	beep=~beep;
	TR1=1;	 	  				   	           		 		   
}

 

你可能感兴趣的:(北京交通大学海滨学院单片机课设,STC51精通+项目,protues,全注释代码,动态数码管显示,定时器计时,按键扫描)