isd4004語音模塊全部資料,分享一下,共同學習
0.png (6.96 KB, 下載次數: 75)
下載附件
2017-12-25 18:35 上傳
ISD4004模塊和控制板的接線方法:
ISD4004模塊 51單片機系統板
VCC VCC
GND GND
SS P1.0
MOSI P1.1
MISO P1.2
SCLK P1.3
IN P1.4
RAC P1.5
LED P1.6
ISD4004模塊電路圖.JPG (132.2 KB, 下載次數: 74)
下載附件
isd4004模塊電路圖
2017-12-24 17:07 上傳
單片機源程序如下(1.錄25段,可重復查詢地址):
- /* 忠興編輯
- 經過長時間的調試,本程序已經通過驗證?
- 請親們方向使用。
- */
- /*====================================================================
- 調試要求:
- 1.MCU:AT89S52芯片
- 2.晶振:12MHz
- 使用說明:
- AN(本店的控制板上該按鍵標號為UP)為放音鍵
- SET_KEY(本店控制板上標號為SET)為錄音鍵。
- 開機時只允許錄音鍵使用,放音鍵不能使用。
- 允許放音后,錄音鍵就失效。
- 錄音操作:按住SET鍵就進入錄音模式,放開就停止錄音
- 再按就再進入錄音模式,如此循環操作,將所
- 有的語言分段一次性錄完。本程序最多錄25段,
- 25段的時間不超過芯片的總時間
- 放音操作:錄好因后,在不斷電或不復位單片機的情況下
- 按AN鍵就放音,每按一次放一段。
- 錄放音時操作時,1602會將該段語音的開始和結束地址進行顯示。
- 本程序的功能就在這里,可以清晰的知道每段語音的起始地址,
- 并且在不斷電或不復位單片機的情況下可進行循環查詢地址。
- 4004系列語音的地址很不好找,相信有些親們應該深有體會,
- 本人從網上找了很多通過ISP通信讀取地址的程序經過驗證都失敗了,
- 可是很多時候又需要知道錄音的地址,經過思考,終于想出了自己的方法
- 來知道錄音地址。下面介紹一下。
- 本程序計算地址的原理:(以ISD4004-8為例進行介紹)
- 4004-08的錄音時間是8分鐘,也就是480秒
- 4004-08的開始地址是A0,結束地址是A15,這樣共有A15-A0=2421個地址
- 約等于2400個地址,也就是說時間480秒,地址是2400個,根據這個推論:
- 錄音1秒,就走了2400/480=5個地址,本程序的編程原理就是由錄音的時間
- 來推算語音的起始地址和結束地址,經過驗證,這樣的編程原理是可行的。
- 本程序只適合知道自己錄音的起始和結束地址,
- 對芯片原有的語音地址的查找不適合。
- 主意:錄音時,按下錄音鍵要等錄音指示燈亮了才開始錄音
- 錄音完后松開錄音鍵顯示的地址才是本段語音的地址
- 放音時,要等本段語音播放完后顯示的地址才是本段的地址0
- ====================================================================*/
- #include <reg52.h>
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- //錄音和放音鍵IO口定義:
- sbit AN=P2^6;//放音鍵控制接口
- sbit set_key=P2^7;//錄音鍵控制口
- // ISD4004控制口定義:
- sbit SS =P1^0; //4004片選
- sbit MOSI=P1^1; //4004數據輸入
- sbit MISO=P1^2; //4004數據輸出
- sbit SCLK=P1^3; //ISD4004時鐘
- sbit INT =P1^4; //4004中斷
- sbit STOP=P3^4; //4004復位
- sbit LED1 =P1^6; //錄音指示燈
- //===============================LCD1602接口定義=====================
- /*注意,P2.2到P2.4需要接上拉電阻
- ---------------------------------------------------
- =============================================================*/
- #define LCM_Data P0 //LCD1602數據接口
- sbit LCM_RW = P2^3; //讀寫控制輸入端,LCD1602的第五腳
- sbit LCM_RS = P2^4; //寄存器選擇輸入端,LCD1602的第四腳
- sbit LCM_E = P2^2; //使能信號輸入端,LCD1602的第6腳
- //***************函數聲明************************************************
- void WriteDataLCM(uchar WDLCM);//LCD模塊寫數據
- void WriteCommandLCM(uchar WCLCM,BuysC); //LCD模塊寫指令
- uchar ReadStatusLCM(void);//讀LCD模塊的忙標
- void DisplayOneChar(uchar X,uchar Y,uchar ASCII);//在第X+1行的第Y+1位置顯示一個字符
- void LCMInit(void);
- void DelayUs(uint us); //微妙延時程序
- void DelayMs(uint Ms);//毫秒延時程序
- void init_t0();//定時器0初始化函數
- void setkey_treat(void);//錄音鍵處理程序
- void upkey_treat(void);//播放鍵處理程序
- void display();//顯示處理程序
- void isd_setrec(uchar adl,uchar adh);//發送setrec指令
- void isd_rec();//發送rec指令
- void isd_stop();//stop指令(停止當前操作)
- void isd_powerup();//發送上電指令
- void isd_stopwrdn();//發送掉電指令
- void isd_send(uchar isdx);//spi串行發送子程序,8位數據
- void isd_setplay(uchar adl,uchar adh);
- void isd_play();
- //程序中的一些常量定義
- uint time_total,st_add,end_add=0;
- uint adds[25];//25段語音的起始地址暫存
- uint adde[25];//25段語音的結束地址暫時
- uchar t0_crycle,count,count_flag,flag2,flag3,flag4;
- uchar second_count=170,msecond_count=0;
- //second_count為芯片錄音的起始地址,起始地址本來是A0,也就是160,
- //我們從170開始錄音吧。
- #define Busy 0x80 //用于檢測LCM狀態字中的Busy標識
- /*===========================================================================
- 主程序
- =============================================================================*/
- void main(void)
- {
- LED1=0;//滅錄音指示燈
- flag3=0;
- flag4=0;
- time_total=340;//錄音地址從170開始,對應的單片機開始計時的時間就是340*0.1秒
- adds[0]=170;
- count=0;
- LCMInit(); //1602初始化
- init_t0();//定時器初始化
- DisplayOneChar( 0,5,'I'); //開機時顯示000 ISD4004-X
- DisplayOneChar( 0,6,'S');
- DisplayOneChar( 0,7,'D');
- DisplayOneChar( 0,8,'4');
- DisplayOneChar( 0,9,'0');
- DisplayOneChar( 0,10,'0');
- DisplayOneChar( 0,11,'4');
- DisplayOneChar( 0,12,'-');
- DisplayOneChar( 0,13,'X');
- while(1)
- {
- display();//顯示處理
- upkey_treat();//放音鍵處理
- setkey_treat();//錄音鍵處理
- }
- }
- //*******************************************
- //錄音鍵處理程序
- //從指定地址開始錄音的程序就是在這段里面
- void setkey_treat(void)
- {
- set_key=1;//置IO口為1,準備讀入數據
- DelayUs(1);
- if(set_key==0)
- {
- if(flag3==0)//錄音鍵和放音鍵互鎖,錄音好后,禁止再次錄音。如果要再次錄音,那就要復位單片機,重新開始錄音
- {
- if(count==0)//判斷是否為上電或復位以來第一次按錄音鍵
- {
- st_add=170;
- }
- else
- {
- st_add=end_add+3;
- }//每段語言間隔3個地址
- adds[count]=st_add;//每段語音的起始地址暫時
- if(count>=25)//判斷語音段數時候超過25段,因為單片機內存的關系?
- //本程序只錄音25段,如果要錄更多的語音,改為不可查詢的即可
- {//如果超過25段,則覆蓋之前的語音,從新開始錄音
- count=0;
- st_add=170;
- time_total=340;
- }
- isd_powerup(); //AN鍵按下,ISD上電并延遲50ms
- isd_stopwrdn();
- isd_powerup();
- LED1=1;//錄音指示燈亮,表示錄音模式
- isd_setrec(st_add&0x00ff,st_add>>8); //從指定的地址
- if(INT==1)// 判定芯片有沒有溢出
- {
- isd_rec(); //發送錄音指令
- }
- time_total=st_add*2;//計時初始值計算
- TR0=1;//開計時器
- while(set_key==0);//等待本次錄音結束
- TR0=0;//錄音結束后停止計時
- isd_stop(); //發送4004停止命令
- end_add=time_total/2+2;//計算語音的結束地址
- adde[count]=end_add;//本段語音結束地址暫存
- LED1=0; //錄音完畢,LED熄滅
- count++;//錄音段數自加
- count_flag=count;//錄音段數寄存
- flag2=1;
- flag4=1;//解鎖放音鍵
- }
- }
- }
- //=================================================
- //放音機處理程序
- //從指定地址開始放本段語音就是這段程序
- void upkey_treat(void)
- {
- uchar ovflog;
- AN=1;//準備讀入數據
- DelayUs(1);
- if(AN==0)//判斷放音鍵是否動作
- {
- if(flag4==1)//互鎖錄音鍵
- {
- if(flag2==1)//判斷是否為錄音好后的第一次放音
- {
- count=0;//從第0段開始播放
- }
- isd_powerup(); //AN鍵按下,ISD上電并延遲50ms
- isd_stopwrdn();
- isd_powerup();
- st_add=adds[count];//送當前語音的起始地址
- isd_setplay(st_add&0x00ff,st_add>>8); //發送setplay指令,從指定地址開始放音
- isd_play(); //發送放音指令
- DelayUs(20);
- while(INT==1); //等待放音完畢的EOM中斷信號
- isd_stop(); //放音完畢,發送stop指令
- while(AN==0); //
- isd_stop();
- count++;//語音段數自加
- flag2=0;
- flag3=1;
- if(count>=count_flag)//如果播放到最后一段后還按加鍵,則從第一段重新播放
- {
- count=0;
- }
-
- }
- }
- }
- //************************************************?
- //發送rec指令
- void isd_rec()
- {
- isd_send(0xb0);
- SS=1;
- }
- //****************************************
- //發送setrec指令
- void isd_setrec(unsigned char adl,unsigned char adh)
- {
- DelayMs(1);
- isd_send(adl); //發送放音起始地址低位
- DelayUs(2);
- isd_send(adh); //發送放音起始地址高位
- DelayUs(2);
- isd_send(0xa0); //發送setplay指令字節
- SS=1;
- }
- //=============================================================================
- //**********************************************
- //定時器0中斷程序
- void timer0() interrupt 1
- {
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- t0_crycle++;
- if(t0_crycle==2)// 0.1秒
- {
- t0_crycle=0;
- time_total++;
- msecond_count++;
- if(msecond_count==10)//1秒
- {
- msecond_count=0;
- second_count++;
- if(second_count==60)
- {
- second_count=0;
- }
- }
- if(time_total==4800)time_total=0;
- }
- }
- //********************************************************************************************
- //定時器0初始化函數
- void init_t0()
- {
- TMOD=0x01;//設定定時器工作方式1,定時器定時50毫秒
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- EA=1;//開總中斷
- ET0=1;//允許定時器0中斷
- t0_crycle=0;//定時器中斷次數計數單元
- }
- //******************************************
- //顯示處理程序
- void display()
- {
- uchar x;
- if(flag3==1||flag4==1)//判斷是否有錄音過或者放音過
- {
- x=count-1;
- if(x==255){x=count_flag-1;}
- }
- DisplayOneChar( 0,0,x/100+0x30); //顯示當前語音是第幾段
- DisplayOneChar( 0,1,x/10%10+0x30);
- DisplayOneChar( 0,2,x%10+0x30);
- if(flag3==0)//錄音時顯示本段語音的起始和結束地址
- {
- DisplayOneChar( 1,0,st_add/1000+0x30);//計算并顯示千位
- DisplayOneChar( 1,1,st_add/100%10+0x30);
- DisplayOneChar( 1,2,st_add/10%10+0x30);
- DisplayOneChar( 1,3,st_add%10+0x30);
- DisplayOneChar( 1,4,'-');
- DisplayOneChar( 1,5,'-');
- DisplayOneChar( 1,6,end_add/1000+0x30);
- DisplayOneChar( 1,7,end_add/100%10+0x30);
- DisplayOneChar( 1,8,end_add/10%10+0x30);
- DisplayOneChar( 1,9,end_add%10+0x30);
- }
- if(flag4==1)//放音時顯示本段語音的起始和結束地址
- {
- DisplayOneChar( 1,0,adds[x]/1000+0x30);
- DisplayOneChar( 1,1,adds[x]/100%10+0x30);
- DisplayOneChar( 1,2,adds[x]/10%10+0x30);
- DisplayOneChar( 1,3,adds[x]%10+0x30);
- DisplayOneChar( 1,4,'-');
- DisplayOneChar( 1,5,'-');
- DisplayOneChar( 1,6,adde[x]/1000+0x30);
- DisplayOneChar( 1,7,adde[x]/100%10+0x30);
- DisplayOneChar( 1,8,adde[x]/10%10+0x30);
- DisplayOneChar( 1,9,adde[x]%10+0x30);
- }
- }
- //======================================================================
- // LCM初始化
- //======================================================================
- void LCMInit(void)
- {
- LCM_Data = 0;
- WriteCommandLCM(0x38,0); //三次顯示模式設置,不檢測忙信號
- DelayMs(5);
- WriteCommandLCM(0x38,0);
- DelayMs(5);
- WriteCommandLCM(0x38,0);
- DelayMs(5);
- WriteCommandLCM(0x38,1); //顯示模式設置,開始要求每次檢測忙信號
- WriteCommandLCM(0x08,1); //關閉顯示
- WriteCommandLCM(0x01,1); //顯示清屏
- WriteCommandLCM(0x06,1); // 顯示光標移動設置
- WriteCommandLCM(0x0C,1); // 顯示開及光標設置
- DelayMs(100);
- }
- //*=====================================================================
- // 寫數據函數: E =高脈沖 RS=1 RW=0
- //======================================================================
- void WriteDataLCM(uchar WDLCM)
- {
- ReadStatusLCM(); //檢測忙
- LCM_Data = WDLCM;
- LCM_RS = 1;
- LCM_RW = 0;
- LCM_E = 0; //若晶振速度太高可以在這后加小的延時
- LCM_E = 0; //延時
- LCM_E = 1;
- }
- //*====================================================================
- // 寫指令函數: E=高脈沖 RS=0 RW=0
- //======================================================================
- void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC為0時忽略忙檢測
- {
- if (BuysC) ReadStatusLCM(); //根據需要檢測忙
- LCM_Data = WCLCM;
- LCM_RS = 0;
- LCM_RW = 0;
- LCM_E = 0;
- LCM_E = 0;
- LCM_E = 1;
- }
- //*====================================================================
- // 正常讀寫操作之前必須檢測LCD控制器狀態:E=1 RS=0 RW=1;
- // DB7: 0 LCD控制器空閑,1 LCD控制器忙。
- // 讀狀態
- //======================================================================
- unsigned char ReadStatusLCM(void)
- {
- LCM_Data = 0xFF;
- LCM_RS = 0;
- LCM_RW = 1;
- LCM_E = 0;
- LCM_E = 0;
- LCM_E = 1;
- while (LCM_Data & Busy); //檢測忙信號
- return(LCM_Data);
- }
- //======================================================================
- //功 能: 在1602 指定位置顯示一個字符:第一行位置0~15,第二行16~31
- //說 明: 第 X 行,第 y 列 注意:字符串不能長于16個字符
- //======================================================================
- void DisplayOneChar( unsigned char X, unsigned char Y, unsigned char ASCII)
- {
- X &= 0x1;
- Y &= 0xF; //限制Y不能大于15,X不能大于1
- if (X) Y |= 0x40; //當要顯示第二行時地址碼+0x40;
- Y |= 0x80; // 算出指令碼
- WriteCommandLCM(Y, 0); //這里不檢測忙信號,發送地址碼
- WriteDataLCM(ASCII);
- }
- //======================================================================
- //spi串行發送子程序,8位數據
- void isd_send(uchar isdx)
- {
- uchar 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;
- DelayUs(2);
- SCLK=0;
- DelayUs(2);
- }
- }
- //======================================================================
- //stop指令(停止當前操作)
- void isd_stop()//
- {
- DelayUs(10);
- isd_send(0x30);
- SS=1;
- DelayMs(50);
- }
- //======================================================================
- //發送上電指令
- void isd_powerup()//
- {
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
2無限段錄音程序,不可查詢,單片機源程序如下:
- /* 忠興店編輯
- 經過長時間的調試,本程序已經通過驗證?
- 請親們方向使用。
- */
- /*====================================================================
- 調試要求:
- 1.MCU:AT89S52芯片
- 2.晶振:12MHz
- 使用說明:
- SET_KEY(本店控制板上標號為SET)為錄音鍵。
- 錄音操作:按住SET鍵就進入錄音模式,放開就停止錄音
- 再按就再進入錄音模式,如此循環操作,將所
- 有的語言分段一次性錄完。
- 錄音時操作時,1602會將該段語音的開始和結束地址進行顯示。
- 主意:錄音時,按下錄音鍵要等錄音指示燈亮了才開始錄音
- 錄音完后松開錄音鍵顯示的地址才是本段語音的地址,本程序可以錄255段,
- 但是總時間不能超過8分鐘,因為本程序不可查詢語言的地址,所有每錄
- 一段語言就用筆手動記下起始和結束地址。
- ====================================================================*/
- #include <reg52.h>
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- //錄音鍵IO口定義:
- sbit set_key=P2^7;//錄音鍵控制口
- // ISD4004控制口定義:
- sbit SS =P1^0; //4004片選
- sbit MOSI=P1^1; //4004數據輸入
- sbit MISO=P1^2; //4004數據輸出
- sbit SCLK=P1^3; //ISD4004時鐘
- sbit INT =P1^4; //4004中斷
- sbit STOP=P3^4; //4004復位
- sbit LED1 =P1^5; //錄音指示燈
- //===============================LCD1602接口定義=====================
- /* 注意,P2.2到P2.4需要接上拉電阻
- ---------------------------------------------------
- =============================================================*/
- #define LCM_Data P0 //LCD1602數據接口
- sbit LCM_RW = P2^3; //讀寫控制輸入端,LCD1602的第五腳
- sbit LCM_RS = P2^4; //寄存器選擇輸入端,LCD1602的第四腳
- sbit LCM_E = P2^2; //使能信號輸入端,LCD1602的第6腳
- //***************函數聲明************************************************
- void WriteDataLCM(uchar WDLCM);//LCD模塊寫數據
- void WriteCommandLCM(uchar WCLCM,BuysC); //LCD模塊寫指令
- uchar ReadStatusLCM(void);//讀LCD模塊的忙標
- void DisplayOneChar(uchar X,uchar Y,uchar ASCII);//在第X+1行的第Y+1位置顯示一個字符
- void LCMInit(void);
- void DelayUs(uint us); //微妙延時程序
- void DelayMs(uint Ms);//毫秒延時程序
- void init_t0();//定時器0初始化函數
- void setkey_treat(void);//錄音鍵處理程序
- void display();//顯示處理程序
- void isd_setrec(uchar adl,uchar adh);//發送setrec指令
- void isd_rec();//發送rec指令
- void isd_stop();//stop指令(停止當前操作)
- void isd_powerup();//發送上電指令
- void isd_stopwrdn();//發送掉電指令
- void isd_send(uchar isdx);//spi串行發送子程序,8位數據
- //程序中的一些常量定義
- uint time_total,st_add,end_add=0;
- uchar t0_crycle,count;
- uchar second_count=170,msecond_count=0;
- //second_count為芯片錄音的起始地址,起始地址本來是A0,也就是160,
- //我們從170開始錄音吧。
- #define Busy 0x80 //用于檢測LCM狀態字中的Busy標識
- /*===========================================================================
- 主程序
- =============================================================================*/
- void main(void)
- {
- LED1=0;//滅錄音指示燈
- time_total=340;//錄音地址從170開始,對應的單片機開始計時的時間就是340*0.1秒
- count=0;
- LCMInit(); //1602初始化
- init_t0();//定時器初始化
- DisplayOneChar( 0,5,'I'); //開機時顯示000 ISD4004-X
- DisplayOneChar( 0,6,'S');
- DisplayOneChar( 0,7,'D');
- DisplayOneChar( 0,8,'4');
- DisplayOneChar( 0,9,'0');
- DisplayOneChar( 0,10,'0');
- DisplayOneChar( 0,11,'4');
- DisplayOneChar( 0,12,'-');
- DisplayOneChar( 0,13,'X');
- while(1)
- {
- display();//顯示處理
- setkey_treat();//錄音鍵處理
- }
- }
- //*******************************************
- //錄音鍵處理程序
- //從指定地址開始錄音的程序就是在這段里面
- void setkey_treat(void)
- {
- set_key=1;//置IO口為1,準備讀入數據
- DelayUs(1);
- if(set_key==0)
- {
- if(count==0)//判斷是否為上電或復位以來第一次按錄音鍵
- {
- st_add=170;
- }
- else
- {
- st_add=end_add+3;
- }//每段語言間隔3個地址
- isd_powerup(); //AN鍵按下,ISD上電并延遲50ms
- isd_stopwrdn();
- isd_powerup();
- LED1=1;//錄音指示燈亮,表示錄音模式
- isd_setrec(st_add&0x00ff,st_add>>8); //從指定的地址
- if(INT==1)// 判定芯片有沒有溢出
- {
- isd_rec(); //發送錄音指令
- }
- time_total=st_add*2;//計時初始值計算
- TR0=1;//開計時器
- while(set_key==0);//等待本次錄音結束
- TR0=0;//錄音結束后停止計時
- isd_stop(); //發送4004停止命令
- end_add=time_total/2+2;//計算語音的結束地址
- LED1=0; //錄音完畢,LED熄滅
- count++;//錄音段數自加
- }
- }
- //************************************************?
- //發送rec指令
- void isd_rec()
- {
- isd_send(0xb0);
- SS=1;
- }
- //****************************************
- //發送setrec指令
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼 所有資料51hei提供下載:
ISD4004配套資料.rar
(373.19 KB, 下載次數: 212)
2017-12-24 17:05 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|