ISD4004的SPI(串行外设接口)

ISD4004的SPI(串行外设接口),第1张

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 端上升沿开始执行。 用户不必知道信息的确切地址,就能快进跳过一条信息。信息快进只用于放音模式。放音速度是正

常的160 倍,遇到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(存贮器末尾)时,录音停止。

 ISD4002/4003/4004芯片参数表 型号 存储时间

(秒) 可分

段数 信息分辩

率(毫秒) 采样频

率(HZ) 滤波器

带宽(HZ) 控制码+地址位 ISD4002-120 120 600 200 8.0K 3.4K 5+11 ISD4002-180 180 600 300 5.3k 2.3k 5+11 ISD4002-240 240 600 400 4.0k 1.7k 5+11 ISD4003-04 240 1200 200 8.0K 3.4K 5+11 ISD4003-06 360 1200 300 5.3K 2.3K 5+11 ISD4003-08 480 1200 400 4.0K 1.7K 5+11 ISD4004-08 480 2400 200 8.0K 3.4K 8+16 ISD4004-16 960 2400 400 4.0K 1.7K 8+16 以上芯片由ISD3340K编程拷贝机编程、拷贝。 ************ // 主程序

//

// 功能:1.录音时,按住AN键,LED点亮开始录音,松开AN即可停止录音

// 再次按下AN键,LED点亮开始录第二段音早谈,依次类推,直到芯片溢出。

// 按stop键芯片复位

// 2.放音虚桥时,按一下AN键,即播放一段语音。 按stop键芯片复位。

//************************************************************************

#include <reg52.h>

sbit SS =P1^0//片选

sbit MOSI=P1^1//数据输入

sbit MISO=P1^2//数据输出

sbit SCLK=P1^3//ISD4004时钟

sbit INT =P1^4//中断

sbit LED =P1^7//指示灯

sbit LED1=P1^6//指示灯:亮是录音/不亮是放音

sbit PR =P3^3//录音和放音选择开关

sbit STOP=P3^4//复位

sbit AN =P3^5//执行

void delay(unsigned int time) //延迟n微秒

{

while(time!=0)

{

time--

}

}

void delayms(unsigned int time) //延迟n毫秒

{

TMOD=0x01

for(timetime>0time--)

{

TH0=0xfc

TL0=0x18

TR0=1

while(TF0!=1)

{}

TF0=0

TR0=0

}

}

void isd_send(unsigned char isdx)//spi串行发送子程序,8位数据

{

unsigned char isx_counter

SS=0//ss=0,打开spi通信端

SCLK=0

for(isx_counter=0isx_counter<8isx_counter++)//先发低位再发高位,依次发送。

{

if((isdx&0x01)==1)

MOSI=1

else

MOSI=0

isdx=isdx>>1

SCLK=1

delay(2)

SCLK=0

delay(2)

}

}

void isd_stop()//stop指令(停止当前 *** 作)

{

delay(10)

isd_send(0x30)

SS=1

delayms(50)

}

void isd_powerup()//发送上电指令

{

delay(10)

SS=0

isd_send(0x20)

SS=1

delayms(50)

}

void isd_stopwrdn()//发送掉电指令

{

delay(10)

isd_send(0x10)

SS=1

delayms(50)

}

void isd_play()//发送play指令

{

LED=0

isd_send(0xf0)

SS=1

}

void isd_rec()//发送rec指令

{

LED=0

isd_send(0xb0)

SS=1

}

void isd_setplay(unsigned char adl,unsigned char adh)//发送setplay指令

{

delayms(1)

isd_send(adl)//发送放音起始地址低位

delay(2)

isd_send(adh)//发送放音起始地址高位

delay(2)

isd_send(0xe0)//发送setplay指令字节

SS=1

}

void isd_setrec(unsigned char adl,unsigned char adh)//发送setrec指令

{

delayms(1)

isd_send(adl)//发送放音起始地址低位

delay(2)

isd_send(adh)//发送放音起始地址高位

delay(2)

isd_send(0xa0)//发送setplay指令字节

SS=1

}

void isd_overflow()//芯片溢出,LED闪烁提醒停止录音

{

while(AN==0)

{

LED=1

delayms(300)

LED=0

delayms(300)

}

}

unsigned char chk_isdovf()//检查芯片是否溢出(读OVF,并返回OVF值)

{

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

}

}

void main(void)

{

unsigned char ovflog

while(1)

{

if(PR==0) {delayms(8)LED1=~LED1while(PR==0)}

if(LED1==0)//如果PR=0则转入录音部分

{

if(AN==0)

{

isd_powerup()//AN键按下,ISD上电并延迟50ms

isd_stopwrdn()

isd_powerup()

LED1=0//表示录音模式

delayms(500)//延迟500ms录音

isd_setrec(0x00,0x00)//发送0x0000h地址的setplay指令

do

{

isd_rec()//发送rec指令

while(AN==0) //等待录音完毕

{

if(INT==0) //如果芯片溢出,进行LED闪烁提示,

isd_overflow()//如果取消录音(松开AN键)则停止录音,芯片复位

}

if(INT==0)

break

LED=1//录音完毕,LED熄灭

isd_stop()//发送停止命令

while(AN==1) //如果AN再次按下,开始录制下一段语音

{

if(isd_stop==0) //如果按下STOP按键,则芯片复位

break

if(AN==0)

delayms(500)

}

}

while(AN==0)

}

}

if(LED1==1)//如果PR=0则转入放音部分 //如果PR==1则转入放音部分

{

if(AN==0)

{

isd_powerup()//AN键按下,ISD上电并延迟50ms

isd_stopwrdn()

isd_powerup()

LED1=1//表示录音模式

while(AN==0)

{}

isd_setplay(0x00,0x00)//发送setplay指令,从0x0000地址开始放音

do

{

isd_play()//发送放音指令

delay(20)

while(INT==1) //等待放音完毕的EOM中断信号

{}

LED=1

isd_stop()//放音完毕,发送stop指令

if (ovflog=chk_isdovf()) //检查芯片是否溢出 ,如溢出则停止放音,芯片复位

break

while(AN==1) //等待AN键再次按下

{

if(isd_stop==0)

break

if(AN==0)

delayms(20)

}

}

while(AN==0)// AN键再次按下,播放下一段语音

// isd_stop()

// isd_stopwrdn()

}

}

}

//*****************************************************

// ISD4002-89c51开发板演示例程 C51版本 *

// *

//*****************************************************

#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(timetime>0time--)

{

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=0isx_counter<8isx_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

}*/

ISD4000系列的芯片没有删除指令,只能将原来的语音用静音覆盖掉,如果放音时需要跳过,你可以每并坦宴段语音使用指定地址放音,你说的数组,无非是定义语音芯绝银片信知每段的地址,放音时调用即可


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12529804.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-26
下一篇 2023-05-26

发表评论

登录后才能评论

评论列表(0条)

保存