#include sbit SS = P1^0; //片選 sbit SCLK = P1^1; //ISD4003時(shí)鐘 sbit MOSI = P1^2; //數(shù)據(jù)輸入 sbit MISO = P1^3; //數(shù)據(jù)輸出 sbit LED = P1^7; //指示燈 sbit ISD_INT= P3^2; //中斷 sbit AN = P1^6; //執(zhí)行 sbit STOP = P1^5; //復(fù)位 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串行發(fā)送子程序,8位數(shù)據(jù) //************************************ void spi_send(unsigned char isdx) { unsigned char isx_counter; SS=0; //ss=0,打開(kāi)spi通信端 SCLK=0; for(isx_counter=0;isx_counter<8;isx_counter++) //先發(fā)低位再發(fā)高位,依次發(fā)送。 { if ((isdx&0x01)==1) MOSI=1; else MOSI=0; isdx=isdx>>1; SCLK=1; delay(2); SCLK=0; delay(2); } } //******************************* //發(fā)送stop指令 //******************************* void isd_stop(void) { delay(10); spi_send(0x30); SS=1; delayms(50); } //******************************* //發(fā)送上電指令,并延遲50ms //******************************* void isd_pu(void) { delay(10); SS=0; spi_send(0x20); SS=1; delayms(50); } //******************************* //發(fā)送掉電指令,并延遲50ms //******************************* void isd_pd(void) { delay(10); spi_send(0x10); SS=1; delayms(50); } //******************************* //發(fā)送play指令 //******************************* void isd_play(void) { LED=0; spi_send(0xf0); SS=1; } //******************************* //發(fā)送rec指令 //******************************* void isd_rec(void) { LED=0; spi_send(0xb0); SS=1; } //******************************* //發(fā)送setplay指令 //******************************* void isd_setplay(unsigned char adl,unsigned char adh) { spi_send(adl); //發(fā)送放音起始地址低位 adh=adh|0xe0; spi_send(adh); //發(fā)送放音起始地址高位 SS=1; } //******************************* //發(fā)送setrec指令 //******************************* void isd_setrec(unsigned char adl,unsigned char adh) { spi_send(adl); //發(fā)送放音起始地址低位 adh=adh|0xa0; spi_send(adh); //發(fā)送放音起始地址高位 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; //關(guān)閉spi通信端 isd_stop(); //發(fā)送stop指令 return 1; //OVF為1,返回1 } else { SCLK=0; SS =1; //關(guān)閉spi通信端 isd_stop(); //發(fā)送stop指令 return 0; //OVF為0,返回0 } } //************************************************************************ //主程序 //功能:1.錄音時(shí),按住AN鍵,LED點(diǎn)亮開(kāi)始錄音,松開(kāi)AN即可停止錄音 // 再次按下AN鍵,LED點(diǎn)亮開(kāi)始錄第二段音,依次類(lèi)推,直到芯片溢出。 // 按stop鍵芯片復(fù)位 // 2.放音時(shí),按一下AN鍵,即播放一段語(yǔ)音。 按stop鍵芯片復(fù)位。 //************************************************************************ void main(void) {unsigned char ovflog; while(1) { P0=P1=P2=P3=0xff; //初始化 while (AN==1) //等待AN鍵按下 { if (AN==0) //按鍵防抖動(dòng) {delayms(20);} } isd_pu(); //AN鍵按下,ISD上電并延遲50ms isd_pd(); isd_pu(); if (PR==1) //如果PR=1則轉(zhuǎn)入錄音部分 { delayms(500); //延遲錄音 isd_setrec(0x00,0x00); //發(fā)送0x0000h地址的setplay指令 do { isd_rec(); //發(fā)送rec指令 while(AN==0) //等待錄音完畢 {if (ISD_INT==0) //如果芯片溢出,進(jìn)行LED閃爍提示, isd_overflow(); //如果取消錄音(松開(kāi)AN鍵)則停止錄音,芯片復(fù)位 } if (ISD_INT==0) break; LED=1; //錄音完畢,LED熄滅 isd_stop(); //發(fā)送停止命令 while(AN==1) //如果AN再次按下,開(kāi)始錄制下一段語(yǔ)音 {if(STOP==0) //如果按下STOP按鍵,則芯片復(fù)位 break; if (AN==0) delayms(500); } }while(AN==0); } else //如果PR==0則轉(zhuǎn)入放音部分 { while(AN==0){;} isd_setplay(0x00,0x00); //發(fā)送setplay指令,從0x0000地址開(kāi)始放音 do { isd_play(); //發(fā)送放音指令 delay(20); while(ISD_INT==1) //等待放音完畢的EOM中斷信號(hào) {;} LED=1; isd_stop(); //放音完畢,發(fā)送stop指令 if (ovflog=chk_isdovf()) //檢查芯片是否溢出 ,如溢出則停止放音,芯片復(fù)位 break; while(AN==1) //等待AN鍵再次按下 {if (STOP==0) break; if(AN==0) delayms(20); } }while(AN==0); // AN鍵再次按下,播放下一段語(yǔ)音 } isd_stop(); isd_pd(); } } 注意:與ISD4002/03不同的是,由于ISD4004芯片的語(yǔ)音地址是16位,在發(fā)送帶地址指令(如setplay,setrec,setmc)時(shí),需要先發(fā)送兩個(gè)字節(jié)的地址信息,再發(fā)送一個(gè)字節(jié)的命令字,ISD4004的程序編寫(xiě)與ISD4002/03的區(qū)別,僅此而已。 例如,ISD4004的setplay指令程序應(yīng)為: void isd_setplay(unsigned char adl,unsigned char adh) { delayms(1); spi_send(adl); //發(fā)送放音起始地址低位 delay(2); spi_send(adh); //發(fā)送放音起始地址高位 delay(2); spi_send(0xe0); //發(fā)送setplay指令字節(jié) SS=1; } |
聯(lián)系客服