标题：ISD4000系列2-16min语音录放芯片
概述
ISD4000系列语音芯片是美国ISD公司生产的2.7V~3.3V单电源单片语音录放电路。
ISD4000系列语音芯片采用多电平直接模拟量存储技术。每个取样值直接存储在片内闪存中，因此能够非常真实、自然地再现语音、音乐、音调和效果声，避免了一般固体录音电路因量化和压缩造成的量化噪声和“金属声”。取样频率可分为4.0kHz、5.3kHz、6.4kHz、8.0kHz，取样频率越低，录音时间越长，而音质有所下降，片内信息存于闪存中，可在断电情况下保存100年（典型值），可反复录音10万次。
ISD4000系列语音芯片有ISD4002、ISD4003、ISD4004这三个系列，共16中型号，不同型号的引脚功能和应用电路相同，只是录音时间等参数有些差异，具体区别如下表所示。
型            号录音时间（min）输入取样排列    （kHz）典型带宽（kHz）最大段数最小段长（ms）外部钟频（kHz）ISD4002-12028.03.46002001024ISD4002-1502.56.42.7600250819.2ISD4002-18035.32.3600300682.7ISD4002-24044.01.7600400512ISD4003-04M48.03.412002001024ISD4003-05M56.42.71200250819.2ISD4003-06M65.32.31200300682.7ISD4003-08M84.01.71200400512ISD4004-08M88.03.424002001024ISD4004-10M106.42.72400250819.2ISD4004-12M125.32.32400300682.7ISD4004-16M164.01.72400400512
芯片封装
ISD4000系列语音芯片有DIP/SOIC、TSOP等封装形式，如下图。
  ISD4000芯片封装
芯片引脚描述
电源:(VCCA,VCCD) ：为使噪声最小,芯片的模拟和数字电路使用不同的电源总线,并且分别引到外封装的不同管脚上,模拟和数字电源端最好分别走线,尽可能在靠近供电端处相连,而去耦电容应尽量靠近器件。 　　
地线(VSSA,VSSD) ：芯片内部的模拟和数字电路也使用不同的地线。 　　
同相模拟输入(ANA IN+)：这是录音信号的同相输入端。输入放大器可用单端或差分驱动。单端输入时,信号由耦合电容输入,最大幅度为峰峰值32mV,耦合电容和本端的3KΩ电阻输入阻抗决定了芯片频带的低端截止频率。差分驱动时,信号最大幅度为峰峰值16mV，为ISD33000 系列相同。 　　
反相模拟输入(ANA IN-) ：差分驱动时,这是录音信号的反相输入端。信号通过耦合电容输入,最大幅度为峰峰值16mV 　　
音频输出(AUD OUT) ：提供音频输出,可驱动5KΩ的负载。 　　
片选(SS)： 此端为低,即向该ISD4004 芯片发送指令，两条指令之间为高电平。 　　
串行输入(MOSI) ：此端为串行输入端，主控制器应在串行时钟上升沿之前半个周期将数据放到本端,供ISD 输入。 　　
串行输出(MISO) ：ISD 的串行输出端。ISD 未选中时,本端呈高阻态。 　　
串行时钟(SCLK) ： ISD 的时钟输入端,由主控制器产生,用于同步MOSI 和MISO 的数据传输。数据在SCLK上升沿锁存到ISD,在下降沿移出ISD。 　　
中断(/INT) ：本端为漏极开路输出。ISD 在任何操作(包括快进)中检测到EOM 或OVF 时,本端变低并保持。中断状态在下一个SPI 周期开始时清除。中断状态也可用RINT 指令读取。OVF 标志----指示ISD的录、放操作已到达存储器的未尾。EOM 标志----只在放音中检测到内部的EOM 标志时,此状态位才置1。 　　
行地址时钟(RAC)：漏极开路输出。每个RAC 周期表示ISD 存储器的操作进行了一行(ISD4004 系列中的 　　存贮器共2400 行)。该信号175ms 保持高电平,低电平为25ms。快进模式下,RAC 的218.75μs 是高电平,31.25μs 为低电平。该端可用于存储管理技术。 　　
外部时钟(XCLK) ：本端内部有下拉元件。芯片内部的采样时钟在出厂前已调校,误差在 +1%内。商业级芯片在整个温度和电压范围内, 频率变化在+2.25%内。工业级芯片在整个温度和电压范围内,频率变化在-6/+4%内,此时建议使用稳压电源。若要求更高精度,可从本端输入外部时钟(如前表所列)。由于内部的防混淆及平滑滤波器已设定,故上述推荐的时钟频率不应改变。输入时钟的占空比无关紧要,因内部首先进行了分频。在不外接地时钟时,此端必须接地。 　　
自动静噪(AMCAP) ：当录音信号电平下降到内部设定的某一阈值以下时,自动静噪功能使信号衰弱,这样有助于养活无信号(静音)时的噪声。通常本端对地接1mF 的电容,构成内部信号电平峰值检测电路的一部分。检出的峰值电平与内部设定的阈值作比较,决定自动静噪功能的翻转点。大信号时,自动静噪电路不衰减,静音时衰减6dB。1mF 的电容也影响自动静噪电路对信号幅度的响应速度。本端接VCCA 则禁止自动静噪。  
芯片SPI控制协议
ISD4004 工作于SPI 串行接口。SPI 协议是一个同步串行数据传输协议,协议假定微控制器的SPI 移位寄存器在SCLK 的下降沿动作，因此对ISD4004 而言，在时钟止升沿锁存MOSI 引脚的数据,在下降沿将数据送至MISO 引脚。协议的具体内容为： 　　
1.所有串行数据传输开始于SS 下降沿。 　　
2.SS 在传输期间必须保持为低电平,在两条指令之间则保持为高电平。 　　
3.数据在时钟上升沿移入,在下降沿移出。 　　
4.SS 变低,输入指令和地址后,ISD 才能开始录放操作。 　　
5.指令格式是(8 位控制码)加(16 位地址码)。 　　
6.ISD 的任何操作(含快进)如果遇到EOM 或OVF,则产生一个中断,该中断状态在下一个SPI 周期开始时被清除。 　　
7.使用"读"指令使中断状态位移出ISD 的MISO 引脚时,控制及地址数据也应同步从MOSI 端移入。因此要注意移入的数据是否与器件当前进行的操作兼容。当然,也允许在一个SPI 周期里,同时执行读状态和开始新的操作(即新移入的数据与器件当前的操作可以不兼容)。 　　
8.所有操作在运行位(RUN)置1 时开始,置0 时结束。 　　
9.所有指令都在SS 端上升沿开始执行。  
(一)信息快进用户不必知道信息的确切地址,就能快进跳过一条信息。信息快进只用于放音模式。放音速度是正 　　常的1600 倍,遇到EOM 后停止,然后内部地址计数器加1,指向下条信息的开始处。  
(二)上电顺序器件延时TPUD(8kHz 采样时,约为25 毫秒)后才能开始操作。因此,用户发完上电指令后,必须等待 　　TPUD,才能发出一条操作指令。 　　例如,从00 从处发音,应遵循如下时序: 　　1. 发POWERUP 命令; 　　2. 等待TPUD(上电延时); 　　3. 发地址值为00 的SETPLAY 命令; 　　4. 发PLAY 命令。 　　器件会从此00 地址开始放音,当出现EOM 时,立即中断,停止放音。 　　如果从00 处录音,则按以下时序: 　　1. 发POWER UP 命令; 　　2. 等待TPUD(上电延时); 　　3. 发POWER UP 命令 　　4. 等待2 倍TPUD; 　　5. 发地址值为00 的SETREC 命令; 　　6. 发REC 命令。 　　器件便从00 地址开始录音,一直到出现OVF(存贮器末尾)时,录音停止。  
芯片控制例程
#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指令
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位，在发送带地址指令（如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;
}*/