语音电子开关身份认证系统
一、 设计要求: 1、功能
语音电子你身份认证系统功能为:可以识别8个语音输入,语音识别正确后能自动开锁,且对8个语音输入给出8种不同的语音回答。系统在语言不能正确识别,比如感冒时,可以输入6位的密码开锁,6位密码也可以修改。 2、基本条件
本课题主要是兴趣,再加上看书刚好看到,暂时没有板子,但是如果有条件的话,很想尝试着做一个模型出来;但是我们现在已经学习了单片机、嵌入式、数电模电及高频等等,这些足以帮助我们在实际的课题中解决相关问题。此外网络也给我们的学习提供了方便,我们可以通过网络查找我们需要的资料,比如本课题的语音识别芯片AP7003及语音回放芯片ISD4002-120芯片等等。
二、原理性设计(含部分功能解释)
框图:
ISD4002不能独立进行录放工作,需要采用SPI总线的方式与单片机链接,应用电路如下。
ISD4002的声音输出采用音频功率放大器调节声音。LM386是音频功率放大器,主要应用与低电压消费产品,在1脚和8脚之间增加一只外接电阻和电容,便可将电压增益调为任意值,可以调节范围为20~200。ISD4002的通过数据端MOSI、MISO、时钟端SCLK、片选端SS、中断端INT与单片机相连,单片机的外围电路如下:
录放音系统电路:
PIM1=0接低电平时,AP7003-02为8键控制模式,8键控制模式的典型电路如下:
AP7003的8键模式:
在本系统中,采用由按键直接控制的AP7003-02芯片。AP7003-02可以单独使用,无需控制器,适合于用键盘直接控制。芯片有8键控制盒12键控制两种键盘操作模式。PIM1=1接高电平时,AP7003-02为12键控制模式,12键控制模式的典型电路如下:
AP7003的12键模式:
系统语音识别电路如下,电路采用AP7003-02的12键模式的标准电路,PIM1接高电平。系统可以识别8个1.5m语音长度的语音信号,识别标志信号在A端POA1-POA8输出,POSL接低电平,则A口低输出有效。通电后,先按1#键,LED1端的语音录音指示灯和POA1端的指示灯同时亮,此时可对着话筒讲话,POA1灭,LED1亮。再对着话筒“学习”,LED2语音识别指示灯和POA1同时亮,表示“学习”成功。接着再按2#键,LED1、POA2同时亮,另外一个家庭成员立刻对着话筒发话,以此类推,直到1~8键全部学习完毕,也可以对某一键或某几个键进行无序输入和学习,也可以一个家庭成员输入多个语音识别信息。
在此把8路的输出POA1-POA8端接与8-3优先编码器74LS148芯片,74LS148的输入端0~7低电平有效,7段优先级较高,和AP7003的输出低电平有效正好对应,在此把AP7003的A端POA1-POA8与74LS148的输入端7~0端依次相连,则1号语音信息有效级较高。74LS148芯片的EI端为输入使能端,低电平有效,在此接一个开关,可以控制识别的输出信号是否送单片机,74LS148的A、B、C输出端为输入0~7的编码输出,也是低电平有效,GS端为芯片工作且有有效信号输入的输出端。A、B、C输出端接与单片机的P2.0~P2.2端,GS端接单片机的中断0INT0端,有语音识别成功时可以产生中断,进入中断服务程序。第11键clear output为输出转换键,每转换控制一种电器都需按一下该键。
语音识别正确或输入密码正确时,P2.4端输出高电平,三极管Q1导通,继电器得以动作,黄色指示灯DS12亮表示开锁。
语音电子门锁系统:
三、 程序
流程图:
1、系统主流程图:
2、电子密码锁修改密码子程序流程图
3、电子密码锁输入密码子程序流程图:
源程序代码:
1、语音识别:
#include #include #include #define uint unsigned int #define uchar unsigned char
sbit ISD_SS = P1^0; //ISD4002片选 sbit ISD_SCLK = P1^1; //ISD4002时钟 sbit ISD_MOSI = P1^2; //ISD4002数据输入 sbit ISD_MISO = P1^3; //ISD4002数据输出 sbit ISD_INT = sbit PR =
P3^3; P1^4;
//ISD4002溢出或放音结束中断 //PR=1录音 PR=0放音
//语音识别程序
sbit RUN = P1^5; sbit STOP = P1^6; sbit LED = sbit SDA= sbit SCL= sbit error= sbit right=
//执行录音或放音 //复位
//指示灯
P1^7;
P3^1; //24c02数据端 P3^0; //24c02时钟端 P2^4; //闭锁指示端
P2^5; //开锁指示端 和开锁输出
//8279命令状态地址A11 A14 //8279数据地址 //记录状态字 最高位 //中断0标志位 //语音识别编号
#define COM XBYTE [0x7fff] #define DAT XBYTE [0x77fF] sbit clflag=ACC^7; bit int0_flag=0; uchar nmb_flag;
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, //0,1,2,3,4,5,6,7
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71 //8,9,A,B,C,D,E,F }; //共阳极数码管显示段码
//显示用数据暂存器 8位数据
//密码用数据暂存器 6位数据
uchar idata diss[8]; uchar idata mima[6];
//************** 函数声明 ********************** void reply(void);
//自动回答程序 //手动对ISD录放音
void ISD_PR(void);
void ISD_WRITE(uchar isdx); void ISD_STOP(void); void ISD_PU(void); void ISD_PD(void); void ISD_PLAY(void); void ISD_REC(void);
//SPI串行发送一个字节子程序
//发送stop指令程序 //发送上电指令程序 //发送省电指令程序 //发送play指令程序
//发送rec指令程序
void ISD_SETPLAY(uchar adl,uchar adh); //发送setplay指令程序
void ISD_SETREC(uchar adl,uchar adh); //发送setrec指令程序 uchar READ_ISD_OVF(void); void ISD_OVF(void); void DELAY(uint n);
//读溢出标志OVF程序
//LED闪烁程序
//延迟n微秒 //延迟n毫秒
void DELAYms(uint n);
uchar keyin(); uchar deky(); void disp(uchar idata *d); void start_bit(void); void stop_bit(void); void mast_ack(void); bit write_8bit(uchar ch);
//8279读键号子程序 //8279监测有无按键按下子程序
//8279显示子程序
//2402开始位 //2402停止位 //2402主答函数
//2402写一个字节(8位)数据
uchar page_wr(uint firstw_ad,uint counter,uchar *firstr_ad);
//2402页面写函数
uchar page_rd(uint firstrd_ad,uint count,uchar *firstwr_ad);
//页面读函数
void mimakey(void); //密码锁设置密码 输入密码子程序
//************************************************************************ //主程序
//功能:系统录音分成8段,可以提供8个提示语。 1.录音时,按住RUN键,LED点亮开始录音,松开RUN即可停止录音 // 再次按下RUN键,LED点亮开始录第二段音,依次类推,直到芯片溢出。 // 按stop键芯片复位
// 2.放音时,按一下RUN键,即播放一段语音。 按stop键芯片复位。 //************************************************************************ void main(void) {
uchar i;
P0=P1=P2=P3=0xff; IP=0x01;
//初始化 //INT0高优先级
//INT0开中断,CUP开中断
IE=0X81;
COM=0xd1; do{ACC=COM;} while(clflag==1);
//11010001 总清除命令 //读状态字 直到清除完成
//读状态字 最高位
//键盘/显示器工作方式 左端送入8×8显示双键锁定编码扫描 //时钟分频 20分频
COM=0x00; COM=0x34; right=0;error=1;
//默认闭锁
//************以下测试用*****************//
for(i=0;i
//设置初始密码为234567 测试用 //写入2402
//测试用 当2402存好密码后 该部分程序可以撤除 //************以上测试用*****************//
while(1) {
ISD_PR();
//手动对ISD录放音
if(int0_flag==1) //有中断产生
{right=1;error=10;
reply();
//开锁
//自动回答
int0_flag=0;
//标志位清
}mimakey();
}}
//密码锁 设置密码、输入密码子程序
void reply(void)
//自动回答程序 //录放音的地址变量
{ uchar al,ah; }
ISD_PU(); ISD_PD(); ISD_PU();
//RUN键按下为0,ISD上电并延迟50ms //停止本次操作并进入省电状态
//SD上电并延迟50ms
ah=(nmb_flag+1)/2-1; al=0x80*(1-nmb_flag%2); ISD_SETPLAY(ah,al);
//计算高两位地址 ah //计算低八位地址 al
//发送setplay指令,从指定地址地址开始放音
//发送放音指令
//LED亮
ISD_PLAY(); LED=0; DELAY(20);
while(ISD_INT==1) {;} LED=1;
//等待放音完毕的EOM中断信号
//LED熄灭
ISD_STOP(); ISD_PD();
//放音完毕,发送stop指令
//停止本次操作并进入省电状态
void service_int0() interrupt 0 using 2 { int0_flag=1;
nmb_flag=P2&0x07;}
//外部中断0 用第二组寄存器
void ISD_PR(void) {uchar k=1;
//手动对ISD录放音 //指示录放音段数的变量 //录放音的地址变量
//RUN键按下
uchar al,ah;
while(RUN==0)
{DELAYms(20);
//按键防抖动
if(RUN==1) {break;}
ISD_PU(); ISD_PD(); ISD_PU();
//按键防抖动
//RUN键按下为0,ISD上电并延迟50ms //停止本次操作并进入省电状态
//SD上电并延迟50ms //如果PR=1则转入录音部分
if (PR==1)
{DELAYms(500);
//延迟录音 指定地址录音
ISD_SETREC(0x00,0x00); //发送0x0000h地址的setplay指令 do
{ ah=(k+1)/2-1;
//计算高两位地址 ah //计算低八位地址 al
al=0x80*(1-k%2);
ISD_SETREC(ah,al); //发送指定地址地址的setplay指令 ISD_REC();
//发送rec指令 下一个地址开始录音
while(RUN==0)
//键未松开 等待录音完毕
{if (ISD_INT==0) //如果芯片溢出
ISD_OVF();
//进行LED闪烁提示}
if (ISD_INT==0) //录音溢出,按键RUN释放 则退出录音。则芯片复位 break;
LED=1;
//按键释放,未满,录音完毕,LED熄灭
ISD_STOP(); while(RUN==1) {if(STOP==0)
break; if (RUN==0) DELAYms(500); k++;
//发送停止命令
//如果RUN未按下 查询 RUN和STOP键
//如果按下STOP按键,则芯片复位
//如果RUN再次按下,开始录制下一段语音
//指向下一段录音}
}while(RUN==0);
//如果PR==0则转入放音部分
}else {while(RUN==0){;}
//未释放按键时等待
ISD_SETPLAY(0x00,0x00); //发送setplay指令,从0x0000地址开始放音 do
{ ah=(k+1)/2-1;
al=0x80*(1-k%2); ISD_SETPLAY(ah,al);
//计算高两位地址 ah //计算低八位地址 al
//发送setplay指令,从指定地址地址开始放音
//发送放音指令
ISD_PLAY(); DELAY(20);
while(ISD_INT==1) //等待放音完毕的EOM中断信号 {;} LED=1;
//LED熄灭
ISD_STOP(); //放音完毕,发送stop指令 if (READ_ISD_OVF()==1) break;
while(RUN==1) { if (STOP==0)
break; if(RUN==0) DELAYms(20); k++;
//指向下一段放音}
//如果RUN再次按下,开始播放下一段语音
//等待RUN键再次按下
//如果按下STOP按键,则芯片复位
//检查芯片是否溢出 ,如溢出则停止放音,芯片复位
}while(RUN==0);
//RUN键再次按下,播放下一段语音
//发送stop指令
//停止本次操作并进入省电状态}}
}ISD_STOP(); ISD_PD();
//************************************ //ISD4002 SPI串行发送一个字节子程序,8位数据 //************************************ void ISD_WRITE(uchar isdx) { uchar i;
ISD_SS=0; ISD_SCLK=0; for(i=0;i
//片选使能,打开SPI通信端
//时钟置0
//SPI串行发送一个字节子程序
//8位依次发送
//取最低位,为1则数据线置1
{ if ((isdx&0x01)==1)
{ISD_MOSI=1;} else
//为0则数据线置0
{ISD_MOSI=0;}
isdx=isdx>>1;
ISD_SCLK=1;
DELAY(2);
ISD_SCLK=0;
DELAY(2);}}
//*******************************
//发送stop指令
//*******************************
void ISD_STOP(void)
{ DELAY(10);
ISD_WRITE(0x30);
ISD_SS=1;
DELAYms(50);}
//*******************************
//发送上电指令,并延迟50ms
//*******************************
void ISD_PU(void)
{ DELAY(10);
ISD_SS=0;
ISD_WRITE(0x20);
ISD_SS=1;
DELAYms(50);}
//*******************************
//发送省电指令,并延迟50ms
//*******************************
void ISD_PD(void)
{DELAY(10);
ISD_WRITE(0x10);
ISD_SS=1;
DELAYms(50);}
//*******************************
//发送play指令
//*******************************
void ISD_PLAY(void)
{LED=0;
ISD_WRITE(0xf0);
ISD_SS=1;}
//*******************************
//发送rec指令
//*******************************
void ISD_REC(void)
{LED=0;
ISD_WRITE(0xb0);
ISD_SS=1;} //先发低位再发高位,依次发送 //时钟产生上升沿 锁存输入的数据 //延时使数据稳定 //回复时钟低电平 //发送stop指令程序 //停止录音或放音操作,指令代码0X11 0 //发送上电指令程序 //器件上电,指令代码0010 0 //发送省电指令程序 //停止本次操作并进入省电状态,指令代码0X01 X //发送play指令程序 //指示灯亮 //在下一个地址开始放音,指令代码1111 1/0 //发送rec指令程序 //指示灯亮 //从下一个地址开始录音
//*******************************
//发送setplay指令
//*******************************
void ISD_SETPLAY(uchar adl,uchar adh)
{ ISD_WRITE(adl);
adh=adh||0xe0; ISD_WRITE(adh); ISD_SS=1;} //发送setplay指令程序 //发送放音起始地址低位 //从地址开始放音 //发送放音起始地址高位
//*******************************
//发送setrec指令
//*******************************
void ISD_SETREC(uchar adl,uchar adh) //发送setrec指令程序
{ ISD_WRITE(adl);
adh=adh||0xa0; ISD_WRITE(adh); ISD_SS=1;} //发送录音起始地址低位 //从地址开始录音 //发送录音起始地址高位
//************************************
//检查芯片是否溢出(读OVF,并返回OVF值)
//************************************
uchar READ_ISD_OVF(void)
{ ISD_SS=0;
DELAY(2); ISD_SCLK=0; DELAY(2); ISD_SCLK=1; ISD_SCLK=0; DELAY(2); if (ISD_MISO==1) { ISD_SS =1; //只读第1位数据 //关闭SPI通信端 //时钟信号下降沿时输出数据 //先产生时钟上升沿 //读溢出标志OVF程序 //片选有效 ISD_STOP(); return 1; //发送stop指令 //OVF为1,返回1} //关闭SPI通信端 else{ ISD_SS =1; }} ISD_STOP(); return 0; //发送stop指令 //OVF为0,返回0
//************************************
//芯片溢出,LED闪烁提醒停止录音
//************************************
void ISD_OVF(void)
{while(RUN==0)
//LED闪烁程序 //为0 表示键在按下 还未释放 //指示灯灭 //延时指示灯闪烁 //指示灯亮 { LED=1; DELAYms(300); LED=0; DELAYms(300);}}
void DELAY(uint n)
{while(n!=0)
{n--;}} //延迟n微秒
void DELAYms(uint n)
{ TMOD=0x01;
while(n!=0)
{ TH0=0xfc; TL0=0x18; TR0=1; while(TF0!=1) {;} TF0=0; TR0=0; n--;}} //延迟n毫秒 //T0 16位定时 //12MHZ晶振时 定时1ms
void mimakey(void)
{ uchar i,key;
//密码锁 设置密码、输入密码子程序 //i循环变量 key键号暂存器 //解锁标志位 bit keyok; for(i=0;i=0x0a) {do{key=keyin();}while(key>=0x0a);} //不是取消键且输入键号不是0~9的数字键时 等待1位数输入 mima[i]=key; diss[i]=15; disp(diss); //密码数字存于mima暂存器中 //每输入一位密码数码管显示“F” //送显示 } if(key!=0x0d) { key=keyin(); if (key==0x0d); else //6位密码输入完成时 看是否要确认;未完成6位输入时 返回 //等待按键输入 //是取消键时 输入密码取消 //不是取消键时 等待输入密码确认 { if(key!=0x0c) while(keyin()!=0x0c);//等待确认键按下 while(page_rd(0,6,&diss[0])==0); //在2402中读取密码 keyok=1; //把解锁标志位设为1 解锁 for(i=0;i
//*************以上为 输入密码状态*************// //*************以下为设置密码状态*************// if(keyok==1) //在开锁状态下 可以设置密码或关锁 {if(key==0x0d) //开锁状态时 按下取消键时 关锁 {keyok=0;right=0;error=1; //解锁状态位设为0 闭锁 }if(key==0x0a) //是设定键时 进入设置密码状态 {for(i=0;i=0x0a) {do{key=keyin();}while(key>=0x0a);} //不是取消键且输入键号不是0~9的数字键时 等待1位数字键输入 //密码数字存于mima暂存器中 mima[i]=key; diss[i]=14; //每输入一位密码数码管显示“E” disp(diss); //送显示 }if(key!=0x0d) {key=keyin(); if (key==0x0d); //6位密码输入完成时 看是否要确认;未完成6位输入时 返回 //读一位键 //是取消键时 设置密码取消 else //不是取消键时 等待设置密码确认 while(keyin()!=0x0c); //等待确认键按下 }}}} { if(key!=0x0c) while(page_wr(0,6,&mima[0])==0); //密码写入24lc02 //*************以上为设置密码状态*************// void disp(uchar idata *d) //显示子程序
{uchar j;
COM=0x90; for(j=0;j
DAT=table[*d]; d++; uchar keyin(void)
{ uchar j;
}
uchar deky(void)
{uchar k;
} do //读键号 {while(deky()==0); COM=0x40; j=DAT; j=j&0x3f; }while(j>=0x0e); //监测有键按下吗 无键时等待 //读FIFO/传感器RAM 不自动加1 地址为0 //读数据 //读低6位 D5D4D3为键盘所在列号 D2D1D0为键盘所在行号 //只读取0~9和A~D键 不读取E和F键 //返回键号 return(j); //监测有无按键按下 k=COM; return(k&0x03); //读状态 //只监测2行按键 有键返回1 无键返回0
/*-----------------------------------------------
调用方式:void start_bit(void)
函数说明:2402开始位
在时钟端SCL为高电平时,数据端SDA发生由高到低的变化,为起始条件
启动I2C总线
-----------------------------------------------*/
void start_bit(void)
{ SCL=1;//_nop_();
SDA=1;//_nop_();
SDA=0;//_nop_();
SCL=0;//_nop_();}
/*-----------------------------------------------
调用方式:void stop_bit(void)
函数说明:2402停止位
在时钟端SCL为高电平时,数据端SDA发生由低到高的变化,为停止条件
停止I2C总线数据传输
-----------------------------------------------*/
void stop_bit(void)
{ SDA=0;//_nop_();
SCL=1;//_nop_();
SDA=1;//_nop_();}
/*-----------------------------------------------
调用方式:void mast_ack(void)
函数说明:2402主答函数
主器件在收发每一个字节后产生一个时钟应答脉冲,
在这期间,发送器必须保证SDA为高,由接收器SDA拉低,
称为应答信号(ACK)。
-----------------------------------------------*/
void mast_ack(void)
{ SCL=0;_nop_();
SDA=0;_nop_();
SCL=1;_nop_();
SCL=0;_nop_();
SDA=1;_nop_();}
/*-----------------------------------------------
调用方式:write_8bit(uchar ch)
函数说明:2402写一个字节(8位)数据
-----------------------------------------------*/
bit write_8bit(uchar ch)
{ uchar i=8;
bit fan_w;
SCL=0;_nop_();
while(i--)
{SDA=(bit)(ch&0x80); //取字节的最高位
_nop_();
ch
SCL=1;_nop_(); //上升沿锁存数据
SCL=0;_nop_() }
SDA=1;_nop_();
SCL=1;_nop_();
fan_w=SDA; //读应答信号
SCL=0;_nop_();
return(fan_w); //返回应答信号
}
/*-----------------------------------------------
调用方式:void page_wr(uint firstw_ad,uint counter,uint data *firstr_ad)
函数说明:2402页面写函数,firstw_ad为写入字节单元的首地址,
*firstr-ad为被写入数据所在首地址指针
counter为写入数据字节数
-----------------------------------------------*/
uchar page_wr(uint firstw_ad,uint counter,uchar *firstr_ad)
{ uchar data *ufirstr_ad;
ufirstr_ad=firstr_ad;
start_bit(); //写开始位
if(write_8bit(0xA0)!=0){stop_bit();return(0);} //写命令
if(write_8bit(firstw_ad)!=0){stop_bit();return(0);}//写首地址
while(counter--) //写字节数减1
{if(write_8bit(*ufirstr_ad)!=0){stop_bit();return(0);}//写1字节
ufirstr_ad++; //地址加1
} stop_bit(); //写停止位
return(1);}
/*-----------------------------------------------
调用方式:void page_rd(uint firstrd_ad,uint count,uint firstwr_ad)
函数说明:2402页面读函数,firstrd-ad为所读字节首地址,count为读字节数
*ufirstwr-ad为读出数据存储首地址指针
-----------------------------------------------*/
uchar page_rd(uint firstrd_ad,uint count,uchar *firstwr_ad)
{ uchar j=8;
uchar data *ufirstwr_ad;
ufirstwr_ad=firstwr_ad;
start_bit(); //写开始位
if(write_8bit(0xA0)!=0){stop_bit();return(0);} //写命令
if(write_8bit(firstrd_ad)!=0){stop_bit();return(0);}//写首地址
start_bit(); //写开始位
if(write_8bit(0xA1)!=0){stop_bit();return(0);} //读命令
while(count--) //读字节数减1
{ uchar i=8;
while(i--)
{(*ufirstwr_ad)
if(SDA) (*ufirstwr_ad)|=0x01; //数据端为1时 存1
SCL=0; _nop_();}
ufirstwr_ad++; //地址加1
mast_ack(); //应答信号 }
while(j--)
{ (*ufirstwr_ad)
SCL=0;_nop_();_nop_();SCL=1;
if(SDA) (*ufirstwr_ad)|=0x01; }
stop_bit(); //写停止位
return(1);}
//24c02________________________________在上面
语音录放:
#include
#define uint unsigned int
#define uchar unsigned char
sbit ISD_SS = P1^0; //ISD4002片选
sbit ISD_SCLK = P1^1; //ISD4002时钟
sbit ISD_MOSI = P1^2; //ISD4002数据输入
sbit ISD_MISO = P1^3; //ISD4002数据输出
sbit ISD_INT =
sbit PR = P3^3; P1^4; //ISD4002溢出或放音结束中断 //PR=1录音 PR=0放音
sbit RUN = P1^5;
sbit STOP = P1^6;
sbit LED = //执行录音或放音 //复位 //指示灯 P1^7;
//************** 函数声明 **********************
void ISD_WRITE(uchar isdx);
void ISD_STOP(void);
void ISD_PU(void);
void ISD_PD(void);
void ISD_PLAY(void);
void ISD_REC(void); //SPI串行发送一个字节子程序 //发送stop指令程序 //发送上电指令程序 //发送省电指令程序 //发送play指令程序 //发送rec指令程序
void ISD_SETPLAY(uchar adl,uchar adh); //发送setplay指令程序
void ISD_SETREC(uchar adl,uchar adh); //发送setrec指令程序
uchar READ_ISD_OVF(void);
void ISD_OVF(void);
void DELAY(uint n);
//读溢出标志OVF程序 //LED闪烁程序 //延迟n微秒 //延迟n毫秒 void DELAYms(uint n);
//************************************************************************
//主程序
//功能:1.录音时,按住RUN键,LED点亮开始录音,松开RUN即可停止录音
// 再次按下RUN键,LED点亮开始录第二段音,依次类推,直到芯片溢出。
// 按stop键芯片复位
// 2.放音时,按一下RUN键,即播放一段语音。 按stop键芯片复位。
//************************************************************************ void main(void)
{P0=P1=P2=P3=0xff;
while(1) { while (RUN==1) //等待RUN键按下 //初始化 {if(RUN==0) //按键防抖动 {DELAYms(20);}} //RUN键按下为0,ISD上电并延迟50ms //停止本次操作并进入省电状态 //SD上电并延迟50ms //如果PR=1则转入录音部分 ISD_PU(); ISD_PD(); ISD_PU(); if (PR==1) {DELAYms(500); //延迟录音 指定地址录音 ISD_SETREC(0x00,0x00); //发送0x0000h地址的setplay指令 do{ ISD_REC(); //发送rec指令 下一个地址开始录音 //键未松开 等待录音完毕 while(RUN==0) {if (ISD_INT==0) //如果芯片溢出 ISD_OVF(); //进行LED闪烁提示} if (ISD_INT==0) //录音溢出,按键RUN释放 则退出录音。则芯片复位 break; LED=1; ISD_STOP(); while(RUN==1) { if(STOP==0) break; if (RUN==0) DELAYms(500);}} //如果RUN再次按下,开始录制下一段语音 //按键释放,未满,录音完毕,LED熄灭 //发送停止命令 //如果RUN未按下 查询 RUN和STOP键 //如果按下STOP按键,则芯片复位
while(RUN==0);}
else
{while(RUN==0){;}
//如果PR==0则转入放音部分 //未释放按键时等待 ISD_SETPLAY(0x00,0x00); //发送setplay指令,从0x0000地址开始放音 do { ISD_PLAY(); DELAY(20); while(ISD_INT==1) //等待放音完毕的EOM中断信号 {;} LED=1; //LED熄灭 //发送放音指令 ISD_STOP(); //放音完毕,发送stop指令 if (READ_ISD_OVF()==1) break; while(RUN==1) {if (STOP==0) break; if(RUN==0) //如果RUN再次按下,开始播放下一段语音 //等待RUN键再次按下 //检查芯片是否溢出 ,如溢出则停止放音,芯片复位 //如果按下STOP按键,则芯片复位
DELAYms(20);} //RUN键再次按下,播放下一段语音} //发送stop指令 //停止本次操作并进入省电状态}} }while(RUN==0); ISD_STOP(); ISD_PD();
//************************************
//ISD4002 SPI串行发送一个字节子程序,8位数据 //************************************
void ISD_WRITE(uchar isdx)
{ uchar i;
ISD_SS=0;
ISD_SCLK=0;
for(i=0;i
{ if ((isdx&0x01)==1)
{ISD_MOSI=1;}
else
{ISD_MOSI=0;}
isdx=isdx>>1;
ISD_SCLK=1;
DELAY(2);
ISD_SCLK=0;
DELAY(2);
}}
//*******************************
//发送stop指令
//*******************************
void ISD_STOP(void)
{ DELAY(10);
ISD_WRITE(0x30);
ISD_SS=1;
DELAYms(50);}
//*******************************
//发送上电指令,并延迟50ms
//*******************************
void ISD_PU(void)
{ DELAY(10);
ISD_SS=0;
ISD_WRITE(0x20);
ISD_SS=1;
DELAYms(50);}
//*******************************
//发送省电指令,并延迟50ms
//*******************************
void ISD_PD(void)
{ DELAY(10); //SPI串行发送一个字节子程序 //片选使能,打开SPI通信端 //时钟置0 //8位依次发送 //取最低位,为1则数据线置1 //为0则数据线置0 //先发低位再发高位,依次发送 //时钟产生上升沿 锁存输入的数据 //延时使数据稳定 //回复时钟低电平 //发送stop指令程序 //停止录音或放音操作,指令代码0X11 0 //发送上电指令程序 //器件上电,指令代码0010 0 //发送省电指令程序
ISD_WRITE(0x10);
ISD_SS=1; DELAYms(50);} //停止本次操作并进入省电状态,指令代码0X01 X
//*******************************
//发送play指令
//*******************************
void ISD_PLAY(void)
{LED=0;
//发送play指令程序 //指示灯亮 ISD_WRITE(0xf0); ISD_SS=1;} //在下一个地址开始放音,指令代码1111 1/0
//*******************************
//发送rec指令
//*******************************
void ISD_REC(void)
{ LED=0;
//发送rec指令程序 //指示灯亮 ISD_WRITE(0xb0); ISD_SS=1;} //从下一个地址开始录音
//*******************************
//发送setplay指令
//*******************************
void ISD_SETPLAY(uchar adl,uchar adh)
{ ISD_WRITE(adl);
adh=adh||0xe0; ISD_WRITE(adh); ISD_SS=1;} //发送setplay指令程序 //发送放音起始地址低位 //从地址开始放音 //发送放音起始地址高位
//*******************************
//发送setrec指令
//*******************************
void ISD_SETREC(uchar adl,uchar adh) //发送setrec指令程序 { ISD_WRITE(adl);
adh=adh||0xa0; ISD_WRITE(adh); ISD_SS=1;} //发送录音起始地址低位 //从地址开始录音 //发送录音起始地址高位
//************************************
//检查芯片是否溢出(读OVF,并返回OVF值)
//************************************
uchar READ_ISD_OVF(void)
{ ISD_SS=0;
DELAY(2); ISD_SCLK=0; DELAY(2); ISD_SCLK=1; ISD_SCLK=0; DELAY(2); //时钟信号下降沿时输出数据 //先产生时钟上升沿 //读溢出标志OVF程序 //片选有效
if (ISD_MISO==1) { ISD_SS =1; }else //只读第1位数据 //关闭SPI通信端 ISD_STOP(); return 1; //发送stop指令 //OVF为1,返回1 { ISD_SS =1; }} ISD_STOP(); return 0; //关闭SPI通信端 //发送stop指令 //OVF为0,返回0
//************************************
//芯片溢出,LED闪烁提醒停止录音
//************************************
void ISD_OVF(void)
{while(RUN==0)
//LED闪烁程序 //为0 表示键在按下 还未释放 //指示灯灭 //延时指示灯闪烁 //指示灯亮 { LED=1; DELAYms(300); LED=0; DELAYms(300);}}
void DELAY(uint n)
{while(n!=0)
{n--;}} //延迟n微秒
void DELAYms(uint n)
{ TMOD=0x01;
while(n!=0)
{TH0=0xfc; TL0=0x18; TR0=1; while(TF0!=1) {;} TF0=0; TR0=0; n--;}} //延迟n毫秒 //T0 16位定时 //12MHZ晶振时 定时1ms
四、总结:
本课题的总结与体会:
语音电子开关身份认证系统主要由说话人识别模块、门锁控制电机以及门锁等部分组成。在训练
时,说话人的声音通过麦克风进入说话人语音信号采集前端电路,由语音信号处理电路对采集的语音信号进行特征化和语音处理,提取说话人的个性特征参数进行存储,形成说话人特征参数数据库。在识别时,将待识别语音与说话人特征参数数据库进行匹配,通过输出电路控制门锁电机,最终实现对门锁的控制。另外还具有语言回答密码输入功能。
该课题主要是通过单片机控制按键等操作,再通过语音识别芯片AP7003和语音回
放芯片ISD4002的结合,来整体的实现语音开关身份认证系统。本系统可以直接用于家庭和单位的门锁控制,也可以提取录放部分制作公交车报站系统,或者利用本系统制
作诸如电梯门口等。
创意及改进:
1、该系统还可以在此基础上添加双重密码控制,比如先输入每个要识别用户的个人短密码才可进行语音识别,可以通过长密码直接进入,输入管理员密码才可对语音进行训练等。
2、本系统的电子密码锁,输入接口实用8279芯片扩展14个按键,通过6位7段数码管完成显示。其中,键盘输入采用逐行扫描法,数码管显示采用动态显示方法。本系统可以在此基础上进行修改,完成相关的功能设计,比如可以增加限定密码次数、限定输入密码时间、密码错误声音报警等相关功能。
学到的知识:
AT89C51芯片:
AT89C51是一种带4K字节FLASH存储器(FPEROM—Flash Programmable and Erasable Read Only Memory)的低电压、高性能CMOS 8位微处理器,俗称单片机。AT89C2051是一种带2K字节闪存可编程可擦除只读存储器的单片机。单片机的可擦除只读存储器可以反复擦除1000次。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器,AT89C2051是它的一种精简版本。AT89C51单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。
VCC:供电电压。
GND:接地。
P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。当P0口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的低八位。在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须接上拉电阻。
P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为低八位地址接收。
P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。
P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。
P3口也可作为AT89C51的一些特殊功能口,如下表所示:
口管脚 备选功能
P3.0 RXD(串行输入口)
P3.1 TXD(串行输出口)
P3.2 /INT0(外部中断0)
P3.3 /INT1(外部中断1)
P3.4 T0(计时器0外部输入)
P3.5 T1(计时器1外部输入)
P3.6 /WR(外部数据存储器写选通)
P3.7 /RD(外部数据存储器读选通)
P3口同时为闪烁编程和编程校验接收一些控制信号。
RST:复位输入。当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。
ALE/PROG:当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的低位字节。在FLASH编程期间,此引脚用于输入编程脉冲。在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。因此它可用作对外部输出的脉冲或用于定时目的。然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。如想禁止ALE的输出可在SFR8EH地址上置0。此时, ALE只有在执行MOVX,MOVC指令是ALE才起作用。另外,该引脚被略微拉高。如果微处理器在外部执行状态ALE禁止,置位无效。
/PSEN:外部程序存储器的选通信号。在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。
/EA/VPP:当/EA保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器。在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。
XTAL1:反向振荡放大器的输入及内部时钟工作电路的输入。
XTAL2:来自反向振荡器的输出。
振荡器特性:
XTAL1和XTAL2分别为反向放大器的输入和输出。该反向放大器可以配置为片内振荡器。石晶振荡和陶瓷振荡均可采用。如采用外部时钟源驱动器件,XTAL2应不接。有余输入至内部时钟信号要通过一个二分频触发器,因此对外部时钟信号的脉宽无任何要求,但必须保证脉冲的高低电平要求的宽度。
8279芯片:
DB0~DB7:双向数据总线。在CPU与8279间做数据与命令传送。
CLK:8279的系统时钟,100KHz为最佳选择。
RESET:复位输入线。输入HI时可复位8279。
CS:芯片选择信号线。当这个输入引脚为低电平时,可将命令写入8279或读取8279的数据。
A0:缓冲器地址选择线。A0=0时,读写一般数据;A0=1时,读取状态标志位或写入命令。
RD:读取控制线。RD=0时,8279输送数据到外部总线。
WR:写入控制线。WR=0时,8279从外部总线接收数据。
IRQ:中断请求。平常IRQ为LO,在键盘模式下,每次读取FIFO/SENSOR RAM的数据时,IRQ变为HI,读取后转为LO;在传感器模式下,只要传感器一有变化,就会使IRQ变为HI,读取后转为LO。
SL0~SL3:扫描按键开关或传感器矩阵及显示器,可以是编码模式(16对1)或解码模式(4对1)。
RL0~RL7:键盘/传感器的返回线。无按键被按时,返回线为HI;有按键被按时,该按键的返回线为LO。在激发输入模式时,为8位的数据输入。
SHIFT:在键盘扫描模式时,引脚的输入状态会与其它按键的状态一同储存(在BIT6),内部有上拉电阻,未按时为HI,按时为LO。
CNTL/STB:在键盘扫描模式时,引脚的输入状态会与SHIFT以及其它按键的状态同一储存,内部有上拉电阻,未按时为HI,按时为LO。在激发输入模式时,作为返回线8位数据的使能引脚。
OUTA0~OUTA3:动态扫描显示的输出口(高4位)。
OUTB0~OUTB3:动态扫描显示的输出口(低4位)。
BD:消隐输出线。
JL-034B / C (全指向式)
1、规格:dia.9.7x6.7mm
2、敏感度/dB值:(0dB=1V/Pa),-36dB,-38dB,-40dB,-42dB,-44dB,-46dB
3、频率:20~20kHz
4、电阻:
5、信号杂讯比:>55dB
ISD4002语音回放芯片
特性:
●单片4至8分钟语音录放,4、5、6及8分钟
●无需开发系统
●内置微控制器串行通信接口
●3V单电源工作
●多段信息处理
●工作电流25-30mA,维持电流1μA
●不耗电信息保存100年(典型值)
●高质量、自然的语音还原技术
●100,000次录音周期(典型值)
●自动静噪功能
●片内免调整时钟,可选用外部时钟
引脚分布图:
电源:(VCCA,VCCD)
地线:(VSSA,VSSD) 芯片内部的模拟和数字电路也使用不同的地线。
同相模拟输入(ANA IN+) 这是录音信号的同相输入端。
反相模拟输入(ANA IN-) 差分驱动时,这是录音信号的反相输入端。
音频输出(AUD OUT) 提供音频输出,可驱动5KΩ的负载。
片选(SS) 此端为低,即选中ISD4002系列。
串行输入(MOSI) 此端为串行输入端,
串行时钟(SCLK) ISD的时钟输入端,
中断(/INT) 本端为漏极开路输出。
OVF标志----指示ISD的录、放操作已到达存储器的未尾。
EOM标志----只在放音中检测到内部的EOM标志时,此状态位才置1。
行地址时钟(RAC) 漏极开路输出。
外部时钟(XCLK):本端内部有下拉元件。
自动静噪(AMCAP):当录音信号电平下降到内部设定的某一阈值以下时,自动静噪功能使信号衰弱,这样有助于养活无信号(静音)时的噪声。
AP7003语音识别芯片: 特性:
1.内置麦克风放大器;
2.内置A/D转换器;
3.DIP40双列直插式封装;
4.识别12组1.5秒时长字词;
5.I/O口具有2个普通输入、4个触发输入、2个输出口(分别有4个和12个输出)、2个LED驱动;
6.指令优化以方便用户使用;
7.2.4V-4.5V工作电压,且具备低功耗模式。
引脚:
引脚:
1 PORES 清除A输出口(POA)输出状态,高有效
2 GNDD 数字地
3 LED1 驱动LED,低有效,可编程用于指示语音录音的状态
4 LED2 驱动LED,低有效,可编程用于指示语音识别的结果
8~5 POB1~POB4 B输出口,可编程用于键盘驱动识别的结果
12~9 PIT1~PIT4 低脉冲触发输入,内部有上拉电阻,可编程用于键盘输入
13 VDDD 数字电源
14 CAPV 通过电容接地,对内部电压进行滤波
15 OSC1 振荡频率控制,通过56KΩ电阻接地
17、18 PIM1、PIM2 普通输入引脚,可编程用于芯片工作模式控制:PIM1=1时,芯片具有识别功能;PIM2=1时,A端口可以输出。反之不能 进行识别或A端口不能输出
19 TEST 测试端,芯片出厂时测试用
20 POSL 对A输出口有效电平进行选择:高时A口高有效;低时A口低有效
21 GNDA 模拟地涑隹谟行У缙浇
22 TREF 语音输入门限控制端
23 A2OUT 第二级放大器输出端
24 A1IN 第一级放大器负输入端
26 A1OUT 第一级放大器输出端
27 MICP 电子麦克风电源供应端
28 VDDA 模拟电源
29~40 POA1~POA12 A输出口,可编程用于语音录入/语音识别对的存储体指示
16、25 NC 未用引脚
语音电子开关身份认证系统
一、 设计要求: 1、功能
语音电子你身份认证系统功能为:可以识别8个语音输入,语音识别正确后能自动开锁,且对8个语音输入给出8种不同的语音回答。系统在语言不能正确识别,比如感冒时,可以输入6位的密码开锁,6位密码也可以修改。 2、基本条件
本课题主要是兴趣,再加上看书刚好看到,暂时没有板子,但是如果有条件的话,很想尝试着做一个模型出来;但是我们现在已经学习了单片机、嵌入式、数电模电及高频等等,这些足以帮助我们在实际的课题中解决相关问题。此外网络也给我们的学习提供了方便,我们可以通过网络查找我们需要的资料,比如本课题的语音识别芯片AP7003及语音回放芯片ISD4002-120芯片等等。
二、原理性设计(含部分功能解释)
框图:
ISD4002不能独立进行录放工作,需要采用SPI总线的方式与单片机链接,应用电路如下。
ISD4002的声音输出采用音频功率放大器调节声音。LM386是音频功率放大器,主要应用与低电压消费产品,在1脚和8脚之间增加一只外接电阻和电容,便可将电压增益调为任意值,可以调节范围为20~200。ISD4002的通过数据端MOSI、MISO、时钟端SCLK、片选端SS、中断端INT与单片机相连,单片机的外围电路如下:
录放音系统电路:
PIM1=0接低电平时,AP7003-02为8键控制模式,8键控制模式的典型电路如下:
AP7003的8键模式:
在本系统中,采用由按键直接控制的AP7003-02芯片。AP7003-02可以单独使用,无需控制器,适合于用键盘直接控制。芯片有8键控制盒12键控制两种键盘操作模式。PIM1=1接高电平时,AP7003-02为12键控制模式,12键控制模式的典型电路如下:
AP7003的12键模式:
系统语音识别电路如下,电路采用AP7003-02的12键模式的标准电路,PIM1接高电平。系统可以识别8个1.5m语音长度的语音信号,识别标志信号在A端POA1-POA8输出,POSL接低电平,则A口低输出有效。通电后,先按1#键,LED1端的语音录音指示灯和POA1端的指示灯同时亮,此时可对着话筒讲话,POA1灭,LED1亮。再对着话筒“学习”,LED2语音识别指示灯和POA1同时亮,表示“学习”成功。接着再按2#键,LED1、POA2同时亮,另外一个家庭成员立刻对着话筒发话,以此类推,直到1~8键全部学习完毕,也可以对某一键或某几个键进行无序输入和学习,也可以一个家庭成员输入多个语音识别信息。
在此把8路的输出POA1-POA8端接与8-3优先编码器74LS148芯片,74LS148的输入端0~7低电平有效,7段优先级较高,和AP7003的输出低电平有效正好对应,在此把AP7003的A端POA1-POA8与74LS148的输入端7~0端依次相连,则1号语音信息有效级较高。74LS148芯片的EI端为输入使能端,低电平有效,在此接一个开关,可以控制识别的输出信号是否送单片机,74LS148的A、B、C输出端为输入0~7的编码输出,也是低电平有效,GS端为芯片工作且有有效信号输入的输出端。A、B、C输出端接与单片机的P2.0~P2.2端,GS端接单片机的中断0INT0端,有语音识别成功时可以产生中断,进入中断服务程序。第11键clear output为输出转换键,每转换控制一种电器都需按一下该键。
语音识别正确或输入密码正确时,P2.4端输出高电平,三极管Q1导通,继电器得以动作,黄色指示灯DS12亮表示开锁。
语音电子门锁系统:
三、 程序
流程图:
1、系统主流程图:
2、电子密码锁修改密码子程序流程图
3、电子密码锁输入密码子程序流程图:
源程序代码:
1、语音识别:
#include #include #include #define uint unsigned int #define uchar unsigned char
sbit ISD_SS = P1^0; //ISD4002片选 sbit ISD_SCLK = P1^1; //ISD4002时钟 sbit ISD_MOSI = P1^2; //ISD4002数据输入 sbit ISD_MISO = P1^3; //ISD4002数据输出 sbit ISD_INT = sbit PR =
P3^3; P1^4;
//ISD4002溢出或放音结束中断 //PR=1录音 PR=0放音
//语音识别程序
sbit RUN = P1^5; sbit STOP = P1^6; sbit LED = sbit SDA= sbit SCL= sbit error= sbit right=
//执行录音或放音 //复位
//指示灯
P1^7;
P3^1; //24c02数据端 P3^0; //24c02时钟端 P2^4; //闭锁指示端
P2^5; //开锁指示端 和开锁输出
//8279命令状态地址A11 A14 //8279数据地址 //记录状态字 最高位 //中断0标志位 //语音识别编号
#define COM XBYTE [0x7fff] #define DAT XBYTE [0x77fF] sbit clflag=ACC^7; bit int0_flag=0; uchar nmb_flag;
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, //0,1,2,3,4,5,6,7
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71 //8,9,A,B,C,D,E,F }; //共阳极数码管显示段码
//显示用数据暂存器 8位数据
//密码用数据暂存器 6位数据
uchar idata diss[8]; uchar idata mima[6];
//************** 函数声明 ********************** void reply(void);
//自动回答程序 //手动对ISD录放音
void ISD_PR(void);
void ISD_WRITE(uchar isdx); void ISD_STOP(void); void ISD_PU(void); void ISD_PD(void); void ISD_PLAY(void); void ISD_REC(void);
//SPI串行发送一个字节子程序
//发送stop指令程序 //发送上电指令程序 //发送省电指令程序 //发送play指令程序
//发送rec指令程序
void ISD_SETPLAY(uchar adl,uchar adh); //发送setplay指令程序
void ISD_SETREC(uchar adl,uchar adh); //发送setrec指令程序 uchar READ_ISD_OVF(void); void ISD_OVF(void); void DELAY(uint n);
//读溢出标志OVF程序
//LED闪烁程序
//延迟n微秒 //延迟n毫秒
void DELAYms(uint n);
uchar keyin(); uchar deky(); void disp(uchar idata *d); void start_bit(void); void stop_bit(void); void mast_ack(void); bit write_8bit(uchar ch);
//8279读键号子程序 //8279监测有无按键按下子程序
//8279显示子程序
//2402开始位 //2402停止位 //2402主答函数
//2402写一个字节(8位)数据
uchar page_wr(uint firstw_ad,uint counter,uchar *firstr_ad);
//2402页面写函数
uchar page_rd(uint firstrd_ad,uint count,uchar *firstwr_ad);
//页面读函数
void mimakey(void); //密码锁设置密码 输入密码子程序
//************************************************************************ //主程序
//功能:系统录音分成8段,可以提供8个提示语。 1.录音时,按住RUN键,LED点亮开始录音,松开RUN即可停止录音 // 再次按下RUN键,LED点亮开始录第二段音,依次类推,直到芯片溢出。 // 按stop键芯片复位
// 2.放音时,按一下RUN键,即播放一段语音。 按stop键芯片复位。 //************************************************************************ void main(void) {
uchar i;
P0=P1=P2=P3=0xff; IP=0x01;
//初始化 //INT0高优先级
//INT0开中断,CUP开中断
IE=0X81;
COM=0xd1; do{ACC=COM;} while(clflag==1);
//11010001 总清除命令 //读状态字 直到清除完成
//读状态字 最高位
//键盘/显示器工作方式 左端送入8×8显示双键锁定编码扫描 //时钟分频 20分频
COM=0x00; COM=0x34; right=0;error=1;
//默认闭锁
//************以下测试用*****************//
for(i=0;i
//设置初始密码为234567 测试用 //写入2402
//测试用 当2402存好密码后 该部分程序可以撤除 //************以上测试用*****************//
while(1) {
ISD_PR();
//手动对ISD录放音
if(int0_flag==1) //有中断产生
{right=1;error=10;
reply();
//开锁
//自动回答
int0_flag=0;
//标志位清
}mimakey();
}}
//密码锁 设置密码、输入密码子程序
void reply(void)
//自动回答程序 //录放音的地址变量
{ uchar al,ah; }
ISD_PU(); ISD_PD(); ISD_PU();
//RUN键按下为0,ISD上电并延迟50ms //停止本次操作并进入省电状态
//SD上电并延迟50ms
ah=(nmb_flag+1)/2-1; al=0x80*(1-nmb_flag%2); ISD_SETPLAY(ah,al);
//计算高两位地址 ah //计算低八位地址 al
//发送setplay指令,从指定地址地址开始放音
//发送放音指令
//LED亮
ISD_PLAY(); LED=0; DELAY(20);
while(ISD_INT==1) {;} LED=1;
//等待放音完毕的EOM中断信号
//LED熄灭
ISD_STOP(); ISD_PD();
//放音完毕,发送stop指令
//停止本次操作并进入省电状态
void service_int0() interrupt 0 using 2 { int0_flag=1;
nmb_flag=P2&0x07;}
//外部中断0 用第二组寄存器
void ISD_PR(void) {uchar k=1;
//手动对ISD录放音 //指示录放音段数的变量 //录放音的地址变量
//RUN键按下
uchar al,ah;
while(RUN==0)
{DELAYms(20);
//按键防抖动
if(RUN==1) {break;}
ISD_PU(); ISD_PD(); ISD_PU();
//按键防抖动
//RUN键按下为0,ISD上电并延迟50ms //停止本次操作并进入省电状态
//SD上电并延迟50ms //如果PR=1则转入录音部分
if (PR==1)
{DELAYms(500);
//延迟录音 指定地址录音
ISD_SETREC(0x00,0x00); //发送0x0000h地址的setplay指令 do
{ ah=(k+1)/2-1;
//计算高两位地址 ah //计算低八位地址 al
al=0x80*(1-k%2);
ISD_SETREC(ah,al); //发送指定地址地址的setplay指令 ISD_REC();
//发送rec指令 下一个地址开始录音
while(RUN==0)
//键未松开 等待录音完毕
{if (ISD_INT==0) //如果芯片溢出
ISD_OVF();
//进行LED闪烁提示}
if (ISD_INT==0) //录音溢出,按键RUN释放 则退出录音。则芯片复位 break;
LED=1;
//按键释放,未满,录音完毕,LED熄灭
ISD_STOP(); while(RUN==1) {if(STOP==0)
break; if (RUN==0) DELAYms(500); k++;
//发送停止命令
//如果RUN未按下 查询 RUN和STOP键
//如果按下STOP按键,则芯片复位
//如果RUN再次按下,开始录制下一段语音
//指向下一段录音}
}while(RUN==0);
//如果PR==0则转入放音部分
}else {while(RUN==0){;}
//未释放按键时等待
ISD_SETPLAY(0x00,0x00); //发送setplay指令,从0x0000地址开始放音 do
{ ah=(k+1)/2-1;
al=0x80*(1-k%2); ISD_SETPLAY(ah,al);
//计算高两位地址 ah //计算低八位地址 al
//发送setplay指令,从指定地址地址开始放音
//发送放音指令
ISD_PLAY(); DELAY(20);
while(ISD_INT==1) //等待放音完毕的EOM中断信号 {;} LED=1;
//LED熄灭
ISD_STOP(); //放音完毕,发送stop指令 if (READ_ISD_OVF()==1) break;
while(RUN==1) { if (STOP==0)
break; if(RUN==0) DELAYms(20); k++;
//指向下一段放音}
//如果RUN再次按下,开始播放下一段语音
//等待RUN键再次按下
//如果按下STOP按键,则芯片复位
//检查芯片是否溢出 ,如溢出则停止放音,芯片复位
}while(RUN==0);
//RUN键再次按下,播放下一段语音
//发送stop指令
//停止本次操作并进入省电状态}}
}ISD_STOP(); ISD_PD();
//************************************ //ISD4002 SPI串行发送一个字节子程序,8位数据 //************************************ void ISD_WRITE(uchar isdx) { uchar i;
ISD_SS=0; ISD_SCLK=0; for(i=0;i
//片选使能,打开SPI通信端
//时钟置0
//SPI串行发送一个字节子程序
//8位依次发送
//取最低位,为1则数据线置1
{ if ((isdx&0x01)==1)
{ISD_MOSI=1;} else
//为0则数据线置0
{ISD_MOSI=0;}
isdx=isdx>>1;
ISD_SCLK=1;
DELAY(2);
ISD_SCLK=0;
DELAY(2);}}
//*******************************
//发送stop指令
//*******************************
void ISD_STOP(void)
{ DELAY(10);
ISD_WRITE(0x30);
ISD_SS=1;
DELAYms(50);}
//*******************************
//发送上电指令,并延迟50ms
//*******************************
void ISD_PU(void)
{ DELAY(10);
ISD_SS=0;
ISD_WRITE(0x20);
ISD_SS=1;
DELAYms(50);}
//*******************************
//发送省电指令,并延迟50ms
//*******************************
void ISD_PD(void)
{DELAY(10);
ISD_WRITE(0x10);
ISD_SS=1;
DELAYms(50);}
//*******************************
//发送play指令
//*******************************
void ISD_PLAY(void)
{LED=0;
ISD_WRITE(0xf0);
ISD_SS=1;}
//*******************************
//发送rec指令
//*******************************
void ISD_REC(void)
{LED=0;
ISD_WRITE(0xb0);
ISD_SS=1;} //先发低位再发高位,依次发送 //时钟产生上升沿 锁存输入的数据 //延时使数据稳定 //回复时钟低电平 //发送stop指令程序 //停止录音或放音操作,指令代码0X11 0 //发送上电指令程序 //器件上电,指令代码0010 0 //发送省电指令程序 //停止本次操作并进入省电状态,指令代码0X01 X //发送play指令程序 //指示灯亮 //在下一个地址开始放音,指令代码1111 1/0 //发送rec指令程序 //指示灯亮 //从下一个地址开始录音
//*******************************
//发送setplay指令
//*******************************
void ISD_SETPLAY(uchar adl,uchar adh)
{ ISD_WRITE(adl);
adh=adh||0xe0; ISD_WRITE(adh); ISD_SS=1;} //发送setplay指令程序 //发送放音起始地址低位 //从地址开始放音 //发送放音起始地址高位
//*******************************
//发送setrec指令
//*******************************
void ISD_SETREC(uchar adl,uchar adh) //发送setrec指令程序
{ ISD_WRITE(adl);
adh=adh||0xa0; ISD_WRITE(adh); ISD_SS=1;} //发送录音起始地址低位 //从地址开始录音 //发送录音起始地址高位
//************************************
//检查芯片是否溢出(读OVF,并返回OVF值)
//************************************
uchar READ_ISD_OVF(void)
{ ISD_SS=0;
DELAY(2); ISD_SCLK=0; DELAY(2); ISD_SCLK=1; ISD_SCLK=0; DELAY(2); if (ISD_MISO==1) { ISD_SS =1; //只读第1位数据 //关闭SPI通信端 //时钟信号下降沿时输出数据 //先产生时钟上升沿 //读溢出标志OVF程序 //片选有效 ISD_STOP(); return 1; //发送stop指令 //OVF为1,返回1} //关闭SPI通信端 else{ ISD_SS =1; }} ISD_STOP(); return 0; //发送stop指令 //OVF为0,返回0
//************************************
//芯片溢出,LED闪烁提醒停止录音
//************************************
void ISD_OVF(void)
{while(RUN==0)
//LED闪烁程序 //为0 表示键在按下 还未释放 //指示灯灭 //延时指示灯闪烁 //指示灯亮 { LED=1; DELAYms(300); LED=0; DELAYms(300);}}
void DELAY(uint n)
{while(n!=0)
{n--;}} //延迟n微秒
void DELAYms(uint n)
{ TMOD=0x01;
while(n!=0)
{ TH0=0xfc; TL0=0x18; TR0=1; while(TF0!=1) {;} TF0=0; TR0=0; n--;}} //延迟n毫秒 //T0 16位定时 //12MHZ晶振时 定时1ms
void mimakey(void)
{ uchar i,key;
//密码锁 设置密码、输入密码子程序 //i循环变量 key键号暂存器 //解锁标志位 bit keyok; for(i=0;i=0x0a) {do{key=keyin();}while(key>=0x0a);} //不是取消键且输入键号不是0~9的数字键时 等待1位数输入 mima[i]=key; diss[i]=15; disp(diss); //密码数字存于mima暂存器中 //每输入一位密码数码管显示“F” //送显示 } if(key!=0x0d) { key=keyin(); if (key==0x0d); else //6位密码输入完成时 看是否要确认;未完成6位输入时 返回 //等待按键输入 //是取消键时 输入密码取消 //不是取消键时 等待输入密码确认 { if(key!=0x0c) while(keyin()!=0x0c);//等待确认键按下 while(page_rd(0,6,&diss[0])==0); //在2402中读取密码 keyok=1; //把解锁标志位设为1 解锁 for(i=0;i
//*************以上为 输入密码状态*************// //*************以下为设置密码状态*************// if(keyok==1) //在开锁状态下 可以设置密码或关锁 {if(key==0x0d) //开锁状态时 按下取消键时 关锁 {keyok=0;right=0;error=1; //解锁状态位设为0 闭锁 }if(key==0x0a) //是设定键时 进入设置密码状态 {for(i=0;i=0x0a) {do{key=keyin();}while(key>=0x0a);} //不是取消键且输入键号不是0~9的数字键时 等待1位数字键输入 //密码数字存于mima暂存器中 mima[i]=key; diss[i]=14; //每输入一位密码数码管显示“E” disp(diss); //送显示 }if(key!=0x0d) {key=keyin(); if (key==0x0d); //6位密码输入完成时 看是否要确认;未完成6位输入时 返回 //读一位键 //是取消键时 设置密码取消 else //不是取消键时 等待设置密码确认 while(keyin()!=0x0c); //等待确认键按下 }}}} { if(key!=0x0c) while(page_wr(0,6,&mima[0])==0); //密码写入24lc02 //*************以上为设置密码状态*************// void disp(uchar idata *d) //显示子程序
{uchar j;
COM=0x90; for(j=0;j
DAT=table[*d]; d++; uchar keyin(void)
{ uchar j;
}
uchar deky(void)
{uchar k;
} do //读键号 {while(deky()==0); COM=0x40; j=DAT; j=j&0x3f; }while(j>=0x0e); //监测有键按下吗 无键时等待 //读FIFO/传感器RAM 不自动加1 地址为0 //读数据 //读低6位 D5D4D3为键盘所在列号 D2D1D0为键盘所在行号 //只读取0~9和A~D键 不读取E和F键 //返回键号 return(j); //监测有无按键按下 k=COM; return(k&0x03); //读状态 //只监测2行按键 有键返回1 无键返回0
/*-----------------------------------------------
调用方式:void start_bit(void)
函数说明:2402开始位
在时钟端SCL为高电平时,数据端SDA发生由高到低的变化,为起始条件
启动I2C总线
-----------------------------------------------*/
void start_bit(void)
{ SCL=1;//_nop_();
SDA=1;//_nop_();
SDA=0;//_nop_();
SCL=0;//_nop_();}
/*-----------------------------------------------
调用方式:void stop_bit(void)
函数说明:2402停止位
在时钟端SCL为高电平时,数据端SDA发生由低到高的变化,为停止条件
停止I2C总线数据传输
-----------------------------------------------*/
void stop_bit(void)
{ SDA=0;//_nop_();
SCL=1;//_nop_();
SDA=1;//_nop_();}
/*-----------------------------------------------
调用方式:void mast_ack(void)
函数说明:2402主答函数
主器件在收发每一个字节后产生一个时钟应答脉冲,
在这期间,发送器必须保证SDA为高,由接收器SDA拉低,
称为应答信号(ACK)。
-----------------------------------------------*/
void mast_ack(void)
{ SCL=0;_nop_();
SDA=0;_nop_();
SCL=1;_nop_();
SCL=0;_nop_();
SDA=1;_nop_();}
/*-----------------------------------------------
调用方式:write_8bit(uchar ch)
函数说明:2402写一个字节(8位)数据
-----------------------------------------------*/
bit write_8bit(uchar ch)
{ uchar i=8;
bit fan_w;
SCL=0;_nop_();
while(i--)
{SDA=(bit)(ch&0x80); //取字节的最高位
_nop_();
ch
SCL=1;_nop_(); //上升沿锁存数据
SCL=0;_nop_() }
SDA=1;_nop_();
SCL=1;_nop_();
fan_w=SDA; //读应答信号
SCL=0;_nop_();
return(fan_w); //返回应答信号
}
/*-----------------------------------------------
调用方式:void page_wr(uint firstw_ad,uint counter,uint data *firstr_ad)
函数说明:2402页面写函数,firstw_ad为写入字节单元的首地址,
*firstr-ad为被写入数据所在首地址指针
counter为写入数据字节数
-----------------------------------------------*/
uchar page_wr(uint firstw_ad,uint counter,uchar *firstr_ad)
{ uchar data *ufirstr_ad;
ufirstr_ad=firstr_ad;
start_bit(); //写开始位
if(write_8bit(0xA0)!=0){stop_bit();return(0);} //写命令
if(write_8bit(firstw_ad)!=0){stop_bit();return(0);}//写首地址
while(counter--) //写字节数减1
{if(write_8bit(*ufirstr_ad)!=0){stop_bit();return(0);}//写1字节
ufirstr_ad++; //地址加1
} stop_bit(); //写停止位
return(1);}
/*-----------------------------------------------
调用方式:void page_rd(uint firstrd_ad,uint count,uint firstwr_ad)
函数说明:2402页面读函数,firstrd-ad为所读字节首地址,count为读字节数
*ufirstwr-ad为读出数据存储首地址指针
-----------------------------------------------*/
uchar page_rd(uint firstrd_ad,uint count,uchar *firstwr_ad)
{ uchar j=8;
uchar data *ufirstwr_ad;
ufirstwr_ad=firstwr_ad;
start_bit(); //写开始位
if(write_8bit(0xA0)!=0){stop_bit();return(0);} //写命令
if(write_8bit(firstrd_ad)!=0){stop_bit();return(0);}//写首地址
start_bit(); //写开始位
if(write_8bit(0xA1)!=0){stop_bit();return(0);} //读命令
while(count--) //读字节数减1
{ uchar i=8;
while(i--)
{(*ufirstwr_ad)
if(SDA) (*ufirstwr_ad)|=0x01; //数据端为1时 存1
SCL=0; _nop_();}
ufirstwr_ad++; //地址加1
mast_ack(); //应答信号 }
while(j--)
{ (*ufirstwr_ad)
SCL=0;_nop_();_nop_();SCL=1;
if(SDA) (*ufirstwr_ad)|=0x01; }
stop_bit(); //写停止位
return(1);}
//24c02________________________________在上面
语音录放:
#include
#define uint unsigned int
#define uchar unsigned char
sbit ISD_SS = P1^0; //ISD4002片选
sbit ISD_SCLK = P1^1; //ISD4002时钟
sbit ISD_MOSI = P1^2; //ISD4002数据输入
sbit ISD_MISO = P1^3; //ISD4002数据输出
sbit ISD_INT =
sbit PR = P3^3; P1^4; //ISD4002溢出或放音结束中断 //PR=1录音 PR=0放音
sbit RUN = P1^5;
sbit STOP = P1^6;
sbit LED = //执行录音或放音 //复位 //指示灯 P1^7;
//************** 函数声明 **********************
void ISD_WRITE(uchar isdx);
void ISD_STOP(void);
void ISD_PU(void);
void ISD_PD(void);
void ISD_PLAY(void);
void ISD_REC(void); //SPI串行发送一个字节子程序 //发送stop指令程序 //发送上电指令程序 //发送省电指令程序 //发送play指令程序 //发送rec指令程序
void ISD_SETPLAY(uchar adl,uchar adh); //发送setplay指令程序
void ISD_SETREC(uchar adl,uchar adh); //发送setrec指令程序
uchar READ_ISD_OVF(void);
void ISD_OVF(void);
void DELAY(uint n);
//读溢出标志OVF程序 //LED闪烁程序 //延迟n微秒 //延迟n毫秒 void DELAYms(uint n);
//************************************************************************
//主程序
//功能:1.录音时,按住RUN键,LED点亮开始录音,松开RUN即可停止录音
// 再次按下RUN键,LED点亮开始录第二段音,依次类推,直到芯片溢出。
// 按stop键芯片复位
// 2.放音时,按一下RUN键,即播放一段语音。 按stop键芯片复位。
//************************************************************************ void main(void)
{P0=P1=P2=P3=0xff;
while(1) { while (RUN==1) //等待RUN键按下 //初始化 {if(RUN==0) //按键防抖动 {DELAYms(20);}} //RUN键按下为0,ISD上电并延迟50ms //停止本次操作并进入省电状态 //SD上电并延迟50ms //如果PR=1则转入录音部分 ISD_PU(); ISD_PD(); ISD_PU(); if (PR==1) {DELAYms(500); //延迟录音 指定地址录音 ISD_SETREC(0x00,0x00); //发送0x0000h地址的setplay指令 do{ ISD_REC(); //发送rec指令 下一个地址开始录音 //键未松开 等待录音完毕 while(RUN==0) {if (ISD_INT==0) //如果芯片溢出 ISD_OVF(); //进行LED闪烁提示} if (ISD_INT==0) //录音溢出,按键RUN释放 则退出录音。则芯片复位 break; LED=1; ISD_STOP(); while(RUN==1) { if(STOP==0) break; if (RUN==0) DELAYms(500);}} //如果RUN再次按下,开始录制下一段语音 //按键释放,未满,录音完毕,LED熄灭 //发送停止命令 //如果RUN未按下 查询 RUN和STOP键 //如果按下STOP按键,则芯片复位
while(RUN==0);}
else
{while(RUN==0){;}
//如果PR==0则转入放音部分 //未释放按键时等待 ISD_SETPLAY(0x00,0x00); //发送setplay指令,从0x0000地址开始放音 do { ISD_PLAY(); DELAY(20); while(ISD_INT==1) //等待放音完毕的EOM中断信号 {;} LED=1; //LED熄灭 //发送放音指令 ISD_STOP(); //放音完毕,发送stop指令 if (READ_ISD_OVF()==1) break; while(RUN==1) {if (STOP==0) break; if(RUN==0) //如果RUN再次按下,开始播放下一段语音 //等待RUN键再次按下 //检查芯片是否溢出 ,如溢出则停止放音,芯片复位 //如果按下STOP按键,则芯片复位
DELAYms(20);} //RUN键再次按下,播放下一段语音} //发送stop指令 //停止本次操作并进入省电状态}} }while(RUN==0); ISD_STOP(); ISD_PD();
//************************************
//ISD4002 SPI串行发送一个字节子程序,8位数据 //************************************
void ISD_WRITE(uchar isdx)
{ uchar i;
ISD_SS=0;
ISD_SCLK=0;
for(i=0;i
{ if ((isdx&0x01)==1)
{ISD_MOSI=1;}
else
{ISD_MOSI=0;}
isdx=isdx>>1;
ISD_SCLK=1;
DELAY(2);
ISD_SCLK=0;
DELAY(2);
}}
//*******************************
//发送stop指令
//*******************************
void ISD_STOP(void)
{ DELAY(10);
ISD_WRITE(0x30);
ISD_SS=1;
DELAYms(50);}
//*******************************
//发送上电指令,并延迟50ms
//*******************************
void ISD_PU(void)
{ DELAY(10);
ISD_SS=0;
ISD_WRITE(0x20);
ISD_SS=1;
DELAYms(50);}
//*******************************
//发送省电指令,并延迟50ms
//*******************************
void ISD_PD(void)
{ DELAY(10); //SPI串行发送一个字节子程序 //片选使能,打开SPI通信端 //时钟置0 //8位依次发送 //取最低位,为1则数据线置1 //为0则数据线置0 //先发低位再发高位,依次发送 //时钟产生上升沿 锁存输入的数据 //延时使数据稳定 //回复时钟低电平 //发送stop指令程序 //停止录音或放音操作,指令代码0X11 0 //发送上电指令程序 //器件上电,指令代码0010 0 //发送省电指令程序
ISD_WRITE(0x10);
ISD_SS=1; DELAYms(50);} //停止本次操作并进入省电状态,指令代码0X01 X
//*******************************
//发送play指令
//*******************************
void ISD_PLAY(void)
{LED=0;
//发送play指令程序 //指示灯亮 ISD_WRITE(0xf0); ISD_SS=1;} //在下一个地址开始放音,指令代码1111 1/0
//*******************************
//发送rec指令
//*******************************
void ISD_REC(void)
{ LED=0;
//发送rec指令程序 //指示灯亮 ISD_WRITE(0xb0); ISD_SS=1;} //从下一个地址开始录音
//*******************************
//发送setplay指令
//*******************************
void ISD_SETPLAY(uchar adl,uchar adh)
{ ISD_WRITE(adl);
adh=adh||0xe0; ISD_WRITE(adh); ISD_SS=1;} //发送setplay指令程序 //发送放音起始地址低位 //从地址开始放音 //发送放音起始地址高位
//*******************************
//发送setrec指令
//*******************************
void ISD_SETREC(uchar adl,uchar adh) //发送setrec指令程序 { ISD_WRITE(adl);
adh=adh||0xa0; ISD_WRITE(adh); ISD_SS=1;} //发送录音起始地址低位 //从地址开始录音 //发送录音起始地址高位
//************************************
//检查芯片是否溢出(读OVF,并返回OVF值)
//************************************
uchar READ_ISD_OVF(void)
{ ISD_SS=0;
DELAY(2); ISD_SCLK=0; DELAY(2); ISD_SCLK=1; ISD_SCLK=0; DELAY(2); //时钟信号下降沿时输出数据 //先产生时钟上升沿 //读溢出标志OVF程序 //片选有效
if (ISD_MISO==1) { ISD_SS =1; }else //只读第1位数据 //关闭SPI通信端 ISD_STOP(); return 1; //发送stop指令 //OVF为1,返回1 { ISD_SS =1; }} ISD_STOP(); return 0; //关闭SPI通信端 //发送stop指令 //OVF为0,返回0
//************************************
//芯片溢出,LED闪烁提醒停止录音
//************************************
void ISD_OVF(void)
{while(RUN==0)
//LED闪烁程序 //为0 表示键在按下 还未释放 //指示灯灭 //延时指示灯闪烁 //指示灯亮 { LED=1; DELAYms(300); LED=0; DELAYms(300);}}
void DELAY(uint n)
{while(n!=0)
{n--;}} //延迟n微秒
void DELAYms(uint n)
{ TMOD=0x01;
while(n!=0)
{TH0=0xfc; TL0=0x18; TR0=1; while(TF0!=1) {;} TF0=0; TR0=0; n--;}} //延迟n毫秒 //T0 16位定时 //12MHZ晶振时 定时1ms
四、总结:
本课题的总结与体会:
语音电子开关身份认证系统主要由说话人识别模块、门锁控制电机以及门锁等部分组成。在训练
时,说话人的声音通过麦克风进入说话人语音信号采集前端电路,由语音信号处理电路对采集的语音信号进行特征化和语音处理,提取说话人的个性特征参数进行存储,形成说话人特征参数数据库。在识别时,将待识别语音与说话人特征参数数据库进行匹配,通过输出电路控制门锁电机,最终实现对门锁的控制。另外还具有语言回答密码输入功能。
该课题主要是通过单片机控制按键等操作,再通过语音识别芯片AP7003和语音回
放芯片ISD4002的结合,来整体的实现语音开关身份认证系统。本系统可以直接用于家庭和单位的门锁控制,也可以提取录放部分制作公交车报站系统,或者利用本系统制
作诸如电梯门口等。
创意及改进:
1、该系统还可以在此基础上添加双重密码控制,比如先输入每个要识别用户的个人短密码才可进行语音识别,可以通过长密码直接进入,输入管理员密码才可对语音进行训练等。
2、本系统的电子密码锁,输入接口实用8279芯片扩展14个按键,通过6位7段数码管完成显示。其中,键盘输入采用逐行扫描法,数码管显示采用动态显示方法。本系统可以在此基础上进行修改,完成相关的功能设计,比如可以增加限定密码次数、限定输入密码时间、密码错误声音报警等相关功能。
学到的知识:
AT89C51芯片:
AT89C51是一种带4K字节FLASH存储器(FPEROM—Flash Programmable and Erasable Read Only Memory)的低电压、高性能CMOS 8位微处理器,俗称单片机。AT89C2051是一种带2K字节闪存可编程可擦除只读存储器的单片机。单片机的可擦除只读存储器可以反复擦除1000次。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器,AT89C2051是它的一种精简版本。AT89C51单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。
VCC:供电电压。
GND:接地。
P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。当P0口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的低八位。在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须接上拉电阻。
P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为低八位地址接收。
P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。
P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。
P3口也可作为AT89C51的一些特殊功能口,如下表所示:
口管脚 备选功能
P3.0 RXD(串行输入口)
P3.1 TXD(串行输出口)
P3.2 /INT0(外部中断0)
P3.3 /INT1(外部中断1)
P3.4 T0(计时器0外部输入)
P3.5 T1(计时器1外部输入)
P3.6 /WR(外部数据存储器写选通)
P3.7 /RD(外部数据存储器读选通)
P3口同时为闪烁编程和编程校验接收一些控制信号。
RST:复位输入。当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。
ALE/PROG:当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的低位字节。在FLASH编程期间,此引脚用于输入编程脉冲。在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。因此它可用作对外部输出的脉冲或用于定时目的。然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。如想禁止ALE的输出可在SFR8EH地址上置0。此时, ALE只有在执行MOVX,MOVC指令是ALE才起作用。另外,该引脚被略微拉高。如果微处理器在外部执行状态ALE禁止,置位无效。
/PSEN:外部程序存储器的选通信号。在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。
/EA/VPP:当/EA保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器。在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。
XTAL1:反向振荡放大器的输入及内部时钟工作电路的输入。
XTAL2:来自反向振荡器的输出。
振荡器特性:
XTAL1和XTAL2分别为反向放大器的输入和输出。该反向放大器可以配置为片内振荡器。石晶振荡和陶瓷振荡均可采用。如采用外部时钟源驱动器件,XTAL2应不接。有余输入至内部时钟信号要通过一个二分频触发器,因此对外部时钟信号的脉宽无任何要求,但必须保证脉冲的高低电平要求的宽度。
8279芯片:
DB0~DB7:双向数据总线。在CPU与8279间做数据与命令传送。
CLK:8279的系统时钟,100KHz为最佳选择。
RESET:复位输入线。输入HI时可复位8279。
CS:芯片选择信号线。当这个输入引脚为低电平时,可将命令写入8279或读取8279的数据。
A0:缓冲器地址选择线。A0=0时,读写一般数据;A0=1时,读取状态标志位或写入命令。
RD:读取控制线。RD=0时,8279输送数据到外部总线。
WR:写入控制线。WR=0时,8279从外部总线接收数据。
IRQ:中断请求。平常IRQ为LO,在键盘模式下,每次读取FIFO/SENSOR RAM的数据时,IRQ变为HI,读取后转为LO;在传感器模式下,只要传感器一有变化,就会使IRQ变为HI,读取后转为LO。
SL0~SL3:扫描按键开关或传感器矩阵及显示器,可以是编码模式(16对1)或解码模式(4对1)。
RL0~RL7:键盘/传感器的返回线。无按键被按时,返回线为HI;有按键被按时,该按键的返回线为LO。在激发输入模式时,为8位的数据输入。
SHIFT:在键盘扫描模式时,引脚的输入状态会与其它按键的状态一同储存(在BIT6),内部有上拉电阻,未按时为HI,按时为LO。
CNTL/STB:在键盘扫描模式时,引脚的输入状态会与SHIFT以及其它按键的状态同一储存,内部有上拉电阻,未按时为HI,按时为LO。在激发输入模式时,作为返回线8位数据的使能引脚。
OUTA0~OUTA3:动态扫描显示的输出口(高4位)。
OUTB0~OUTB3:动态扫描显示的输出口(低4位)。
BD:消隐输出线。
JL-034B / C (全指向式)
1、规格:dia.9.7x6.7mm
2、敏感度/dB值:(0dB=1V/Pa),-36dB,-38dB,-40dB,-42dB,-44dB,-46dB
3、频率:20~20kHz
4、电阻:
5、信号杂讯比:>55dB
ISD4002语音回放芯片
特性:
●单片4至8分钟语音录放,4、5、6及8分钟
●无需开发系统
●内置微控制器串行通信接口
●3V单电源工作
●多段信息处理
●工作电流25-30mA,维持电流1μA
●不耗电信息保存100年(典型值)
●高质量、自然的语音还原技术
●100,000次录音周期(典型值)
●自动静噪功能
●片内免调整时钟,可选用外部时钟
引脚分布图:
电源:(VCCA,VCCD)
地线:(VSSA,VSSD) 芯片内部的模拟和数字电路也使用不同的地线。
同相模拟输入(ANA IN+) 这是录音信号的同相输入端。
反相模拟输入(ANA IN-) 差分驱动时,这是录音信号的反相输入端。
音频输出(AUD OUT) 提供音频输出,可驱动5KΩ的负载。
片选(SS) 此端为低,即选中ISD4002系列。
串行输入(MOSI) 此端为串行输入端,
串行时钟(SCLK) ISD的时钟输入端,
中断(/INT) 本端为漏极开路输出。
OVF标志----指示ISD的录、放操作已到达存储器的未尾。
EOM标志----只在放音中检测到内部的EOM标志时,此状态位才置1。
行地址时钟(RAC) 漏极开路输出。
外部时钟(XCLK):本端内部有下拉元件。
自动静噪(AMCAP):当录音信号电平下降到内部设定的某一阈值以下时,自动静噪功能使信号衰弱,这样有助于养活无信号(静音)时的噪声。
AP7003语音识别芯片: 特性:
1.内置麦克风放大器;
2.内置A/D转换器;
3.DIP40双列直插式封装;
4.识别12组1.5秒时长字词;
5.I/O口具有2个普通输入、4个触发输入、2个输出口(分别有4个和12个输出)、2个LED驱动;
6.指令优化以方便用户使用;
7.2.4V-4.5V工作电压,且具备低功耗模式。
引脚:
引脚:
1 PORES 清除A输出口(POA)输出状态,高有效
2 GNDD 数字地
3 LED1 驱动LED,低有效,可编程用于指示语音录音的状态
4 LED2 驱动LED,低有效,可编程用于指示语音识别的结果
8~5 POB1~POB4 B输出口,可编程用于键盘驱动识别的结果
12~9 PIT1~PIT4 低脉冲触发输入,内部有上拉电阻,可编程用于键盘输入
13 VDDD 数字电源
14 CAPV 通过电容接地,对内部电压进行滤波
15 OSC1 振荡频率控制,通过56KΩ电阻接地
17、18 PIM1、PIM2 普通输入引脚,可编程用于芯片工作模式控制:PIM1=1时,芯片具有识别功能;PIM2=1时,A端口可以输出。反之不能 进行识别或A端口不能输出
19 TEST 测试端,芯片出厂时测试用
20 POSL 对A输出口有效电平进行选择:高时A口高有效;低时A口低有效
21 GNDA 模拟地涑隹谟行У缙浇
22 TREF 语音输入门限控制端
23 A2OUT 第二级放大器输出端
24 A1IN 第一级放大器负输入端
26 A1OUT 第一级放大器输出端
27 MICP 电子麦克风电源供应端
28 VDDA 模拟电源
29~40 POA1~POA12 A输出口,可编程用于语音录入/语音识别对的存储体指示
16、25 NC 未用引脚