⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ir_yinyue.c

📁 Keil C51单片机基础实验源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
0X76,0XA2,0X82,0X72,0X51,0X41,0X32,
0X4C,0X42,0X32,
0X76,0X82,0X74,0X82,0X72,
0X53,0X41,0X38,0X32,0X42,
0X16,0XC2,0X72,0X52,0X41,0X51,0X12,
0XCC,0XC2,0XB2,
0X16,0XC2,0X72,0X52,0X42,0X42,
0X3C,0X32,0X32,
0X26,0X22,0X24,0X42,0X32,
0x22,0x12,0x18,0x02,0x52,
0X46,0X12,0X44,0X72,0X82,
0X5C,0X52,0X52,
0X46,0X42,0X74,0X42,0X32,
0X36,0X42,0X58,
0X82,0X72,0X62,0X52,0X46,0X32,
0X3C,0X12,0XB2,
0X36,0X52,0X42,0X32,0X11,0XC1,0XB2,
0XC6,0X12,0XC4,0X12,0XC2,
0X76,0XA2,0X82,0X72,0X51,0X41,0X32,
0X48,0X02,0X42,0X52,0X62,
0X76,0X82,0X74,0X82,0X72,
0X56,0X41,0X38,0X32,0X22,
0X16,0XC2,0X72,0X52,0X42,0X42,
0X3C,0X04,0X04,0X04,0X04,
0xFF};
//第十二首 
unsigned char code song12[]={
0x34,0x32,0x34,0x34,0x24,0x34,0x32,0x32,0x24,0x38,0x44,0x58,0x48,
0x34,0x32,0x34,0x34,0x24,0x38,0x34,0x7F,0x34,0x32,0x34,0x32,
0x24,0x38,0x34,0x24,0x38,0x44,0x58,0x48,0x34,0x32,0x34,0x34,
0x24,0x38,0x34,0x7F,0x16,0x4C,0x74,
0x78,0x64,0x54,0x48,0x54,0x64,0x58,0x44,0x34,0x24,0x38,0x24,
0x14,0x12,0x21,0x11,0x78,0x68,0x3F,0x4C,0x74,
0x78,0x64,0x52,0x42,0x48,0x54,0x64,0x58,0x44,0x34,0x24,0x38,0x24,
0x24,0x38,0x44,0x58,0x48,0x3C,
0xFF};

unsigned char code* code songs[]={song1,song2,song3,song4,song5,song6,
                                  song7,song8,song9,song10,song11,song12};  //指向12首歌



unsigned char code yin[30]={0xFF,0xFF,0xFB,0x90,0xFC,0x0C,0xFC,0x44,0xFC,0xAC,0xFD,0x09,0xFD,0x34,
                  0xFD,0x82,0xFD,0xC8,0xFE,0x06,0xFE,0x22,0xFA,0X15,0XFB,0x04,0xFA,0x67,0xFE,0x85};  //C调各音符频率与计数初值T的对照表


//0.9ms
void delay0_9ms(void)
{
   unsigned char j,k;
   for(j=18;j>0;j--)
   for(k=20;k>0;k--) ;
}

//1ms
void delay1ms(void)
{
  unsigned char i,j;
  for(i=2;i>0;i--)
  for(j=230;j>0;j--) ;
}

//4.5ms
void delay4_5ms(void)
{
   unsigned char i,j;
   for(i=10;i>0;i--)
   for(j=225;j>0;j--) ;
}

//100ms
void delay100ms(void)
{
  unsigned char i,j,k;
  for(i=200;i>0;i--)  
  for(j=20;j>0;j--)
  for(k=10;k>0;k--) ;
}


/*延时1/4拍时间即187ms*/
void  delay187ms()
/*
{
  unsigned char i,j,k;
  for(i=200;i>0;i--)  
  for(j=20;j>0;j--)
  for(k=15;k>0;k--) ;
}
*/

{
 unsigned char i,j;
 for(i=255;i>0;i--)
	{
	 for(j=120;j>0;j--)
	  {
	     if(IR_OK==1) {break;}
	  }
	}
}



