资源描述
///////////ISD4004语音播放部分/////////////////////////////
////当按下P3.5键时,从指定地址开始录音
/// 当按下P3.6键时,从指定地址开始放音
/// 当按下P3.7键时,停止当前的操作
/// 程序中的录放停部分已做成子函数,可以直接调用, 只需要输入录音的地址就行
// 录音地址的设定与芯片型号有关系,以ISD4004-16为例,ISD40044-16录音时间为16
// 分钟,即16*60=960S, 根据4004的资料,960秒可分为2400段,也就是1S的段数为
// 25段,即从,0000-0019H的内容为1S,
///作者:长沙致望科技电子公司 WWW.CSMCU.COM
///版本:V1.0(2008.12.1)
//实验使用注意,按录音键,要切换到放音时,可按停止再放音,也可以先按一下放音键,再按一次放音键,那可
//原因:本程序在放音前,没有做停止和下电处理,感兴趣的朋友可以直接到停止部分加到放音子函数中。
#include <reg51.h>
#include <intrins.h>
#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; }
}
}
1。两个按键:AN和STOP。
2。一个跳线选择开关P/R,选择放音/录音
3。录音状态下,按住AN键,LED灯亮起,开始录音。直到AN松开,或者芯片溢出(溢出后LED闪烁提示)
AN松开后生成一段,再次按下则开始录下一段,如此反复。按下STOP后,复位。
4。放音状态下,按下AN键,LED灯亮起,开始放音,知道该段结束,或到芯片末尾。
再次按下AN键后,放下一段,如此反复。按下STOP后,复位。
#i nclude
#define uchar unsigned char
#define uint unsigned int
sbit SS="P1"^0;
sbit SCLK="P1"^1;
sbit MOSI="P1"^2;
sbit MISO="P1"^3;
sbit LED="P2"^0;
sbit ISD_INT=P3^2;
sbit AN="P1"^6;
sbit STOP="P1"^5;
sbit PR="P1"^4;
void delay(uint time)
{
while(time!=0)
{
time--;
}
}
void delayms(uint time)
{
TMOD=0x01;
for(time;time>0;time--)
{
TH0=0xfc;
TL0=0x18;
TR0=1;
while(TF0!=1)
{;}
TF0=0;
TR0=0;
}
}
void spi_send(uchar isdx)
{
uchar isx_counter;
SS=0;
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);
}
}
void isd_stop(void)
{
delay(10);
spi_send(0x30);
SS=1;
delayms(50);
}
void isd_pu(void)
{
delay(10);
SS=0;
spi_send(0x20);
SS=1;
delayms(50);
}
void isd_pd(void)
{
delay(10);
spi_send(0x10);
SS=1;
delayms(50);
}
void isd_play(void)
{
LED=0;
spi_send(0xf0);
SS=1;
}
void isd_rec(void)
{
LED=0;
spi_send(0xb0);
SS=1;
}
void isd_setplay(uchar adl,uchar adh)
{
spi_send(adl);
adh=adh|0xe0;
spi_send(adh);
SS=1;
}
void isd_setrec(uchar adl,uchar adh)
{
spi_send(adl);
adh=adh|0xa0;
spi_send(adh);
SS=1;
}
void isd_overflow(void)
{
while(AN==0)
{
LED=1;
delayms(300);
LED=0;
delayms(300);
}
}
uchar chk_isdovf(void)
{
SS=0;
delay(2);
SCLK=0;
delay(2);
SCLK=1;
SCLK=0;
delay(2);
if(MISO==1)
{
SCLK=0;
SS=1;
isd_stop();
return 1;
}
else
{
SCLK=0;
SS=1;
isd_stop();
return 0;
}
}
void main()
{
uchar ovflog;
while(1)
{
P0=P1=P2=P3=0xff;
while(AN==1)
{
if(AN==0)
{
delayms(20);
}
}
isd_pu();
isd_pd();
isd_pu();
if(PR==1)
{
delayms(500);
isd_setrec(0x00,0x00);
do
{
isd_rec();
delay(20);
while(AN==0)
{
if(ISD_INT==0)
isd_overflow();
}
if(ISD_INT==0)
break;
LED=1;
isd_stop();
while(AN==1)
{
if(STOP==0)
break;
if(AN==0)
delayms(500);
}
}while(AN==0);
}
else
{
while(AN==0)
{;}
isd_setplay(0x00,0x00);
do
{
isd_play();
delay(20);
while(ISD_INT==1)
{;}
LED=1;
isd_stop();
if(ovflog=chk_isdovf())
break;
while(AN==1)
{
if(STOP==0)
delayms(20);
if(STOP==0)
break;
if(AN==0)
delayms(20);
}
LED=0;
}while(AN==0);
}
isd_stop();
isd_pd();
}
}
12
展开阅读全文