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

📄 111.c

📁 ISD4003的子程序,实现语音的录音与播放
💻 C
字号:
/*
  模块功能:键盘控制ISD录音和放音,并在每段放音结束后,显示下一段起始地址。
  完成日期:2007年8月30日
  备注:    PR端接1为录音,接0为放音。
            AN按控制录放音。
		    STOP控制复位。
*/
//--------------------------------------------函数声明-----------------------------------------------
#include <reg52.h>
#include <absacc.h>
#include <intrins.h>
#define uchar unsigned char
#define uint  unsigned int
#define  LINE1     0
#define  LINE2     1
#define  LINE1_HEAD    0x80
#define  LINE2_HEAD    0xC0
#define  LCD_DELAY_TIME   40
#define  DATA_MODE    0x38
#define  OPEN_SCREEN    0x0C
#define  DISPLAY_ADDRESS   0x80
#define  CLEARSCREEN    LCD_en_command(0x01)
//common part 
#define  HIGH   1
#define  LOW    0
#define  TRUE    1
#define  FALSE    0
#define  ZERO    0 
#define  MSB    0x80
#define  LSB    0x01

/*******************************************************************/

#define  LCDIO     P2
sbit LCD1602_RS=P1^4;  
sbit LCD1602_RW=P1^5;  
sbit LCD1602_EN=P1^6;
//--------------------------------------------变量定义-----------------------------------------------
sbit   SS   = P3^0;                               //片选
sbit   SCLK = P3^1;                               //ISD4004时钟
sbit   MOSI = P3^2;                               //数据输入
sbit   MISO = P3^3;                               //数据输出
sbit   INT  = P3^4;                               //中断

sbit   AN   = P1^0;                               //执行
sbit   STOP = P1^1;                               //复位
sbit   PR   = P1^2;                               //PR=1录音,PR=0放音
sbit   LED  = P1^3;                               //指示灯

sbit E_CLK =P3^7;                                 //同步时钟输入端
sbit RW_SID=P3^6;                                 //串行数据输入、输出端
unsigned char code tab[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
/******************** LCD PART *************************************/
void LCD_delay(void)   
{
 unsigned char i;
 for(i=LCD_DELAY_TIME;i>ZERO;i--)//be sure lcd reset
   ;
}
/********************************************************************/  
void LCD_en_command(unsigned char command)
{
 LCDIO=command;
 LCD1602_RS=LOW;   
 LCD1602_RW=LOW;
 LCD1602_EN=LOW;
 LCD_delay();
 LCD1602_EN=HIGH;
}
/********************************************************************/
void LCD_en_dat(unsigned char dat)
{
 LCDIO=dat;
 LCD1602_RS=HIGH;
 LCD1602_RW=LOW;
 LCD1602_EN=LOW;
 LCD_delay();
 LCD1602_EN=HIGH;
}
/********************************************************************/
void LCD_set_xy( unsigned char x, unsigned char y )
{
 unsigned char address;
 if (y == LINE1) 
  address = LINE1_HEAD + x;
 else 
     address = LINE2_HEAD + x;
 LCD_en_command(address); 
}
/********************************************************************/
void LCD_write_char( unsigned x,unsigned char y,unsigned char dat)
{
 LCD_set_xy( x, y ); 
 LCD_en_dat(dat);
}
/********************************************************************/
void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s)
{
    LCD_set_xy( X, Y ); //set address 
    while (*s)  // write character
    {
     LCDIO=*s;
        LCD_en_dat(*s);   
 s ++;
    }
}
/********************************************************************/
void LCD_init(void)
{ 
 CLEARSCREEN;//clear screen 
 LCD_en_command(DATA_MODE);//set 8 bit data transmission mode 
 LCD_en_command(OPEN_SCREEN);//open display (enable lcd display)
 LCD_en_command(DISPLAY_ADDRESS);//set lcd first display address 
 CLEARSCREEN;//clear screen
}
/********************************************************************/
/*********************** OTHER PART *********************************/
void delay_nms(unsigned int n)      
{
    unsigned int i=0,j=0;
    for (i=n;i>0;i--)
     for (j=0;j<1140;j++);  
}
/********************************************************************/



//--------------------------------------------------------------------------------------------------
// 函数名称: delaynms
// 入口参数: n:延时的毫秒数
// 函数功能: 延时N毫秒
//--------------------------------------------------------------------------------------------------
void delaynms(uchar n)
{
	uchar i,j;
	for(i=0;i<n;i++)
		for(j=0;j<120;j++)
			;
}

//===========================================ISD驱动模块============================================//
//--------------------------------------------------------------------------------------------------
// 函数名称: YS50
// 入口参数: 无
// 函数功能: 延时25ms,ISD4003上电后需要延时
//--------------------------------------------------------------------------------------------------
void  YS50()
{
delaynms(25);
/*
TMOD=1;
TH0=0x3C;                           //50mS延时初值置入
TL0=0xB0;
TR0=1;
while(!TF0);
TF0=0;
TR0=0;*/
}
//--------------------------------------------------------------------------------------------------
// 函数名称: ISDX
// 入口参数: d:要发送的命令
// 函数功能: 向ISD发送单字节命令
//--------------------------------------------------------------------------------------------------
void  ISDX(unsigned char d)
{
unsigned char i,j;
SS=0;                               //开片选
SCLK=0;                             //时钟SCLK=0
j=d;
for(i=0;i<8;i++)
{
if(j&0x01)                          //数据写 MOSI
MOSI=1;
else
MOSI=0;
SCLK=1;                             //时钟SCLK=1
j=j>>1;
SCLK=0;                             //时钟SCLK=0
}
SS=1; 
}
//--------------------------------------------------------------------------------------------------
// 函数名称: ISDX1
// 入口参数: d:要发送的指令字
// 函数功能: 向ISD发送2字节命令
//--------------------------------------------------------------------------------------------------
void  ISDX1(unsigned int d)
{
unsigned char i;
unsigned int j;
SS=0;                               //开片选
SCLK=0;                             //时钟SCLK=0
j=d;
for(i=0;i<16;i++)
{
if(j&0x0001)                        //数据写 MOSI
MOSI=1;
else
MOSI=0;
SCLK=1;                             //时钟SCLK=1
j=j>>1;
SCLK=0;                             //时钟SCLK=0
}
SS=1;  
}
//--------------------------------------------------------------------------------------------------
// 函数名称: UP
// 入口参数: 无
// 函数功能: ISD上电
//--------------------------------------------------------------------------------------------------
void  UP()
{
ISDX(0x20);                         //发00100XXXXXXXXXXX
SS=1;                               //关片选
YS50();                             //50mS延时
YS50();                             //50mS延时
}
//--------------------------------------------------------------------------------------------------
// 函数名称: STOPP
// 入口参数: 无
// 函数功能: ISD停止当前操作
//--------------------------------------------------------------------------------------------------
void  STOPP()
{
ISDX(0x30);                         //发 0X110XXX
SS=1;                               //关片选
YS50();                             //50mS延时
YS50();                             //50mS延时
}
//--------------------------------------------------------------------------------------------------
// 函数名称: DSTOP
// 入口参数: 无
// 函数功能: ISD停止当前操作并掉电
//--------------------------------------------------------------------------------------------------
void  DSTOP()
{
ISDX(0x10);                         //发0X010XXXXXXXXXX
SS=1;                               //关片选
YS50();                             //50mS延时
YS50();                             //50mS延时
}



//--------------------------------------------主函数-----------------------------------------------  
void main(void)
{
    bit key_flag=1;                             //延时参数
    uchar i,ad[4];                    //ISD高低位
	uint  isd_addr,temp;                        //ISD地址,j
    unsigned int Seg_Addr=0,seg_addr;
 
    SP=0x10;                                    //初始化
    P0=0xFF;
    P1=0xFF;
    P2=0xFF;
    P3=0xFF;
    EA=0;

	LCD_init();
	CLEARSCREEN;
   delay_nms(2);
 lab:
    LED=1;                                      //关指示灯
    DSTOP();                                    //ISD掉电
	
    while(key_flag)                             //等待AN按下
	  {
	    if (AN == 0)
		  delaynms(10);
		    if (AN == 0)
			  {
			    key_flag=0;
			  }
        ;
	  }
    key_flag=1;

    UP();                                       //ISD上电    
	isd_addr=0x0000;                            //ISD高低位地址置0  

    if(PR)                                      //PR=1 录音
      {
		UP();
		temp = isd_addr & 0x07ff ;
		isd_addr = temp | 0xa000 ;
		ISDX1(isd_addr);                        //SETREC

    rec:
		for (i=0; i<6; i++)
        {
		  YS50(); 
		}
		LED=0;
		ISDX(0xb0);                             // REC

		while(AN == 0)                          //等待按键放开
		  {
		    if (INT == 0)                       //遇到OVF
			  {
			    LED=1;
		        while(AN == 0) ;                //等待按键放开
		        SCLK=0;
				SS=1;
		        STOPP();
		        goto lab;
			  }
	        ;
		  }
		
		LED=1;
		STOPP();
		while(AN)                                //等待AN按键按下
		{
		  if (STOP == 0)
		    delaynms(10);
			  if (STOP == 0)                     //复位
			    {
				  SCLK=0;
				  SS=1;
		          STOPP();
		          goto lab;
				}
		}
		STOPP();
		goto rec;                                //按键按下返回录下一段
    }

  else                                           //PR=0 放音
    {
	  while(AN == 0);                            
	  temp = isd_addr & 0x07ff ;
	  isd_addr = temp | 0xe000 ;
	  ISDX1(isd_addr);                           //SETPLAY
	
 play: 
	  LED=0;
	  ISDX(0xf0);                                //PLAY
	
	  while(INT)
	    {
		  if (STOP == 0)
	        delaynms(10);
		      if (STOP == 0)
		        {
			      SCLK=0;
			      SS=1;
	              STOPP();
	              goto lab;
				}
		}
	
	  LED=1;                                     //遇到EOM或者OVF
	  STOPP();

	                                             //检测OVF   --_--  
	  SCLK=1;
	  SS=0;
	  for(i=0; i<16; i++)                        //读当前状态。EOM OVF 和 下一段起始地址
	    {	
		  _nop_();
		  _nop_();	      
		  SCLK=0;
		  _nop_();
		  _nop_();
		  Seg_Addr = Seg_Addr >> 1;	  
		  if(MISO)
		    {
			  Seg_Addr = Seg_Addr | 0x8000;
			}
		  SCLK=1;
		}
	  SS=1;
	  SCLK=0;
	  STOPP();

	  if(Seg_Addr & 0x0001)
	    {
	      goto lab;		                         //ISD溢出,则复位  
		}

	  else                                       //当前段结束
	    {
		  		  
          seg_addr = Seg_Addr / 4;  
		  ad[0]=tab[(uchar)((seg_addr&0xf000)>>12)];
          ad[1]=tab[(uchar)((seg_addr&0x0f00)>>8)];
		  ad[2]=tab[(uchar)((seg_addr&0x00f0)>>4)];
		  ad[3]=tab[(uchar)(seg_addr&0x000f)];
		  LCD_write_char(0,LINE1,ad[0]);
		  LCD_write_char(1,LINE1,ad[1]);
		  LCD_write_char(2,LINE1,ad[2]);
		  LCD_write_char(3,LINE1,ad[3]);
		  while(AN)                           //等待AN键按下
		    {
			  if (STOP == 0)
		        delaynms(10);
			      if (STOP == 0)
			        {
				      SCLK=0;                //复位
				      SS=1;
		              STOPP();
		              goto lab;
					}
			}
		
		  goto play;		                 //返回播放下一段 
		}
     }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -