⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 isd4002.c

📁 单片机应用系统(光盘内容)
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -