C51语音单片机通用开发板电路图和相关程序.docx
《C51语音单片机通用开发板电路图和相关程序.docx》由会员分享,可在线阅读,更多相关《C51语音单片机通用开发板电路图和相关程序.docx(14页珍藏版)》请在冰豆网上搜索。
C51语音单片机通用开发板电路图和相关程序
89C51-ISD4000语音单片机通用开发板
本板采用国内最常用的MCS-51语言单片机89C51,与最新的ISD4000系列语音芯片结合,可供用户开发各种最新的智能型数码语音产品。
一、结构
板上已装配好:
89C51--单片机,8031内核,4K可反复擦写的程序存储器,32条I/O口,5V工作
ISD4003-08--语音芯片,音质优异的模拟存储技术,可反复录放,8分钟,可分1200段,SPI接口方式,3V供电
LM386--功率放大器,0.5W驱动
24C01(选配件)--I2C总线串行存储器。
还有驻极体话筒(MIC)、话筒放大器、音量电位器、发光管等部件。
二、性能参数
外接电源电压:
5V(稳压)
外接喇叭:
4-16欧姆,0.5W
工作电流:
25~30mA(录音),50~80mA(放音)
静态电流:
13mA
随板提供的演示程序功能:
1、录音
跳线插在"REC"一侧是录音状态,按住"AN"键不放,指示灯亮即可对着板上话筒讲话录音,松键时录音停止并形成一段。
再按则录下一段。
按"STOP"键为复位,再录音时又从第一段开始。
2、放音
跳线插在"PLAY"一侧是放音状态,按一下"AN"键即播放一段,一段结束后自动停止放音,再按"AN"则播放下一段
按"STOP"键为复位,再放音时又从第一段开始。
89C51-ISD4000语音电路程序AT89C51单片机
89C51单片机12MHz
注:
本程序为ISD4002、4003的控制程序,ISD4004的程序须加些改动,请注意程序后边的注释。
SSEQUP1.0;片选
SCLKEQUP1.1;ISD4003时钟
MOSIEQUP1.2;数据输入
MISOEQUP1.3;数据输出
LEDEQUP1.7;指示灯
INTEQUINT0;中断
ANEQUP1.6;执行
STOPEQUP1.5;复位
PREQUP1.4;PR=1录音PR=0放音
;初始化
ORG0000H;
AJMPMAIN;
MAIN:
MOVSP,#10H;
MOVP1,#0FFH;
MOVP2,#0FFH;
MOVP3,#0FFH;
MOVP0,#0FFH;
CLREA;
MAII:
SETBLED;关指示灯
ACALLDSTOP;ISD掉电
MAS0:
MOV3AH,#200;
MAS1:
JBAN,MAS0;等按AN键
DJNZ3AH,MAS1;
ACALLUP;ISD上电
MOV20H,#00H;ISD低位地址
MOV21H,#00H;ISD高位地址
JBPR,REC;PR=1录音
AJMPPLAY;PR=0放音
;SETREC16位
;从指定地址录音10100
REC:
MOVA,20H;发地址A7-A0
ACALLISDX;
MOVA,21H;发地址A9-A8
SETBACC.7;
CLRACC.6;
SETBACC.5;
CLRACC.4;
CLRACC.3;
ACALLISDX;
SETBSS;关片选
;REC8位
;从当前地址录音10110
REC1:
MOV36H,#10;
REC2:
ACALLYS50;延时录音
DJNZ36H,REC2;
CLRLED;开指示灯
MOVA,#0B0H;发10110XXX
ACALLISDX;
SETBSS;关片选
REC3:
MOV35H,#200;
REC4:
JNBINT,REC7;OVF=0芯片溢出
JNBAN,REC3;
DJNZ35H,REC4;
SETBLED;关指示灯
ACALLSTOPP;停止当前操作
REC5:
JNBSTOP,REC6;中断RESET
JBAN,REC5;等待AN=0
ACALLSTOPP;停止当前操作
AJMPREC1;
REC6:
CLRSCLK;时钟SCLK=0
SETBSS;关片选
ACALLSTOPP;停止当前操作
AJMPMAII;
REC7:
SETBLED;关指示灯
MOV36H,#15;
REC8:
ACALLYS50;延时录音
JBAN,REC6;等待AN=1
DJNZ36H,REC8;
CLRLED;
MOV36H,#15;
REC9:
ACALLYS50;延时录音
JBAN,REC6;等待AN=1
DJNZ36H,REC9;
AJMPREC7;
;SETPLAY16位
;从指定地址放音11100
PLAY:
JNBAN,PLAY;等待AN=1
MOVA,20H;发地址A7-A0
ACALLISDX;
MOVA,21H;发地址A9-A8
SETBACC.7;
SETBACC.6;
SETBACC.5;
CLRACC.4;
CLRACC.3;
ACALLISDX;
SETBSS;关片选
;PLAY8位
;从当前地址放音11110
PLAY1:
CLRLED;LED开指示灯
MOVA,#0F0H;发11110XXXXXXXX
ACALLISDX;发<>
SETBSS;关片选
PLAY2:
JNBSTOP,REC6;STOP=0停止放音
JBINT,PLAY2;无OVFEOM继续放音
SETBLED;关指示灯
ACALLSTOPP;停止当前操作
;检测OVF
CLRSS;开片选
CLRSCLK;时钟SCLK=0
SETBSCLK;时钟SCLK=1
JBMISO,REC6;芯片到未
CLRSCLK;时钟SCLK=0
SETBSS;关片选
ACALLSTOPP;停止当前操作
PLAY3:
JNBSTOP,REC6;中断放音
JBAN,PLAY3;等待AN=0
AJMPPLAY1;顺序放音
;ISD上电<>
UP:
MOVA,#20H;发00100XXXXXXXXXXX
ACALLISDX;
SETBSS;关片选
ACALLYS50;50mS延时
ACALLYS50;50mS延时
RET;
;停止当前操作<>8位
STOPP:
MOVA,#30H;发0X110XXX
ACALLISDX;
SETBSS;关片选
ACALLYS50;50mS延时
ACALLYS50;50mS延时
RET;
;停止当前操作掉电<>8位
DSTOP:
MOVA,#10H;发0X010XXXXXXXXXX
ACALLISDX;
SETBSS;关片选
ACALLYS50;50mS延时
ACALLYS50;50mS延时
RET;
;ISD3300,4003SPI写入程序8位数据在A
ISDX:
CLRSS;开片选
MOVR6,#8;
CLRSCLK;时钟SCLK=0
ISD1:
MOVC,ACC.0;
MOVMOSI,C;数据写MOSI
SETBSCLK;时钟SCLK=1
RRA;
CLRSCLK;时钟SCLK=0
DJNZR6,ISD1;
RET;
;****10mS延时****
YS1:
MOVTMOD,#01H;
MOVTH0,#0D8H;10mS延时初值置入
MOVTL0,#0F0H;(65536-X)*1=10MS
SETBTR0;65536-(10000/1)=D8F0H
JNBTF0,$;
CLRTF0;
CLRTR0;
RET;
;****50mS延时****
YS50:
MOVTMOD,#01H;
MOVTH0,#3CH;50mS延时初值置入
MOVTL0,#0B0H;(65536-X)*1=50MS
SETBTR0;65536-(50000/1)
JNBTF0,$;
CLRTF0;
CLRTR0;
RET;
END;
附:
ISD4004的程序改动注明:
SETREC:
;指定地址录音
MOV20H,#00H;低八为地址
MOV21H,#00H;高八位地址
MOV22H,#0a0H;操作码
MOVA,20H
ACALLISDX
MOVA,21H
ACALLISDX
MOVA,22H
ACALLISDX
SETBSS
指定地址录音(SETPLAY)和指定地址快进(SETMC)的改动与上述相同
ISD4000-89c51开发板C程序示例
//*****************************************************
//ISD4002-89c51开发板演示例程C51版本*
//作者:
中青世纪Lell*
//2008.2.27*
//*
//更多ISD4000使用心得请登陆中青世纪论坛*
//*
//*
//*****************************************************
#include
sbitSS = P1^0; //片选
sbitSCLK= P1^1; //ISD4003时钟
sbitMOSI= P1^2; //数据输入
sbitMISO= P1^3; //数据输出
sbitLED= P1^7; //指示灯
sbitISD_INT= P3^2; //中断
sbitAN= P1^6; //执行
sbitSTOP= P1^5; //复位
sbitPR= P1^4; //PR=1录音?
PR=0放音
void delay(unsignedinttime) //延迟n微秒
{
while(time!
=0)
{
time--;
}
}
void delayms(unsignedinttime) //延迟n毫秒
{ TMOD=0x01;
for(time;time>0;time--)
{
TH0=0xfc;
TL0=0x18;
TR0=1;
while(TF0!
=1)
{;}
TF0=0;
TR0=0;
}
}
//************************************
//ISD4002spi串行发送子程序,8位数据
//************************************
voidspi_send(unsignedcharisdx)
{ unsignedcharisx_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指令
//*******************************
voidisd_stop(void)
{ delay(10);
spi_send(0x30);
SS=1;
delayms(50);
}
//*******************************
//发送上电指令,并延迟50ms
//*******************************
voidisd_pu(void)
{ delay(10);
SS=0;
spi_send(0x20);
SS=1;
delayms(50);
}
//*******************************
//发送掉电指令,并延迟50ms
//*******************************
voidisd_pd(void)
{ delay(10);
spi_send(0x10);
SS=1;
delayms(50);
}
//*******************************
//发送play指令
//*******************************
voidisd_play(void)
{
LED=0;
spi_send(0xf0);
SS=1;
}
//*******************************
//发送rec指令
//*******************************
voidisd_rec(void)
{
LED=0;
spi_send(0xb0);
SS=1;
}
//*******************************
//发送setplay指令
//*******************************
voidisd_setplay(unsignedcharadl,unsignedcharadh)
{
spi_send(adl); //发送放音起始地址低位
adh=adh||0xe0;
spi_send(adh); //发送放音起始地址高位
SS=1;
}
//*******************************
//发送setrec指令
//*******************************
voidisd_setrec(unsignedcharadl,unsignedcharadh)
{
spi_send(adl); //发送放音起始地址低位
adh=adh||0xa0;
spi_send(adh); //发送放音起始地址高位
SS=1;
}
//************************************
//芯片溢出,LED闪烁提醒停止录音
//************************************
voidisd_overflow(void)
{
while(AN==0)
{LED=1;
delayms(300);
LED=0;
delayms(300);
}
}
//************************************
//检查芯片是否溢出(读OVF,并返回OVF值)
//************************************
unsignedcharchk_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指令
return1; //OVF为1,返回1
}
else
{SCLK=0;
SS=1; //关闭spi通信端
isd_stop(); //发送stop指令
return0; //OVF为0,返回0
}
}
//************************************************************************
//主程序
//功能:
1.录音时,按住AN键,LED点亮开始录音,松开AN即可停止录音
// 再次按下AN键,LED点亮开始录第二段音,依次类推,直到芯片溢出。
// 按stop键芯片复位
// 2.放音时,按一下AN键,即播放一段语音。
按stop键芯片复位。
//************************************************************************
voidmain(void)
{unsignedcharovflog;
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指令
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)
break;
if(AN==0)
delayms(20);
}
}while(AN==0); //AN键再次按下,播放下一段语音
}
isd_stop();
isd_pd();
}
}
注意:
与ISD4002/03不同的是,由于ISD4004芯片的语音地址是16位,在发送带地址指令(如setplay,setrec,setmc)时,需要先发送两个字节的地址信息,再发送一个字节的命令字,ISD4004的程序编写与ISD4002/03的区别,仅此而已。
例如,ISD4004的setplay指令程序应为:
voidisd_setplay(unsignedcharadl,unsignedcharadh)
{
delayms
(1);
spi_send(adl); //发送放音起始地址低位
delay
(2);
spi_send(adh); //发送放音起始地址高位
delay
(2);
spi_send(0xe0); //发送setplay指令字节
SS=1;
}