void t0(void) interrupt 0 using 2   //外部中断0的函数
{
    unsigned char i,j,k;
    EA=0;                        //暂时关闭CPU的所有中断请求

    for(k=0;k<10;k++)            //重复10次,目的是检测在9毫秒内如果出现高电平就退出解码程序
  {                              //aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
    
    delay0_9ms();               //延时0.9毫秒
    if (IR==1) {k=10;break;}    //延时0.9毫秒后判断P3.2脚是否出现高电平如果有就退出解码程序
    else if(k==9)                //重复10次?
           {                     //bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
            while(IR==0);       //等待高电平避开9毫秒低电平引导脉冲
            delay4_5ms();           //延时4.5毫秒避开4.5毫秒的结果码

			
/********************************************
//26位的用户码,前13位数据码,后13位数据反码
*********************************************/
              for(j=1;j<=26;j++)//每组数据为26位
                {                 
                 while(IR==0);  //
                 delay0_9ms();
                  if(IR==1)
                   {
					   delay1ms();
	                   dm=dm|0x2000000;              //因为是26位,一个"1",后面25个"0",转化二进制即为"1000000"    
	                   if(j<26) dm=dm>>1;            //数据"1",右移一个"1",一共25次
                   }                
                 else  if(j<26) dm=dm>>1;            //数据"0",一共25次
                }                    
             bb=dm;
             dm=0;



/***************************************************
//16位的用户码,前8位数据码,后8位数据反码
****************************************************/

			  for(i=0;i<2;i++)     
               {                
                 for(j=1;j<=8;j++)//每组数据为26位
                {                
                 while(IR==0);  //
                 delay0_9ms();
                  if(IR==1)
                   {
				     delay1ms();
                     dm=dm|0x80;
                     if(j<8) dm=dm>>1;           //数据"1",右移一个"1",一共7次
                   }                
                  else  if(j<8) dm=dm>>1;          //数据"0",一共7次
                }                    
             aa[i]=dm;
             dm=0;
               }              

/***************************************************
//解码成功的话,蜂鸣器叫一声
****************************************************/	           
               if(aa[0]==~aa[1])         //验证成功
        	   {
	               IR_OK=1;
			       sound=0;
             	   delay100ms();
	               sound=1;
        	   }

          }                     //bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
  }                             //aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
EA=1;
}


/*每个音符的发声*/
void timer0() interrupt 1 using 1  //定时器T0
{ 
     TH0=yin[2*l];
     TL0=yin[2*l+1];
     SPK = !SPK; 

}




void sing_song()
 {  
   unsigned int data j;    //取码指针
   unsigned char data i;   //用于循环
   unsigned char data k;   //几个1/4拍
   IR_OK=0;                //不能少掉!!!!
   song=songs[song_number];
   j=0;
    while(*(song+j)!=0xFF)                     //是否取到结束码
    {  
	   if(IR_OK==1){break;}                     //这一句很重要的!!!!!
       k=*(song+j)&0x0F;                       //后4位为多少个1/4拍
       l=*(song+j)>>4;                         //song(song+j)[]中所放的每个字节
                                               //前4位乘2表示为音符频率在数组yin[]中的位置
      
       TH0=yin[2*l];                           //置初值
       TL0=yin[2*l+1];
       TR0=1;                                  //起动定时器0
       if ((yin[2*l]==0xff)&&(yin[2*l+1]==0xff)) //如果取到的都是休止符,则不输出音频
           {
               TR0=0;SPK=1;
    		}
       for(i=k;i>0;--i)     //节拍K为多少就执行多少个1/4拍
           {  delay187ms();  } 
       TR0=0;
       j++;
    }                                            //回22222
 }                                               //回xxxxxx
                                          


 void main()
{

     EA=1;            //总中断
     TMOD=0x01;       //timer0工作在方式1
	 IT0=1;           //外部中断0触发方式控制位,下降沿触发
	 ET0=1;          //允许定时器T0中断
	 EX0=1;           //外部中断0(INT0)中断允许位
	 IP=0x01;         //定义外部中断0优先于定时器中断的优先级
 
	 dm=0;
	 P2=0xc0;
	 P1=0x00;

    while(1)
{
    if(IR_OK==1)
      { if(aa[0]==0x11)
         {song_number=0;P1=0x00;P2=0xf9;sing_song();}       //显示并演奏第1首
         else if(aa[0]==0x12)
         {song_number=1;P1=0x00;P2=0xa4;sing_song();}       //显示并演奏第2首
         else if(aa[0]==0x13)
         {song_number=2;P1=0x00;P2=0xb0;sing_song();}       //显示并演奏第3首
         else if(aa[0]==0x14)
         {song_number=3;P1=0x00;P2=0x99;sing_song();}       //显示并演奏第4首
         else if(aa[0]==0x15)
         {song_number=4;P1=0x00;P2=0x92;sing_song();}       //显示并演奏第5首
         else if(aa[0]==0x16)
         {song_number=5;P1=0x00;P2=0x82;sing_song();}       //显示并演奏第6首
         else if(aa[0]==0x17)
         {song_number=6;P1=0x00;P2=0xf8;sing_song();}       //显示并演奏第7首
         else if(aa[0]==0x18)
         {song_number=7;P1=0x00;P2=0x80;sing_song();}       //显示并演奏第8首
         else if(aa[0]==0x19)
         {song_number=8;P1=0x00;P2=0x90;sing_song();}       //显示并演奏第9首
         else if(aa[0]==0x10)
         {song_number=9;P1=0x00;P2=0x88;sing_song();}       //显示并演奏第10首
         else if(aa[0]==0x1a)
         {song_number=10;P1=0x00;P2=0x83;sing_song();}      //显示并演奏第11首
         else if(aa[0]==0x1b)
         {song_number=11;P1=0x00;P2=0xc6;sing_song();}      //显示并演奏第12首
		 else{sound=0;delay100ms();sound=1;delay100ms();
		      sound=0;delay100ms();sound=1;P1=0x00;P2=0xb6;}  //蜂鸣器叫,表明没有歌啦
        }
	  }
}
  		

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -