📄 51
字号:
#include <reg51.h> //语音识别程序
#include <absacc.h>
#include <intrins.h>
#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 = P3^3; //ISD4002溢出或放音结束中断
sbit PR = P1^4; //PR=1录音 PR=0放音
sbit RUN = P1^5; //执行录音或放音
sbit STOP = P1^6; //复位
sbit LED = P1^7; //指示灯
sbit SDA= P3^1; //24c02数据端
sbit SCL= P3^0; //24c02时钟端
sbit error= P2^4; //闭锁指示端
sbit right= P2^5; //开锁指示端 和开锁输出
#define COM XBYTE [0x7fff] //8279命令状态地址A11 A14
#define DAT XBYTE [0x77fF] //8279数据地址
sbit clflag=ACC^7; //记录状态字 最高位
bit int0_flag=0; //中断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
}; //共阳极数码管显示段码
uchar idata diss[8]; //显示用数据暂存器 8位数据
uchar idata mima[6]; //密码用数据暂存器 6位数据
//************** 函数声明 **********************
void reply(void); //自动回答程序
void ISD_PR(void); //手动对ISD录放音
void ISD_WRITE(uchar isdx); //SPI串行发送一个字节子程序
void ISD_STOP(void); //发送stop指令程序
void ISD_PU(void); //发送上电指令程序
void ISD_PD(void); //发送省电指令程序
void ISD_PLAY(void); //发送play指令程序
void ISD_REC(void); //发送rec指令程序
void ISD_SETPLAY(uchar adl,uchar adh); //发送setplay指令程序
void ISD_SETREC(uchar adl,uchar adh); //发送setrec指令程序
uchar READ_ISD_OVF(void); //读溢出标志OVF程序
void ISD_OVF(void); //LED闪烁程序
void DELAY(uint n); //延迟n微秒
void DELAYms(uint n); //延迟n毫秒
uchar keyin(); //8279读键号子程序
uchar deky(); //8279监测有无按键按下子程序
void disp(uchar idata *d); //8279显示子程序
void start_bit(void); //2402开始位
void stop_bit(void); //2402停止位
void mast_ack(void); //2402主答函数
bit write_8bit(uchar ch); //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高优先级
IE=0X81; //INT0开中断,CUP开中断
COM=0xd1; //11010001 总清除命令
do{ACC=COM;} //读状态字 直到清除完成
while(clflag==1); //读状态字 最高位
COM=0x00; //键盘/显示器工作方式 左端送入8×8显示双键锁定编码扫描
COM=0x34; //时钟分频 20分频
right=0;error=1; //默认闭锁
//************以下测试用*****************//
for(i=0;i<6;i++) {mima[i]=i+2;} //设置初始密码为234567 测试用
while(page_wr(0,6,&mima[0])==0); //写入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(); //RUN键按下为0,ISD上电并延迟50ms
ISD_PD(); //停止本次操作并进入省电状态
ISD_PU(); //SD上电并延迟50ms
ah=(nmb_flag+1)/2-1; //计算高两位地址 ah
al=0x80*(1-nmb_flag%2); //计算低八位地址 al
ISD_SETPLAY(ah,al); //发送setplay指令,从指定地址<ah,al>地址开始放音
ISD_PLAY(); //发送放音指令
LED=0; //LED亮
DELAY(20);
while(ISD_INT==1) //等待放音完毕的EOM中断信号
{;}
LED=1; //LED熄灭
ISD_STOP(); //放音完毕,发送stop指令
ISD_PD(); //停止本次操作并进入省电状态
}
void service_int0() interrupt 0 using 2 //外部中断0 用第二组寄存器
{
int0_flag=1;
nmb_flag=P2&0x07;
}
void ISD_PR(void) //手动对ISD录放音
{
uchar k=1; //指示录放音段数的变量
uchar al,ah; //录放音的地址变量
while(RUN==0) //RUN键按下
{
DELAYms(20); //按键防抖动
if(RUN==1) //按键防抖动
{
break;
}
ISD_PU(); //RUN键按下为0,ISD上电并延迟50ms
ISD_PD(); //停止本次操作并进入省电状态
ISD_PU(); //SD上电并延迟50ms
if (PR==1) //如果PR=1则转入录音部分
{
DELAYms(500); //延迟录音 指定地址录音
ISD_SETREC(0x00,0x00); //发送0x0000h地址的setplay指令
do
{
ah=(k+1)/2-1; //计算高两位地址 ah
al=0x80*(1-k%2); //计算低八位地址 al
ISD_SETREC(ah,al); //发送指定地址<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) //如果RUN未按下 查询 RUN和STOP键
{
if(STOP==0) //如果按下STOP按键,则芯片复位
break;
if (RUN==0) //如果RUN再次按下,开始录制下一段语音
DELAYms(500);
k++; //指向下一段录音
}
}while(RUN==0);
}
else //如果PR==0则转入放音部分
{
while(RUN==0){;} //未释放按键时等待
ISD_SETPLAY(0x00,0x00); //发送setplay指令,从0x0000地址开始放音
do
{
ah=(k+1)/2-1; //计算高两位地址 ah
al=0x80*(1-k%2); //计算低八位地址 al
ISD_SETPLAY(ah,al); //发送setplay指令,从指定地址<ah,al>地址开始放音
ISD_PLAY(); //发送放音指令
DELAY(20);
while(ISD_INT==1) //等待放音完毕的EOM中断信号
{;}
LED=1; //LED熄灭
ISD_STOP(); //放音完毕,发送stop指令
if (READ_ISD_OVF()==1) //检查芯片是否溢出 ,如溢出则停止放音,芯片复位
break;
while(RUN==1) //等待RUN键再次按下
{
if (STOP==0) //如果按下STOP按键,则芯片复位
break;
if(RUN==0) //如果RUN再次按下,开始播放下一段语音
DELAYms(20);
k++; //指向下一段放音
}
}while(RUN==0); //RUN键再次按下,播放下一段语音
}
ISD_STOP(); //发送stop指令
ISD_PD(); //停止本次操作并进入省电状态
}
}
//************************************
//ISD4002 SPI串行发送一个字节子程序,8位数据
//************************************
void ISD_WRITE(uchar isdx) //SPI串行发送一个字节子程序
{
uchar i;
ISD_SS=0; //片选使能,打开SPI通信端
ISD_SCLK=0; //时钟置0
for(i=0;i<8;i++) //8位依次发送
{
if ((isdx&0x01)==1) //取最低位,为1则数据线置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) //发送stop指令程序
{
DELAY(10);
ISD_WRITE(0x30); //停止录音或放音操作,指令代码0X11 0
ISD_SS=1;
DELAYms(50);
}
//*******************************
//发送上电指令,并延迟50ms
//*******************************
void ISD_PU(void) //发送上电指令程序
{
DELAY(10);
ISD_SS=0;
ISD_WRITE(0x20); //器件上电,指令代码0010 0
ISD_SS=1;
DELAYms(50);
}
//*******************************
//发送省电指令,并延迟50ms
//*******************************
void ISD_PD(void) //发送省电指令程序
{
DELAY(10);
ISD_WRITE(0x10); //停止本次操作并进入省电状态,指令代码0X01 X
ISD_SS=1;
DELAYms(50);
}
//*******************************
//发送play指令
//*******************************
void ISD_PLAY(void) //发送play指令程序
{
LED=0; //指示灯亮
ISD_WRITE(0xf0); //在下一个地址开始放音,指令代码1111 1/0
ISD_SS=1;
}
//*******************************
//发送rec指令
//*******************************
void ISD_REC(void) //发送rec指令程序
{
LED=0; //指示灯亮
ISD_WRITE(0xb0); //从下一个地址开始录音
ISD_SS=1;
}
//*******************************
//发送setplay指令
//*******************************
void ISD_SETPLAY(uchar adl,uchar adh) //发送setplay指令程序
{
ISD_WRITE(adl); //发送放音起始地址低位
adh=adh||0xe0; //从地址<A9~A0>开始放音
ISD_WRITE(adh); //发送放音起始地址高位
ISD_SS=1;
}
//*******************************
//发送setrec指令
//*******************************
void ISD_SETREC(uchar adl,uchar adh) //发送setrec指令程序
{
ISD_WRITE(adl); //发送录音起始地址低位
adh=adh||0xa0; //从地址<A9~A0>开始录音
ISD_WRITE(adh); //发送录音起始地址高位
ISD_SS=1;
}
//************************************
//检查芯片是否溢出(读OVF,并返回OVF值)
//************************************
uchar READ_ISD_OVF(void) //读溢出标志OVF程序
{
ISD_SS=0; //片选有效
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -