ISD4004录放多段音乐C程序
          
            时间:12-01 11:29 阅读:1879次
*温馨提示:点击图片可以放大观看高清大图
                
         
        
		  
               简介:如需要录更多的段数,只需要注意更改段数的值和录音的时间。程序中的录放停部分已做成子函数,可以直接调用,只需要输入录音的地址就行。
               
                        
          
            ///////////ISD4004语音播放模块----四段语音部分演示程序////////////////////////////
////当按下P3.5键时,从指定地址开始录音,每按一次,录一段语音,总共可以录四次。
/// 当按下P3.4键时,从指定地址开始放音,每按一次,放一段语音。总共可以放四段。
///	如需要录更多的段数,只需要注意更改段数的值和录音的时间。
///	程序中的录放停部分已做成子函数,可以直接调用, 只需要输入录音的地址就行
//录音地址的设定与芯片型号有关系,以ISD4004-8为例,ISD4004-8录音时间为8
//  分钟,即8*60=480S,	 根据4004的资料,480秒可分为2400段,也就是1S的段数为
//  5段,即从,0000-0005H的内容为1秒。
//本程序在放音前,没有做停止和下电处理,感兴趣的朋友可以把停止部分加到放音子函数中。
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned  char
#define uint  unsigned  int
bit playbit,recbit;	//定义两个位变量,放音和录音位
////////定义放音命令,定义常量//////
#define ISDPOWERUP      0X20           //ISD4004上电
#define ISDSTOP         0X10           //ISD4004下电
#define OPERSTOP        0X30           //ISD4004停止当前操作
#define PLAYSET         0XE0           //ISD4004从指定地址开始放音
#define PLAYCUR         0XF0           //ISD4004从当前地址开始放音
#define RECSET          0XA0      	   //ISD4004从指定地址开始录音
#define RECCUR          0XB0		   //ISD4004从当前地址开始录音
sbit   SS=P1^5;            //LOW IS ACTIVELY
sbit   MOSI=P1^1;
sbit   MISO=P1^7;
sbit   SCLK=P1^4; 
sbit   K1=P3^5;
sbit   K2=P3^6;
sbit   K3=P3^7;
sbit   LED1=P0^1;
sbit   LED2=P0^2;
void delayms(uchar ms);
uchar playcout,reccout;	 //放音和录音次数。		
////////////////放音部分子程序,放音地址由ADDR决定////
void play(uint addr)
 { 	uint y;
	SS=0;
	MOSI=0;//发送开始
	SCLK=0;
	for(y=0;y<8;y++)
	{
		SCLK=0;
		if((0x20>>y)&0x01)MOSI=1;
		else MOSI=0;
		_nop_();
		_nop_();
		_nop_();
		SCLK=1;
		_nop_();
		_nop_();
		_nop_();
	}//发送结束
	SS=1;//上电结束
	delayms(50);
	SS=0;
	MOSI=0;//发送地址
	SCLK=0;
	for(y=0;y<16;y++)
	{
		SCLK=0;
		if((addr>>y)&0x01)MOSI=1;
		else MOSI=0;
		_nop_();
		_nop_();
		_nop_();
		SCLK=1;
		_nop_();
		_nop_();
		_nop_();
	}//发送地址结束
	MOSI=0;//从指定地址放音指令
	SCLK=0;
	for(y=0;y<8;y++)
	{
		SCLK=0;
		if((0xe0>>y)&0x01)MOSI=1;
		else MOSI=0;
		_nop_();
		_nop_();
		_nop_();
		SCLK=1;
		_nop_();
		_nop_();
		_nop_();
	}
	SS=1;
	SS=0;
	MOSI=0;//放音指令
	SCLK=0;
	for(y=0;y<8;y++)
	{
		SCLK=0;
		if((0xf0>>y)&0x01)MOSI=1;
		else MOSI=0;
		_nop_();
		_nop_();
		_nop_();
		SCLK=1;
		_nop_();
		_nop_();
		_nop_();
	}
	SS=1;	  }	
