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

📄 myboard.c

📁 单片机电子音乐程序
💻 C
📖 第 1 页 / 共 4 页
字号:
  SCL=0;
  IICClockDelay();
}
/*************************************************************************/
void StartIIC()                /*发送IIC总线启动时序*/
{
    SCL=1;
	IICClockDelay();
	SDA=1;
	IICClockDelay();
    SDA=0;
	IICClockDelay();
	SCL=0;
	IICClockDelay();   
}
/*************************************************************************/
void StopIIC()                 /*发送IIC总线停止时序*/
{
    SDA=0;
	IICClockDelay();
	SCL=1;
	IICClockDelay();
	SDA=1;
	IICClockDelay();
	SCL=1;
	IICClockDelay();
}
/*************************************************************************/
bit IICSendByte(uchar byteData)   /*向24C02发送一个字节数据或地址函数,返回值为发送成功与否标志*/
{
    bit ackFlag;
	uchar i;
    for(i=0;i<8;i++)              /*要传送的数据长度为8位*/
    {
        if((byteData<<i)&0x80)    /*依次判断待发送位高低*/
            SDA=1;                
        else  
            SDA=0;                   
        IICClockDelay();
        SCL=1;                    /*置时钟线为高,通知24C02开始接收数据位*/
        IICClockDelay();         
        SCL=0; 
	    IICClockDelay();
    }
    SDA=1;                        /*8位数据发送完后释放数据线,准备接收应答位*/
    IICClockDelay();   
    SCL=1;
    IICClockDelay();
    if(SDA==1)
        ackFlag=0;                /*24c02无应答*/     
    else 
        ackFlag=1;                /*数据成功发送*/
    SCL=0;
    IICClockDelay();
	return(ackFlag);              /*返回24C02应答标志*/
}
/*************************************************************************/
uchar  IICRcvByte()               /*从24C02读取一个字节数据函数,返回值为读入的该字节*/
{
    uchar retbyteData=0x00,i;       /*置返回值初值为0x00*/
    for(i=0;i<8;i++)
    {
        SDA=1;
        IICClockDelay();
        SCL=1;                    /*拉高时钟线后读取数据线电平*/
        IICClockDelay();
	    retbyteData=retbyteData<<1;   /*返回值依次左移一位*/
	    if(SDA==1)                    /*读取数据线电平至于返回值空出的一位*/
	    { 
	        retbyteData+=1;
	    }
	    SCL=0;                    /*拉低释放时钟线*/     
	    IICClockDelay();
   }
   return(retbyteData);
}
/*************************************************************************/
/*向24C02的指定地址写入若干个数据函数*/
bit IICWrite(uchar slaveAddress,uchar subAddress,uchar *dataPointer,uchar num)
{
    bit retBit;	
    uchar i;
    StartIIC();               	              /*启动总线*/
    retBit=IICSendByte(slaveAddress);         /*发送器件地址*/
    if(retBit==0)
        return(0);
    retBit=IICSendByte(subAddress);           /*发送器件子地址*/
    if(retBit==0)
        return(0);
    for(i=0;i<num;i++)
    {
        retBit=IICSendByte(*(dataPointer+i)); /*发送数据*/
        if(retBit==0)
            return(0);
    }   
    StopIIC();  		                      /*结束总线*/ 
    return(0);
}
/*************************************************************************/
/*从24C02的指定地址读入若干个数据函数*/
bit IICRead(uchar slaveAddress,uchar subAddress,uchar *dataPointer,uchar num)
{
    bit retBit;	
	uchar i;
    StartIIC();                               /*启动总线*/
    retBit=IICSendByte(slaveAddress);         /*发送器件从地址*/   
    if(retBit==0)
        return(0);   
    retBit=IICSendByte(subAddress);           /*发送器件子地址*/   
    if(retBit==0)
        return(0);
    StopIIC();                                /*结束总线*/ 
    StartIIC();			                      /*重新启动总线*/
    retBit=IICSendByte(slaveAddress+1);   
    if(retBit==0)
        return(0);  
    for(i=0;i<num-1;i++)
    {
        *dataPointer=IICRcvByte();            /*接收数据*/
        IICAck(0);                            /*发送应答位*/
        dataPointer++;
    }                   
    *dataPointer=IICRcvByte();                /*接收数据*/
    IICAck(1);
    StopIIC();                                /*结束总线*/ 
    return(1);
}
/*************************************************************************/
void Timer0Int() interrupt 1 using 2   	    /*每隔SCAN_CYCLEus中断扫描一次数码管*/
{
    uint temp;
    LEDCycle500usFlag=1;                    /*置500us标志位*/
    ScanSeg7();
    if(Int0Flag==1)                         /*如果需要产生音乐频率则按音频改变Timer0的中断周期*/
	{	    
        P3_3=~P3_3;                         /*每个Timer0中断翻转一下P3.7的电平以产生相应频率的方波*/
		TH0=TH0Global;
	    TL0=TL0Global;
	}
	else                                    /*如果不需要产生音乐频率则按固定扫描时间改变Timer0的中断周期*/
	{
	    temp=65536-SCAN_CYCLE;
	    TH0=temp>>8;
		TL0=temp-((temp>>8)<<8);
	}	
}	
/*************************************************************************/
void Timer1Int() interrupt 3 using 3     	/*Timer1中断服务程序,中断周期为10ms*/
{
    uchar ucharTemp,ucharTemp1,TH0temp,TL0temp;
	uint temp;
    static uchar s_timeBaseCounter;
    static uchar s_paiCounter,s_secCounter,s_paiNum;
	temp=65536-10000;                       /*中断周期为10ms*/
    TH1=temp>>8;	                        /*temp/256相当于右移8位*/ 	
    TL1=temp-((temp>>8)<<8);                /*temp%256*/
	if(++s_timeBaseCounter>=10)             /*100ms到了则设置100ms标志位*/
	{
	    s_timeBaseCounter=0;
	    LEDCycle100msFlag=1;       
	}
	LEDCycle10msFlag=1;                     /*设置10ms标志位*/

    if(++s_paiCounter>=s_paiNum)		    /*音乐一拍的时间到了*/
    {
        s_paiCounter=0;
        switch(s_musicCounter)              /*根据当前音乐编号查找下一个音乐标识码*/
		{
		case 0x01: ucharTemp=c_music1[s_tableCounter++];break;
		case 0x02: ucharTemp=c_music2[s_tableCounter++];break;
		case 0x03: ucharTemp=c_music3[s_tableCounter++];break;
		case 0x04: ucharTemp=c_music4[s_tableCounter++];break;
		case 0x05: ucharTemp=c_music5[s_tableCounter++];break;
		case 0x06: ucharTemp=c_music6[s_tableCounter++];break;
		case 0x07: ucharTemp=c_music7[s_tableCounter++];break;
		case 0x08: ucharTemp=c_music8[s_tableCounter++];break;
		case 0x09: ucharTemp=c_music9[s_tableCounter++];break;
		case 0x00: ucharTemp=c_music0[s_tableCounter++];break;
		}			
		if(ucharTemp==0x00)                 /*如果查到0x00则表示本首歌曲结束*/
		{
			Int0Flag=0;                     /*产生音乐频率标志置零*/
			temp=65536-SCAN_CYCLE;
			TH0temp=temp>>8;                    /*temp/256相当于右移8位*/
			TL0temp=temp-((temp>>8)<<8);        /*temp%256*/
			TH0=TH0temp;
			TL0=TL0temp;
			s_paiNum=4*PAI_BASE;            /*本首歌曲结束后停顿4*PAI_BASE*10ms=600ms再继续播放*/
			P3_7=1;                         /*把喇叭关掉*/
			s_tableCounter=0;
			if(musicAutoFlag==1)            /*如果歌曲自动循环播放功能打开则跳到下一首歌曲*/
			{
			    if(++s_musicCounter>(uchar)MUSIC_NUM)
			    {
				    s_musicCounter=0x01;
			    }
			}
		}
		else                                       /*如果查到非0x00则表示是音乐标识码*/
		{			    
			s_paiNum=(ucharTemp&0x0f)*PAI_BASE;    /*音乐标识码的低四位为节拍码*/
			ucharTemp1=(ucharTemp&0xf0)>>4;        /*音乐标识码的高四位为音频码*/
			if(ucharTemp1==0)                      /*如果音频码为零则表示不发音*/
			{
			    Int0Flag=0;
				temp=65536-SCAN_CYCLE;
				TH0temp=temp>>8;                       /*temp/256相当于右移8位*/
			    TL0temp=temp-((temp>>8)<<8);           /*temp%256*/
				TH0=TH0temp;
			    TL0=TL0temp;
				Int0Flag=0;
			}
			else                                   /*如果音频码不为零则按此改变Timer0的中断周期*/
			{
			    Int0Flag=0;
			    temp=c_musicFreq[ucharTemp1-1];
				TH0temp=temp>>8;                       /*temp/256相当于右移8位*/
			    TL0temp=temp-((temp>>8)<<8);           /*temp%256*/
				TH0=TH0temp;
			    TL0=TL0temp;
				TH0Global=TH0;                       /*保存新的代表音频的Timer0周期值*/
				TL0Global=TL0;
				Int0Flag=1;
		    }
		}
    }

    if(++s_secCounter>=100)               /*如果Timer1中断100次则表示1s到了*/
	{
	    s_secCounter=0;
        sec++;			                  /*秒加一*/
        modifyTimeFlag=1;
    }	
    TF1=0;                                 
}				
/*************************************************************************/
void UARTInt() interrupt 4 using 1   	  /*串口中断服务程序*/
{
    if(TI==1)                             /*是发送中断则返回*/
	{
	    TI=0;
		return;
	}
	else                                  /*接收到数据*/
	{	
	    uchar rcv;
        while(RI!=1);
	    {
	        RI=0;                         /*请接收标志位以激活下次串口中断*/
		    rcv=SBUF;
		    switch(rcv)
		    {
			case 48: UARTKeyFlag=0x0d;    /*收到'0'*/
					 break;
		    case 49: UARTKeyFlag=0x00;    /*收到'1'*/
					 break;
			case 50: UARTKeyFlag=0x01;    /*收到'2'*/
					 break;
			case 51: UARTKeyFlag=0x02;    /*收到'3'*/
					 break;
			case 52: UARTKeyFlag=0x04;    /*收到'4'*/
					 break;
			case 53: UARTKeyFlag=0x05;    /*收到'5'*/
					 break;
			case 54: UARTKeyFlag=0x06;    /*收到'6'*/
					 break;
			case 55: UARTKeyFlag=0x08;    /*收到'7'*/
					 break;
			case 56: UARTKeyFlag=0x09;    /*收到'8'*/
					 break;
			case 57: UARTKeyFlag=0x0a;    /*收到'9'*/
					 break;
			case 65: UARTKeyFlag=0x03;    /*收到'A'*/
					 break;
			case 66: UARTKeyFlag=0x07;    /*收到'B'*/
					 break;
			case 67: UARTKeyFlag=0x0b;    /*收到'C'*/
					 break;
			case 68: UARTKeyFlag=0x0f;    /*收到'D'*/
					 break;
			case 69: UARTKeyFlag=0x0c;    /*收到'E'*/
					 break;
			case 70: UARTKeyFlag=0x0e;    /*收到'F'*/
					 break;
			}
	    }
	}
}
/*************************************************************************/
/////////////////////////////End of Program////////////////////////////////
/*************************************************************************/

⌨️ 快捷键说明

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