| 
 //***************************************************** //      ISD4002-89c51开发板演示例程    C51版本        * //              作者:中青世纪       Lell             * //                     2008.2.27                      * //                                                    * //      更多ISD4000使用心得请登陆中青世纪论坛         * //        http://www.atvoc.com/bbs                    * //                                                    * //***************************************************** #include <reg51.h> sbit SS   =     P1^0;              //片选 sbit SCLK =     P1^1;              //ISD4003时钟 sbit MOSI =     P1^2;              //数据输入 sbit MISO =     P1^3;              //数据输出 sbit LED =     P1^7;              //指示灯 sbit ISD_INT=   P3^2;           //中断 sbit AN =     P1^6;              //执行 sbit STOP =     P1^5;             //复位 sbit PR =     P1^4;              //PR=1录音? PR=0放音 void    delay(unsigned int time)   //延迟n微秒 { while(time!=0) { time-- ; } } void     delayms(unsigned int time)    //延迟n毫秒 {    TMOD=0x01; 
    for(time;time>0;time--) { TH0=0xfc; TL0=0x18; TR0=1; while(TF0!=1) {;} TF0=0; TR0=0; } 
} 
//************************************ //ISD4002 spi串行发送子程序,8位数据 //************************************ void spi_send(unsigned char isdx) {   unsigned char isx_counter; SS=0;     //ss=0,打开spi通信端 SCLK=0; for(isx_counter=0;isx_counter<8;isx_counter++) //先发低位再发高位,依次发送。 { if ((isdx&0x01)==1) MOSI=1; else MOSI=0; isdx=isdx>>1; SCLK=1; delay(2); 
   SCLK=0; delay(2); } } 
//******************************* //发送stop指令 //******************************* void isd_stop(void) {   delay(10); spi_send(0x30); SS=1; delayms(50); } //******************************* //发送上电指令,并延迟50ms //******************************* void isd_pu(void) {  delay(10); SS=0; spi_send(0x20); SS=1; delayms(50); } //******************************* //发送掉电指令,并延迟50ms //******************************* 
void isd_pd(void) { delay(10); 
     spi_send(0x10); SS=1; delayms(50); } //******************************* //发送play指令 //******************************* void isd_play(void) { LED=0; spi_send(0xf0); SS=1; } //******************************* //发送rec指令 //******************************* void isd_rec(void) { LED=0; spi_send(0xb0); SS=1; } //******************************* //发送setplay指令 //******************************* void isd_setplay(unsigned char adl,unsigned char adh) 
{ 
spi_send(adl);    //发送放音起始地址低位 adh=adh||0xe0; spi_send(adh);   //发送放音起始地址高位 SS=1; } //******************************* //发送setrec指令 //******************************* void isd_setrec(unsigned char adl,unsigned char adh) { spi_send(adl);    //发送放音起始地址低位 adh=adh||0xa0; spi_send(adh);    //发送放音起始地址高位 SS=1; } //************************************ //芯片溢出,LED闪烁提醒停止录音 //************************************ void isd_overflow(void) { while(AN==0) {LED=1; delayms(300); LED=0; delayms(300); } 
} //************************************ //检查芯片是否溢出(读OVF,并返回OVF值) //************************************ unsigned char chk_isdovf(void) { SS=0; delay(2); SCLK=0; delay(2); SCLK=1; SCLK=0; delay(2); 
if (MISO==1) { SCLK=0; SS =1;     //关闭spi通信端 isd_stop();     //发送stop指令 return 1;     //OVF为1,返回1 } else { SCLK=0; SS =1;         //关闭spi通信端 isd_stop();     //发送stop指令 return 0;     //OVF为0,返回0 
} } 
//************************************************************************ //主程序 //功能:1.录音时,按住AN键,LED点亮开始录音,松开AN即可停止录音 //    再次按下AN键,LED点亮开始录第二段音,依次类推,直到芯片溢出。 //     按stop键芯片复位 //     2.放音时,按一下AN键,即播放一段语音。 按stop键芯片复位。 //************************************************************************ 
void main(void) {unsigned char ovflog; while(1) { P0=P1=P2=P3=0xff;  //初始化 while (AN==1)     //等待AN键按下 { if (AN==0)                 //按键防抖动 {delayms(20);} } isd_pu();     //AN键按下,ISD上电并延迟50ms isd_pd(); isd_pu(); 
    if (PR==1)     //如果PR=1则转入录音部分 { delayms(500);     //延迟录音 
     isd_setrec(0x00,0x00);     //发送0x0000h地址的setplay指令 do { isd_rec();    //发送rec指令 while(AN==0)    //等待录音完毕 {if (ISD_INT==0)     //如果芯片溢出,进行LED闪烁提示, isd_overflow();    //如果取消录音(松开AN键)则停止录音,芯片复位 } 
     if (ISD_INT==0) 
     break; LED=1;         //录音完毕,LED熄灭 isd_stop();     //发送停止命令 while(AN==1)     //如果AN再次按下,开始录制下一段语音 {if(STOP==0)    //如果按下STOP按键,则芯片复位 break; if (AN==0) delayms(500); } }while(AN==0); 
    } else             //如果PR==0则转入放音部分 { while(AN==0){;} isd_setplay(0x00,0x00);     //发送setplay指令,从0x0000地址开始放音 do { isd_play();            //发送放音指令 delay(20); while(ISD_INT==1)         //等待放音完毕的EOM中断信号 {;} LED=1; isd_stop();         //放音完毕,发送stop指令 
     if (ovflog=chk_isdovf())         //检查芯片是否溢出 ,如溢出则停止放音,芯片复位 break; while(AN==1)     //等待AN键再次按下 {if (STOP==0) break; if(AN==0) delayms(20); } }while(AN==0);     // AN键再次按下,播放下一段语音 } 
isd_stop(); isd_pd(); } } 注意:与ISD4002/03不同的是,由于ISD4004芯片的语音地址是16位,在发送带地址指令(如setplay,setrec,setmc)时,需要先发送两个字节的地址信息,再发送一个字节的命令字,ISD4004的程序编写与ISD4002/03的区别,仅此而已。 例如,ISD4004的setplay指令程序应为: void isd_setplay(unsigned char adl,unsigned char adh) { delayms(1); spi_send(adl);     //发送放音起始地址低位 delay(2); spi_send(adh);    //发送放音起始地址高位 delay(2); spi_send(0xe0);    //发送setplay指令字节 SS=1; }  |