////////////////////////////////////////////////////////////////////
/////////======基于51单片机的ISD4004多段语音录放实验=======/////////
/////////==================== isd.c ===================//////////
///////// 控制IC: AT89C51/52,STC89C51/52RC //////////
///////// 系统晶振:22.1184MHz //////////
///////// 程序编写:东冬(自然风) //////////
///////// 调试时间:2009/02/13 //////////
///////// 版本: ISD4004_1.0V //////////
////////////////////////////////////////////////////////////////////
/*操作说明:1、按住K1键开始录音,放开K1键结束录音;再按住K1键,开始录第二段;以此类推;
2、按一下K2键,开始放音,等该段放音结束,继续等待;再按下K2键,放第二段,以此类推
PS:每一段录音长度要手动设置,不能自主控制录音长度(以待后改)*/
#include "STC89C52RC.H"
//#include
#include
#include "MyType.h"
//=======分段录音首地址定义======================
#define ISD_ADDS1 0x0000 //录音存放地址1
#define ISD_ADDS2 0x0100 //录音存放地址2
#define ISD_ADDS3 0x0200 //录音存放地址3
#define ISD_ADDS4 0x0300 //录音存放地址4
#define ISD_ADDS5 0x0400 //录音存放地址5
//========ISD4004指令定义========================
#define POWER_UP 0x20 //上电指令
#define SET_PLAY 0xE0 //指定放音指令
#define PLAY 0xF0 //当前放音指令
#define SET_REC 0xA0 //指定录音指令
#define REC 0xB0 //当前录音指令
#define SET_MC 0xE1 //指定快进指令
#define MC 0xF1 //快进执行指令
#define STOP 0x30 //停止当前操作
#define STOP_WRDN 0xF1 //停止当前操作并掉电
#define RINT 0x30 //读状态:OVF和EOM
//=========ISD4004--c51接口定义=================
sbit ISD_SS = P0^0; //片选
sbit ISD_MOSI = P0^1; //数据输入
sbit ISD_SCLK = P0^2; //ISD4004 时钟
sbit ISD_INT = P3^3; //溢出中断
sbit ISD_RAC = P3^2; //行地址时钟
sbit ISD_MISO = P3^6; //数据输出
//==========按键定义==========================
sbit K1 = P1^0 ; //录音键
sbit K2 = P1^1; //放音键
//==========BEEP开关定义======================
#define Beep_ON (P0&=0x7f) //蜂鸣器开
#define Beep_OFF (P0|=0x80) //蜂鸣器关
//==========ISD4004函数定义===================
void ISD_SPI_Send8( uchar isdx8 ); //spi 串行发送子程序,8位数据,从低到高
void ISD_SPI_Send16( uint isdx16 ); //spi 串行发送子程序,16位数据.从低到高
uint ISD_SPI_Radd(void); //读取标行地址
void ISD_Stop(void); //发送 stop 指令
void ISD_PowerUp(void); //发送上电指令,并延迟 50ms
void ISD_PowerDown(void); //发送掉电指令,并延迟 50ms
void ISD_Play(void); //发送放音指令,并延迟 50ms
void ISD_SetPlay(uint add); //发送指定放音指令,并延迟 50ms
void ISD_Rec(void); //发送录音指令,并延迟 50ms
void ISD_SetRec(uint add); //发送指定录音指令,并延迟 50ms
uchar ISD_Chk_Isdovf(void);
void PLAY_now(uchar add_sect); //按指定地址开始放音
void REC_now(uchar add_sect); //按指定地址开始录音
//========延时函数===========================
void Delay1Ms(uchar t); //延时t*1毫秒
void Delay();
////////////////////////////////////////////////////////////////////////
// 程序开始 //
////////////////////////////////////////////////////////////////////////
/*******************************主程序*********************************/
main ()
{
uchar i,j;
while (1)
{
//=========================K1录音键================================
if(K1==0) //K1键按下。录音
{
REC_now(i++); //录第一段
if(i>5) i = 0;
while(K1==0) //等待录音完毕
{
if (ISD_INT==0) //如果芯片OVF溢出,进行 蜂鸣器 提示,如果取消录音(松开 AN 键)则停止录音,芯片复 位
{
while(K1==0)
{
Beep_ON;
Delay1Ms(250);
Beep_OFF;
Delay1Ms(250);
}
}
}
ISD_Stop(); //发送停止命令
ISD_PowerDown();
}
//============================K2放音键================================
if(K2==0)
{
PLAY_now(j++); //放第一段
if(j>5) j = 0;
while(ISD_INT==1); //等待一段放音完毕的 EOM 中断信号
ISD_Stop(); //放音完毕,发送 stop 指令
ISD_PowerDown();
}
}
}
/******************************************************************
名称:PLAY_now(uchar add_sect)
功能:按指定地址段开始播放
指令:
调用:无
返回:无
/*****************************************************************/
void PLAY_now(uchar add_sect)
{
ISD_PowerUp(); //ISD 上电
Delay1Ms(50);
switch (add_sect) //发送 setplay 指令,从 0x0000 地址开始放
{
case 1: ISD_SetPlay(ISD_ADDS1);break; //发送地址的 SetRec 指令
case 2: ISD_SetPlay(ISD_ADDS2);break; //发送地址的 SetRec 指令
case 3: ISD_SetPlay(ISD_ADDS3);break; //发送地址的 SetRec 指令
case 4: ISD_SetPlay(ISD_ADDS4);break; //发送地址的 SetRec 指令
case 5: ISD_SetPlay(ISD_ADDS5);break; //发送地址的 SetRec 指令
//case 6:……
}
ISD_Play(); //发送放音指令
}
/******************************************************************
名称:REC_now(uchar add_sect)
功能:按指定地址段开始录音
指令:
调用:无
返回:无
/******************************************************************/
void REC_now(uchar add_sect)
{
ISD_PowerUp(); //ISD 上电
Delay1Ms(50); //延迟录音
ISD_PowerUp(); //ISD 上电
Delay1Ms(100); //延迟录音
switch (add_sect)
{
case 1: ISD_SetRec(ISD_ADDS1);break; //发送地址的 SetRec 指令
case 2: ISD_SetRec(ISD_ADDS2);break; //发送地址的 SetRec 指令
case 3: ISD_SetRec(ISD_ADDS3);break; //发送地址的 SetRec 指令
case 4: ISD_SetRec(ISD_ADDS4);break; //发送地址的 SetRec 指令
case 5: ISD_SetRec(ISD_ADDS5);break; //发送地址的 SetRec 指令
//case 6:……
}
ISD_Rec(); //发送 rec 指令
}
/******************************************************************
名称:ISD_SPI_Send8(uchar isdx)
功能:spi 串行发送子程序,8 位数据
指令:
调用:无
返回:无
/******************************************************************/
void ISD_SPI_Send8( uchar isdx8 )
{
uchar i;
ISD_SS = 0; //选中ISD4004
ISD_SCLK = 0;
for(i=0;i<8;i++) //先发低位再发高位,依次发送。
{
if ((isdx8 & 0x01) == 1) //发送最低位
ISD_MOSI = 1;
else
ISD_MOSI = 0;
isdx8 >>= 1; //右移一位
ISD_SCLK = 1; //时钟下降沿发送
ISD_SCLK = 0;
}
}
/******************************************************************
名称:ISD_SPI_Send16(uint isdx16)
功能:spi 串行发送子程序,16位数据
指令:
调用:无
返回:无
/******************************************************************/
void ISD_SPI_Send16( uint isdx16 )
{
uchar i;
ISD_SS = 0; //选中ISD4004
ISD_SCLK = 0;
for(i=0;i<16;i++) //先发低位再发高位,依次发送。
{
if ((isdx16&0x0001)==1) //发送最低位
ISD_MOSI = 1;
else
ISD_MOSI = 0;
isdx16 = isdx16 >> 1; //右移一位
ISD_SCLK=1; //时钟下降沿发送
ISD_SCLK=0;
}
}
/******************************************************************
名称:ISD_SPI_Radd(void)
功能:读取16位行地址
指令:
调用:无
返回:无
/******************************************************************/
uint ISD_SPI_Radd(void)
{
uchar i;
uint addsig;
ISD_SS = 0; //选中ISD4004
ISD_SCLK = 0;
//==============读16位地址================
for(i=0;i<16;i++) //读行地址
{
ISD_SCLK = 1; //时钟下降沿数据移出ISD
ISD_SCLK = 0;
if (ISD_MISO == 1)
addsig |= 0x8000;
if (i<15) addsig >>= 1; //最先读出的是地址的低位,所以要左移,最后一次地址不用左移,否则地址溢出
}
ISD_Stop(); //发送 stop 指令
ISD_SS = 1; //关闭 spi 通信端
return addsig; //返回地址值
}
/******************************************************************
名称:ISD_Stop(void)
功能:发送 stop 指令
指令:ISD_SPI_Send8(uchar isdx8);
调用:无
返回:无
/******************************************************************/
void ISD_Stop(void)
{
//ISD_SS = 0;
ISD_SPI_Send8(STOP);
ISD_SS = 1; //关闭片选
}
/******************************************************************
名称:ISD_PowerUp(void)
功能:发送上电指令,并延迟 50ms
指令:ISD_SPI_Send8(uchar isdx8);
调用:无
返回:无
/******************************************************************/
void ISD_PowerUp(void)
{
ISD_SS = 0; //选中ISD4004
ISD_SPI_Send8(POWER_UP);
ISD_SS = 1;
}
/******************************************************************
名称:ISD_PowerDown(void)
功能:发送掉电指令,并延迟 50ms
指令:ISD_SPI_Send8(uchar isdx8);
调用:无
返回:无
/******************************************************************/
void ISD_PowerDown(void)
{
ISD_SS = 0;
ISD_SPI_Send8(STOP_WRDN);
ISD_SS = 1;
}
/******************************************************************
名称:ISD_Play(void)
功能:发送play指令,并延迟 50ms
指令:ISD_SPI_Send8(uchar isdx8);
调用:无
返回:无
/******************************************************************/
void ISD_Play(void)
{
ISD_SS = 0;
ISD_SPI_Send8(PLAY);
ISD_SS = 1;
}
/******************************************************************
名称:ISD_Rec(void)
功能:发送rec录音指令,并延迟 50ms
指令:ISD_SPI_Send8(uchar isdx8);
调用:无
返回:无
/******************************************************************/
void ISD_Rec(void)
{
ISD_SS = 0;
ISD_SPI_Send8(REC);
ISD_SS = 1;
}
/******************************************************************
名称:ISD_SetPlay(uint add)
功能:发送setplay指令,并延迟 50ms
指令:ISD_SPI_Send8(uchar isdx8);
ISD_SPI_Send16(uint isdx16);
调用:无
返回:无
/******************************************************************/
void ISD_SetPlay(uint add)
{
Delay1Ms(1);
ISD_SPI_Send16(add); //发送放音起始地址
ISD_SPI_Send8(SET_PLAY); //发送 setplay 指令字节
ISD_SS = 1;
}
/******************************************************************
名称:ISD_SetRec(uint add)
功能:发送setrec指令,并延迟 50ms
指令:ISD_SPI_Send8(uchar isdx8);
ISD_SPI_Send16(uint isdx16);
调用:无
返回:无
/******************************************************************/
void ISD_SetRec(uint add)
{
Delay1Ms(1);
ISD_SPI_Send16(add); //发送录音起始地址
ISD_SPI_Send8(SET_REC); //发送 setrec 指令字节
ISD_SS = 1;
}
//************************************
//检查芯片是否溢出(读 OVF,并返回 OVF 值)
//************************************
/*uchar ISD_Chk_Isdovf(void)
{
ISD_SS=0;
ISD_SCLK=0;
ISD_SCLK=1;
ISD_SCLK=0;
if (ISD_MISO==1)
{
ISD_SCLK=0;
ISD_SS =1; //关闭 spi 通信端
ISD_Stop(); //发送 stop 指令
return 1; //OVF 为 1,返回 1
}
else
{
ISD_SCLK=0;
ISD_SS =1; //关闭 spi 通信端
ISD_Stop(); //发送 stop 指令
return 0; //OVF 为 0,返回 0
}
}*/
/*=========================================================================
名称: void Delay1Ms(uchar t);
功能:延时0.1ms
参数:t,最大255
调用: 无
返回:无
=========================================================================*/
void Delay1Ms(uchar t)
{
uchar i;
for (;t>0;t--)
{
for (i=0;i<150;i++)
{
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
}
}
}
//========================================
void Delay()
{
uchar i;
uint d=5000;
while (d--)
{
i=255;
while (i--);
}
}
我来帮你搞定,其实和简单的。