开发工具:
文件大小: 1mb
下载次数: 0
上传时间: 2014-12-03
详细说明: //***************************************************** // ISD4002-89c51开发板演示例程 C51版本 * // 作者:中青世纪 Lell * // 2008.2.27 * // * // 更多ISD4000使用心得请登陆中青世纪论坛 * // http://www.atvoc.com/bbs * // * //***************************************************** #include 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指令 delay(20); 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) delayms(20); if (STOP==0) break; if(AN==0) delayms(20); } LED=0; }while(AN==0); // AN键再次按下,播放下一段语音 } isd_stop(); isd_pd(); } } /*注意:与ISD4002/03不同的是,由于ISD4004芯片的语音地址是16位, //ISD4004芯片在发送带地址指令(如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; }*/ ///////////ISD4004语音播放部分///////////////////////////// ////当按下P3.5键时,从指定地址开始录音 /// 当按下P3.6键时,从指定地址开始放音 /// 当按下P3.7键时,停止当前的操作 /// 程序中的录放停部分已做成子函数,可以直接调用, 只需要输入录音的地址就行 // 录音地址的设定与芯片型号有关系,以ISD4004-16为例,ISD40044-16录音时间为16 // 分钟,即16*60=960S, 根据4004的资料,960秒可分为2400段,也就是10S的段数为 // 25段,即从,0000-0019H的内容为10S, ///作者:长沙致望科技电子公司 WWW.CSMCU.COM ///版本:V1.0(2008.12.1) //实验使用注意,按录音键,要切换到放音时,可按停止再放音,也可以先按一下放音键,再按一次放音键,那可 //原因:本程序在放音前,没有做停止和下电处理,感兴趣的朋友可以直接到停止部分加到放音子函数中。 #include #include #define uchar unsigned char #define uint unsigned int ////////定义放音命令,定义常量////// #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=P0^0; //LOW IS ACTIVELY sbit MOSI=P0^1; sbit MISO=P0^2; sbit SCLK=P0^3; //sbit INT=P1^2; sbit K1=P3^1; //用串口烧写程序时会用到 sbit K2=P3^2; sbit K3=P3^3; sbit LED1=P1^0; sbit LED2=P1^1; sbit LED3=P1^2; void delayms(uchar ms); uint addr;////全局变量//// 放音地址 ////////////////放音部分子程序,放音地址由ADDR决定//// void play() { uint y; SS=1; 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_(); SCLK=0; }//发送结束 SS=1;//上电结束 delayms(25); 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_(); SCLK=0; } SS=1;//上电结束 delayms(25); SS=0; //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_(); SCLK=0; } SS=1; delayms(25); 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_(); SCLK=0; } SS=1; } //////////////////////////lu音部分子程序,地址由ADDR决定///////////////////////// void rec() { 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_(); SCLK=0; }//发送结束 SS=1;//上电结束 delayms(25); 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_(); SCLK=0; }//发送结束 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_(); SCLK=0; }//发送地址结束*/ SS=1;//上电结束 delayms(25); SS=0; // 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_(); SCLK=0; } SS=1; delayms(25); 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_(); SCLK=0; } 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_(); SCLK=0; } SS=1; delayms(50); //delayms(50); } /////////////////////////////// ////////////////////////////////// void Dstop() { uchar y; SS=1; SS=0; MOSI=0;//放音 SCLK=0; for(y=0;y<8;y++) { SCLK=0; if((0x10>>y)&0x01)MOSI=1; else MOSI=0; _nop_(); _nop_(); _nop_(); SCLK=1; _nop_(); _nop_(); _nop_(); SCLK=0; } SS=1; delayms(50); //delayms(50); } //////////////////////////////////// ////////////////////////////////////void press_key() void delayms(uchar ms) // 延时子程序 { uchar j; while(ms--) { for(j =0;j<125;j++); } } //////////////////////////////// //////////////////////////////////// void main() { P1=0xFF; P2=0XFF; P3=0XFF; while(1) {if(K1==0) {delayms(10); while(K1==0); ///松手判断 LED1=0; LED2=1; LED3=1; addr=0X00;/////从0X50单元开始 delayms(500); rec(); delayms(10); //if(INT==0) // stop(); P3=0XFF; } if(K2==0) {delayms(10); while(K2==0); LED1=1; LED2=0; LED3=1; addr=0X00; delayms(500); play(); delayms(10); //addr=0x50; // play(); P3=0XFF; } if(K3==0) {delayms(10); while(K3==0); LED1=1; LED2=1; LED3=0; stop(); P3=0XFF; } } } ////当按下P3.5键时,从指定地址开始录音 /// 当按下P3.6键时,从指定地址开始放音 /// 当按下P3.7键时,停止当前的操作 /// 程序中的录放停部分已做成子函数,可以直接调用, 只需要输入录音的地址就行 // 录音地址的设定与芯片型号有关系,以ISD4004-16为例,ISD40044-16录音时间为16 // 分钟,即16*60=960S, 根据4004的资料,960秒可分为2400段,1段的时间为960/2400=0.4S,也就是1S的段数为 2.5段,如要要录5秒, 5/0.4= 12.5段=13段,从00H--0CH , #include #include #define uchar unsigned char #define uint unsigned int ////////定义放音命令,定义常量////// #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^3; //LOW IS ACTIVELY sbit MOSI=P1^2; 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); uint addr;////全局变量//// 放音地址 ////////////////放音部分子程序,放音地址由ADDR决定//// void play() { 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() { 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 press_key() void delayms(uchar ms) // 延时子程序 { uchar j; while(ms--) { for(j = 0; j < 120; j++); } } //////////////////////////////// //////////////////////////////////// void main() { P1=0xff; P2=0XFF; P3=0XFF; while(1) {if(K1==0) {delayms(10); while(K1==0); ///松手判断 LED1=0; LED2=1; addr=0X05;/////从0X05单元开始 rec(); P1=0XFF;} if(K2==0) {delayms(10); while(K2==0); LED1=1; LED2=0; addr=0X05; play(); P1=0XFF;} if(K3==0) {delayms(10); while(K3==0); LED1=1; LED2=1; stop(); P1=0XFF; } } } ...展开收缩
(系统自动生成,下载前可以参看下载内容)
下载文件列表
相关说明
- 本站资源为会员上传分享交流与学习,如有侵犯您的权益,请联系我们删除.
- 本站是交换下载平台,提供交流渠道,下载内容来自于网络,除下载问题外,其它问题请自行百度。
- 本站已设置防盗链,请勿用迅雷、QQ旋风等多线程下载软件下载资源,下载后用WinRAR最新版进行解压.
- 如果您发现内容无法下载,请稍后再次尝试;或者到消费记录里找到下载记录反馈给我们.
- 下载后发现下载的内容跟说明不相乎,请到消费记录里找到下载记录反馈给我们,经确认后退回积分.
- 如下载前有疑问,可以通过点击"提供者"的名字,查看对方的联系方式,联系对方咨询.