//////////////////////////lu音部分子程序,地址由ADDR决定/////////////////////////
void rec(addr)                
{ 	uint y;	
	SS=0;
	//录音必须两次上电?
	MOSI=0;//发送开始
	SCLK=0;
	for(y=0;y<8;y++)
	{
		SCLK=0;
		if((0x20>>y)&0x01)MOSI=1;
		else MOSI=0;
		_nop_();
		_nop_();
		_nop_();
		SCLK=1;
		_nop_();
		_nop_();
		_nop_();
	}//发送结束
	SS=1;//上电结束
	delayms(50);
	SS=0;
	MOSI=0;//发送开始
	SCLK=0;
	for(y=0;y<8;y++)
	{
		SCLK=0;
		if((0x20>>y)&0x01)MOSI=1;
		else MOSI=0;
		_nop_();
		_nop_();
		_nop_();
		SCLK=1;
		_nop_();
		_nop_();
		_nop_();
	}//发送结束
	SS=1;//上电结束
	delayms(50);
	delayms(50);//延迟两个上电延迟时间?
	SS=0;
	MOSI=0;//发送地址
	SCLK=0;
	for(y=0;y<16;y++)
	{
		SCLK=0;
		if((addr>>y)&0x01)MOSI=1;
		else MOSI=0;
		_nop_();
		_nop_();
		_nop_();
		SCLK=1;
		_nop_();
		_nop_();
		_nop_();
	}//发送地址结束
	MOSI=0;
	SCLK=0;
	for(y=0;y<8;y++)
	{
		SCLK=0;
		if((0xa0>>y)&0x01)MOSI=1;
		else MOSI=0;
		_nop_();
		_nop_();
		_nop_();
		SCLK=1;
		_nop_();
		_nop_();
		_nop_();
	}
	SS=1;
	SS=0;
	MOSI=0;
	SCLK=0;
	for(y=0;y<8;y++)
	{
		SCLK=0;
		if((0xb0>>y)&0x01)MOSI=1;
		else MOSI=0;
		_nop_();
		_nop_();
		_nop_();
		SCLK=1;
		_nop_();
		_nop_();
		_nop_();
	}
	SS=1;	  }
////////////////////////////////////
////////////////////////////////
void stop()
{ 
    uchar y;
	SS=1;
	SS=0;
	MOSI=0;//放音
	SCLK=0;
	for(y=0;y<8;y++)
	{
		SCLK=0;
		if((0x30>>y)&0x01)MOSI=1;
		else MOSI=0;
		_nop_();
		_nop_();
		_nop_();
		SCLK=1;
		_nop_();
		_nop_();
		_nop_();
	}
	SS=1;
}
////////////////////////////////////
////////////////////////////////////
 void delayms(uchar ms)	
// 延时子程序
{						
	uchar j;
	while(ms--)
	{
		for(j = 0; j < 120; j++);
	}
}
////////////////////////////////
playsound()	///录放音子函数
{if(playbit)
 {playbit=0;
   switch(playcout)
    {case 0x01:{play(0x00);}break;	//此处第一段音乐的开始地址为0X00,到0X100地址结束,约为51秒。
     case 0x02:{play(0x100);}break;
     case 0x03:{play(0x200);}break;
     case 0x04:{play(0x300);}break; 
     }
   }
  if(recbit)
   {recbit=0;
    switch(reccout)
    {case 0x01:{rec(0x00);}break;
     case 0x02:{rec(0x100);}break;
     case 0x03:{rec(0x200);}break;
     case 0x04:{rec(0x300);}break; 
     }
    }
}
////////////////////////////////////
keyscan()  //直控键盘扫描子程序。
{uchar temp,temp1;
 temp=P3;
 if((temp&0xf0)!=0xf0)
   {  delayms(10);
      temp&=0xf0;
	  while(((temp1=P3)&0xf0)!=0xf0);
       { 
	    switch(temp)
	    {case 0xe0:
	      {playbit=1;
	       playcout++;
		   LED1=~LED1;
		   if(playcout>4)
		   playcout=0;}break;
	     case 0xd0:
	      { recbit=1;
		    reccout++;
		 	LED2=~LED2;
		    if(reccout>4)
		    reccout=0;}break;
		 case 0xb0:
		    { stop();
			  LED2=1;
			  LED1=1;
			}break;
         }
	    }
  }
 } 
////////////////////////////////////////////////
/////////以下部分为主程序///////////////////
void main()
{  P1=0xff;
   P2=0XFF;
   P3=0XFF;
while(1)
   { keyscan();
     playsound();
   	}
}