单片机电子琴模拟系统

2023-05-16

单片机电子琴模拟系统


实验一:


电子琴模拟系统即电子琴模拟器当选择不同的按键时,扬声器发出不同音阶的声音,仪器的最基本组成部分应包括:扬声器、模数转换电路、单片机控制电路。 设计一个用蜂鸣器模拟电子琴演奏音乐的程序。产生e调8个音阶的振荡频率,它分别由1、2、3、4、5、6、7、0号数字键控制。
实物图连线如图所示:
在这里插入图片描述

汇编程序如下:

    ;电子琴  -----------连续型   查询式键盘
    ;P3.2(INT0)   接扬声器

                  ;P1 键盘读入口    查询式
Pulse    equ 10h  ;脉冲
PulseCNT equ 50h  ;脉冲计数
ToneHigh equ 40h  ;高音调
ToneLow  equ 41h  ;低音调
Tone     equ 42h  ;音调
KeyBuf   equ 54h

Speaker  BIT  P2.0
         ORG  0000H
         ljmp  Start
         org   000bh
	 LJMP  Timer0Int
	 ORG   0030H
Timer0Int:        ;定时中断
       push  PSW
       clr   TR0
       mov   TH0, ToneHigh
       mov   TL0, ToneLow
       setb  TR0
       mov   C, Pulse
       MOV   Speaker,C

       CPL   Pulse
       pop   PSW
       reti

ToneTable:
      
        DW    64578,64686,64778,64821
        DW    64898,64968,65029
        
TestKey:
        MOV   P1,  #0FFH
        MOV   A,   P1
        CPL   A                ; 读入键状态

        ret

KeyTable:DB 0FEH,0FDH,0FBH,0F7H
         DB 0EFH,0DFH,0BFH,07FH    ; 键码定义
GETKEY:
        MOV       R6,#10
        ACALL     DELAY
        MOV       A,P1
        CJNE      A,#0FFH,K01               ;确有键按下
        LJMP      MLOOP
K01:    MOV       R3,#8                    ;8个键
        MOV       R2,#0                    ;键码
        MOV       B,A                      ;暂存键值
        MOV       DPTR,#KeyTable
K02:    MOV       A,R2
        MOVC      A,@A+DPTR                ;从键值表中取键值
        CJNE      A,B,K04                  ;键值比较
        MOV       A,R2                     ;得键码
        INC       A
        RET
K04:    INC       R2            ;不相等,到继续访问键值表
        DJNZ      R3,K02
        MOV       A,#0FFH       ;键值不在键值中,即多键同时按下
        LJMP      MLOOP

Delay:               ; 延时子程序
       mov   r7, #0
DelayLoop:
       djnz  r7, DelayLoop
       djnz  r6, Delay
       ret
             ;#########################
Start:
       mov  sp, #70h
       mov  TMOD, #01  ;  Timer
       mov  IE, #82h   ;  EA=1, IT0 = 1
       mov  Tone,#0
MLoop:
       call TestKey
       jz   MLoop
       call GetKey
       mov  b, a
       jz   MLoop      ; = 0, < 1
       anl  a, #8
       jnz  MLoop      ; > 8
       dec  b
       mov  a, b
       rl   a          ; a = a*2
       mov  b, a
       mov  dptr, #ToneTable
       movc a, @a+dptr
       mov  ToneHigh, a
       mov  TH0, a
       mov  a, b
       inc  a
       movc a, @a+dptr
       mov  ToneLow, a
       mov  TL0, a
        SETB      TR0
        MOV       P1,#0FFH
WAIT:
        MOV       A,P1

        CJNE      A,#0FFH, WAIT
        MOV       R6,#10
        ACALL     DELAY
        CLR       TR0
        LJMP      MLOOP
        END


实验二


把VOICE接到P2.2,能弹奏一首简单的儿歌《两只老虎》,实物图连接如图所示:
在这里插入图片描述

C语言代码如下:

#include<reg51.h>
#include<intrins.h>
#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;	 	  				   	           		 		   
}

实验三

连接44矩阵式键盘,实物图连接如所示,可以使用44矩阵键盘自己演奏音乐
在这里插入图片描述

可以实现自动播放音乐,可以播放《两只蝴蝶》《生日快乐》《爱情买卖》。需要源代码第147行进行修改,把m=music1则播放《两只蝴蝶》;改成m=music2则播放《生日快乐》;改成m=music3则播放《爱情买卖》。源代码如下:

#include <reg52.h>	         //调用单片机头文件 
#define uchar unsigned char  //无符号字符型 宏定义	变量范围0~255
#define uint  unsigned int	 //无符号整型 宏定义	变量范围0~65535  
sbit beep  = P3^2;	   //蜂鸣器定义  
sbit K1=P2^7;//音乐播放按键 
uchar flag_en = 0;	   //开始放歌 
uchar flag_i = 0; 
uint TT=0;
 sbit LED=P3^7;
  uchar num=0;//初始化num,用于控制数1码管显示的字符 
   //数码管段选定义       0    1    2    3   4	   5	6	 7	  8	   9	
    uchar code smg_du[]={0x28,0xee,0x34,0xa4,0xe2,0xa1,0x21,0xec,0x20,0xa0, 
	//					   A	B	 C	  D	   E   F	不显示 					  
	 0x60,0x23,0x39,0x26,0x31,0x71,0xbf};	 //断码	 
   uchar m,n; 
    uchar code T[49][2]={{0,0},
	 {0xF8,0x8B},{0xF8,0xF2},{0xF9,0x5B},{0xF9,0xB7},{0xFA,0x14},{0xFA,0x66},{0xFA,0xB9},{0xFB,0x03},
	  {0xFB,0x4A},{0xFB,0x8F},{0xFB,0xCF},{0xFC,0x0B},{0xFC,0x43},{0xFC,0x78},{0xFC,0xAB},{0xFC,0xDB}, 
	  {0xFD,0x08},{0xFD,0x33},{0xFD,0x5B},{0xFD,0x81},{0xFD,0xA5},{0xFD,0xC7},{0xFD,0xE7},{0xFE,0x05},
	   {0xFE,0x21},{0xFE,0x3C},{0xFE,0x55},{0xFE,0x6D},{0xFE,0x84},{0xFE,0x99},{0xFE,0xAD},{0xFE,0xC0},
	    {0xFE,0x02},{0xFE,0xE3},{0xFE,0xF3},{0xFF,0x02},{0xFF,0x10},{0xFF,0x1D},{0xFF,0x2A},{0xFF,0x36},
		 {0xFF,0x42},{0xFF,0x4C},{0xFF,0x56},{0xFF,0x60},{0xFF,0x69},{0xFF,0x71},{0xFF,0x79},{0xFF,0x81} 
		 };
		  uchar code music1[][2]={{0,4},	   //两只蝴蝶  
		 {23,4},{21,4},{23,16},{23,4},{21,4},{23,4},{21,4},{19,16},{16,4},
		 {19,4},{21,8},{21,4},{23,4},{21,4},{19,4},{16,4},{19,4},{14,24},
		  {23,4},{21,4},{23,16},{23,4},{21,4},{23,4},{21,4},{19,24},{16,4},
		  {19,4},{21,8},{21,4},{23,4},{21,4},{19,4},{16,4},{19,4},{21,24}, 
		   {23,4},{21,4},{23,16},{23,4},{21,4},{23,4},{21,4},{19,16},{16,4},
		   {19,4},{21,8},{21,4},{23,4},{21,4},{19,4},{16,4},{19,4},{14,24},
		    {23,4},{26,4},{26,16},{26,4},{28,4},{26,4},{23,24},{21,4},{23,4},
			{21,8},{21,4},{23,4},{21,4},{19,4},{16,4},{16,2},{19,2},{19,24},
			{0,20}, {26,4},{26,4},{28,4},{31,4},{30,4},{30,4},{28,4},{23,4},{21,4},{21,4},{23,16},{0,4},
			{23,4},{23,4},{26,4},{28,8},{28,12},{16,4},{23,4},{21,4}, {21,24},{23,4},{26,4},{26,4},{23,4},{26,8},{0,4},
			{31,8},{30,4},{28,4},{30,4},{23,8},{0,4},{28,4},{28,4},{30,4},{28,4},{26,4},{23,4},{21,8},{23,4},{21,4},{23,4},
			{26,16}, {0xFF,0xFF}}; 
				uchar code music2[][2]={{0,4},	  //生日快乐
				 {17,6},{17,2},{19,8},{17,8},{22,8},{21,16},
				  {17,6},{17,2},{19,8},{17,8},{24,8},{22,16},
				  {17,6},{17,2},{29,8},{26,8},{22,8},{21,8},{19,8},
				  {27,6},{27,2},{26,8},{22,8},{24,8},{22,16}, {0xFF,0xFF}}; 
				 uchar code music3[][2]={{0,4},	 //爱情买卖 
				 {22,4},{22,4},{17,4},{15,4},{15,4},{17,12}, {15,4},
				 {15,2},{17,2},{15,4},{13,4},{13,4},{15,12},{0,4}, {20,4},{20,4},
				 {20,4},{17,4},{20,4},{20,4},{20,4},{17,4}, {22,4},{17,4},{17,4},{15,4},
				 {15,4},{17,12}, {22,4},{22,4},{17,4},{15,4},{15,4},{17,12}, {15,4},{15,2},
				 {17,2},{15,4},{13,4},{13,4},{15,12}, {20,4},{20,4},{20,2},{17,2},{17,4},{20,4},{20,4},{20,2},
				 {17,2},{17,2},{17,2}, {24,4},{20,4},{20,2},{17,2},{17,4},{20,4},{22,12}, {17,4},{22,4},{25,4},
				 {25,4},{17,4},{22,4},{25,8}, {24,4},{22,2},{24,2},{22,4},{20,4},{15,4},{17,12}, {15,4},{15,4},
				 {15,4},{10,4},{15,4},{17,4},{20,8}, {17,4},{24,4},{24,4},{20,4},{15,4},{17,12}, {17,4},{22,4},{25,4},
				 {25,4},{17,4},{22,4},{25,8}, {29,4},{27,2},{29,2},{27,4},{25,4},{25,4},{27,12}, {29,4},{29,2},{27,4},
				 {25,4},{27,6},{27,2},{25,4},{24,4}, {20,4},{20,2},{17,2},{20,4},{20,2},{22,2},{22,16}, {0xFF,0xFF}}; 
				  void delay(uchar p) 
				  {     uchar i,j;    
				    for(;p>0;p--)    
					 for(i=181;i>0;i--)     
					 for(j=181;j>0;j--); 
					 }  void pause()
					  {     uchar i,j;     
					  for(i=150;i>0;i--)    
					   for(j=150;j>0;j--); } 
					     /***********************1ms延时函数*****************************/ 
						 void delay_1ms(uint q) 
						 { 	uint i,j; 
						 	for(i=0;i<q;i++) 	
								for(j=0;j<120;j++); 
								} 
								 /******************按键程序*************************/
								  uchar key_can;//按键值 	
									  void key()	 //独立按键程序 
									  { 	static uchar key_new = 0, key_l; 
									  	key_can = 20;                   //按键值还原 
											P2 = 0x0f;
											 	if((P2 & 0x0f) != 0x0f)		//按键按下
												 	{ 		delay_1ms(1);	     	//按键消抖动 	
														if(((P2 & 0x0f) != 0x0f) && (key_new == 1)) 
																{						//确认是按键按下 		
																	key_new = 0; 			key_l = (P2 | 0xf0);   //矩阵键盘扫描 	
																			P2 = key_l; 		
																				switch(P2) 
																			   {						 
																			   				case 0xee:  key_can = 0; m = 8;	TT=0; flag_en=0;TR0 = 1; break;  //得到按键值  //打开定时器  		
																						case 0xde:  key_can = 1; m = 9;	TT=0;flag_en=0;TR0 = 1;   break;   //得到按键值  
																						case 0xbe:  key_can = 2; m = 10;TT=0;flag_en=0;	TR0 = 1;   break;   //得到按键值 
																						case 0x7e:  key_can = 3; m = 11;TT=0;flag_en=0;	TR0 = 1;   break;   //得到按键值 
																						case 0xed:  key_can = 4; m = 12;TT=0;flag_en=0;	TR0 = 1;   break;  //得到按键值  				
																						case 0xdd:  key_can = 5; m = 13;TT=0;flag_en=0;	TR0 = 1;   break;   //得到按键值  				
																						case 0xbd:  key_can = 6; m = 14;TT=0;flag_en=0;	TR0 = 1;  break;   //得到按键值  				
																						case 0x7d:  key_can = 7; m = 15;TT=0;flag_en=0;	TR0 = 1;   break;   //得到按键值  	 				
																						case 0xeb:  key_can = 8; m = 16;TT=0;flag_en=0;	TR0 = 1;   break;  //得到按键值  				
																						case 0xdb:  key_can = 9; m = 17;TT=0;flag_en=0;	TR0 = 1;   break;   //得到按键值  				
																						case 0xbb:  key_can = 10; m = 18;TT=0;flag_en=0;	TR0 = 1;   break;   //得到按键值  				
																						case 0x7b:  key_can = 11; m = 19;TT=0;flag_en=0;	TR0 = 1;   break;   //得到按键值  	 				
																						case 0xe7:  key_can = 12; m = 20;TT=0;flag_en=0;	TR0 = 1;   break;  //得到按键值  				
																						case 0xd7:  key_can = 13; m = 21;TT=0;flag_en=0;	TR0 = 1;   break;  //得到按键值  				
																						case 0xb7:  key_can = 14; m = 22;TT=0;flag_en=0;	TR0 = 1;   break;   //得到按键值  				
																						case 0x77:  key_can = 15; m = 23;TT=0;flag_en=0;	TR0 = 1;   break;  //得到按键值 	 		
																						}
	P1 = smg_du[key_can];	  //显示 			
	while(P2 != 0x0f) 		   		
	P2 = 0x0f; 			
	TR0 = 0;  	    //关闭定时器 	
		}			 
			} 	
			else 		 //按键松开 	
			{ 		P1 = 0xdf;	  //显示小数点 		
				key_new = 1;	 	
			} 
			 /*********************歌曲播放*********************/ 
			 K1=1 ; 	
			 if(K1==0) 	
			 { 		
			 	delay_1ms(10);	 //按键去抖动 		
				if(K1==0) 		
				{ 			
					num=8; 
					//			P1=smg_du[num];//使数码管显示该音调的字符 			
					flag_en ++; 			
					flag_i = 0; 			
					if(flag_en > 3) 			
					{ 				
						flag_en = 0;	 				
						TR0 = 0; 			}	 			
						while(!K1) 			
						{ 			
						}//使蜂鸣器发出相应频率的声音; 		
					} 	
			} 
} 
						/******************主程序**********************/	    
						void main() 
						{ 	
							P0 = P1 = P2 = P3 = 0xff; 	
							TMOD=0x11;  	 
							EA=1; 	  
							PT1=1; 	   
							ET0=1; 	   
							TR1=1; 	   
							ET1=1;   	   
							TH1=(65536-50000)/256;  
						TL1=(65536-50000)%256; //定时器0初始化 
						while(1) 	
						{ 		
							P1 = 0xdf;	  //显示小数点 		
							key();	  //按键程序 		
							if(flag_en == 1)	 //爱情买卖 		
							{ 			m=music1[flag_i][0];n=music1[flag_i][1]; 	   //放歌  			
							P1 = smg_du[m % 16];	  //显示 			
							if(m==0x00) 			
							{ 				
								TR0=0; 				
								beep = 1; 				
								delay(n); 				
								flag_i++; 			}
								else if(m==0xFF)				 //放歌结束 			
								{ 				
									TR0=0;beep = 1;
									delay(30);
									flag_i=0;
									flag_en = 0;
									}  			
								else if(m==music1[flag_i+1][0])  				
								{	TR0=1;
									delay(n);TR0=0;beep = 1;pause();flag_i++; } 			
								else 				{TR0=1;delay(n);flag_i++;} 		} 		
								else  			beep = 1 ; 
								if(flag_en == 2)	 //生日歌 		
								{ 	m=music2[flag_i][0];n=music2[flag_i][1]; 	   //放歌  			
									P1 = smg_du[m % 16];	  //显示 			
									if(m==0x00) 			
									{ 				
										TR0=0; 				
										beep = 1; 				
										delay(n); 				
										flag_i++; 			}  
										else if(m==0xFF)				 //放歌结束 			
										{ 				TR0=0;beep = 1;delay(30);flag_i=0;flag_en = 0;}  			
										else if(m==music2[flag_i+1][0])  				
										{TR0=1;delay(n);TR0=0;beep = 1;pause();flag_i++; } 			
										else 				{TR0=1;delay(n);flag_i++;} 		} 		
										else  			{ 			beep = 1 ; 			 			}
										if(flag_en == 3)	 //新年好 		
										{ 			m=music3[flag_i][0];n=music3[flag_i][1]; 	   
										//放歌  			
										P1 = smg_du[m % 16];	  //显示 			
										if(m==0x00) 			
										{ 				
											TR0=0; 				
											beep = 1; 				
											delay(n); 				
											flag_i++; 			}  			
										else if(m==0xFF)				 //放歌结束 			
										{ 				TR0=0;beep = 1;delay(30);flag_i=0;flag_en = 0;}  			
										else if(m==music3[flag_i+1][0])  				
										{TR0=1;delay(n);TR0=0;beep = 1;pause();flag_i++; } 			
										else 				{TR0=1;delay(n);flag_i++;} 		} 		
										else  		{ 			beep = 1 ; 			 			 			 			} 	} }  
										/*****************定时器0中断*********************/	    
										void T0_int() interrupt 1 
										{ 	beep=!beep; 	
											TH0=T[m][0];  	
											TL0=T[m][1]; } 
											void T1_int() interrupt 3 
											{  TH1=(65536-50000)/256;  
											TL1=(65536-50000)%256;  
											if(flag_en==0)
											{  TT++;  
												LED=!LED;    
												if(TT>=100)  
													{  TT=0;  
													flag_en++;  //TR1=0;   
													}  } }

实验台型号如下图所示:
在这里插入图片描述

大家也可以从源代码中更换简谱,来演奏别的的音乐。这里就不过多解释了。学艺不精,还请各位大佬多多批评指正,提出把宝贵的意见,不胜感激!!!
感兴趣的可以加我qq:779551378
wx:15668141627
最后希望对大家有帮助 !!1

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

单片机电子琴模拟系统 的相关文章

  • 什么是串口通信协议

    ARM体系结构 串口通信 一 什么是串口通信 1 串口通信属于基层基本性的通信规约 xff0c 收发双方事先规定好通信参数 2 它自己本身不会去协商通信参数 xff0c 需要通信前通信双方事先约定好通信参数来进行通信 3 因此 xff0c
  • 利用MQTT协议与阿里云数据交互的python程序

    利用MQTT协议与阿里云数据交互的python程序 设计目的功能要求和关键问题环境配置问题本地程序如何连接云上设备云上的数据交互问题界面设计问题 阿里云相关操作本地程序 设计目的 设计开发一个py应用程序 xff0c 实现对阿里云数据的双向
  • 中文分词:隐马尔可夫-维特比算法(HMM-Viterbi)附源码

    目录 0 先验知识 1 什么是中文分词 2 数据集的构造 3 训练及预测过程简述 4 训练阶段 xff1a 统计隐马尔可夫模型的参数 5 预测阶段 xff1a 应用 Viterbi 算法 6 完整的 Python 实现代码 0 先验知识 有
  • python学习day1

    打印字 print haha 注释符 单行注释符 xxx 多行注释符 xxx xxx 34 34 定义变量 a 61 10 定义数字 b 61 haha ni hao 定义字符串 print a print b 赋值 b 61 a 用户交互
  • 系统学习-----firewalld概述

    动态防火墙后台服务程序 xff1a 提供一个动态管理的防火墙 xff0c 用以支持网络 Zone xff0c 来分配对一个网络链接和界面一定程序的信息 xff0c 它具备对IPv4和Ipv6防火墙设置的支持 它支持以太网桥 xff0c 并有
  • 系统学习----DHCP服务原理

    文章目录 DHCPDHCP优点DHCP相关概念DHCP租约更新DHCP运行过程 DHCP DHCP xff1a 动态主机设置协议 xff0c 是一个局域网协议 xff0c 使用UDP协议工作 主要有两个用途 xff1a 用于局域网或网络服务
  • 区块链技术及应用---区块链技术(一)

    文章目录 第一章 疯狂的比特币及其原理机制1 1 比特币诞生1 2 疯狂的比特币1 2 1 疯狂的价格1 2 2 疯狂的矿机和芯片 1 3 通俗地讲比特币机制1 4比特币交易1 5 比特币挖矿1 5 1 数学难题1 5 2 矿池原理 1 6
  • OpenFlow协议是什么

    为什么学习OpenFlow xff1f 实践SDN的首选主流南向接口协议P4和PISA的前身 OpenFlow起源 Ethane项目是OpenFlow的前身 集中式 主动式 xff0c 基于Flow控制2008年的Open Flow论文最初
  • OpenDaylight(ODL)学习笔记

    什么是OpenDaylight xff1f OpenDaylight是SDN开发及运行的一个平台 OpenDaylight架构特点 基于OSGi的模块化设计多南向协议 OpenFlow xff0c Netconf xff0c OVSDB 模
  • Vue / axios / props 调用后端接口数据并渲染到页面

    情景介绍 给了一个可视化大屏的代码 xff0c 代码上写的是假数据 现在要调用后端接口获取数据 xff0c 并将其渲染到页面上 分析问题 给的代码是一个 vue 组件嵌套一个子组件 xff0c 要把数据渲染到子组件上 要调用后端接口 xff
  • Element-ui关于el-icon无法正常显示的问题(已解决)

    在使用element ui组件库的时候 xff0c 使用自带的图标不显示 xff0c 查了好多篇博客 xff0c 都说是element ui的版本老了 xff0c 在package json中修改版本重新安装就行 xff0c 但是我的情况不
  • el-dialog关闭后表单数据缓存没清空【已解决】

    情景介绍 系统中有 新增 和 修改 两个功能 xff0c 共用一个对话框 要求新增时对话框内容为空 xff0c 修改时内容默认填充旧数据 遇到的问题是 xff0c 点击新增后内容填充了 xff0c 关闭对话框再点击新增或者其他条目的修改 x
  • Vue中父组件向子组件传值,子组件没有接收到

    情景介绍 父组件调用接口获取数据 xff0c 然后通过props传值给子组件 xff0c 子组件拿到数据后渲染到 el table 表格组件中 结果子组件没有将数据渲染到表格中 xff0c 但是控制台打印是获取到数据的 问题分析 先看父组件
  • 数字通信系统的性能及可靠性

    目录 1 数字通信系统的性能 2 数字通信系统的可靠性 1 数字通信系统的性能 数字通信系统的性能由码元速率 信息速率 频带利用率表示 每个码元所携带的信息量I定义如下 xff1a 这里 P 是每个码元的概率 xff0c M 是码元的个数
  • 前端学习资源分享

    学习资源 编程导航 xff08 包含以下所有资源 xff0c 强烈推荐 x1f44d xff09 xff1a https www code nav cn freeCodecamp 在线编程 xff1a https learn freecod
  • 嵌入式方向分析

    很多计算机 电子信息类专业的学生都想把嵌入式开发作为自己的职业目标 xff0c 但是因为嵌入式涉及的知识太多 xff0c 太杂 xff0c 太广 xff0c 很多嵌入式初学者陷入嵌入式知识的海洋中 xff0c 东学一点 xff0c 西学一点
  • UWB-DW1000初始化、发送和接收详解(一)

    DWM1000简介 DWM1000板子上的DW1000芯片 xff0c 是基于CMOS的 低功耗的无线收发集成电路 xff0c 遵循IEEE 802 15 4 2011协议中的UWB标准芯片 DWM1000不需要用户去设计电路 xff0c
  • 云计算-弹性存储

    云盘 挂载到ECS上的磁盘 NAS 文件存储 OSS 对象存储 外链图片转存失败 源站可能有防盗链机制 建议将图片保存下来直接上传 img 1NMdcten 1653882562436 https files mdnice com user
  • computers & security投稿教程

    在computers amp security上投稿了一篇论文 xff0c 中间还是遇到一些不太懂的东西 xff0c 在此记录下来 1 首先打开官网 xff0c 链接 https www editorialmanager com cose
  • 【SDN测试题】

    SDN测试题 一 判断题 NFV与SDN的基础都是通用服务器 云计算以及虚拟化技术 正确答案 xff1a 对 安装OpenvSwitch时必须根据系统内核版本选择相应的Open vSwitch版本 正确答案 xff1a 对 执行命令ovs

随机推荐