ISD1760语音芯片SPI不能播放,独立模式可以播放

2019-03-24 17:57发布

程序如下:(硬件应该没问题)
SPI.H
#ifndef _SPI_H_  
#define _SPI_H_  

#include<reg51.h>  

//#include "typedef.h"  
#define uchar unsigned char
#define uint unsigned int

#define  PU   0x01  
#define  STOP   0x02  
#define  RESET   0x03  
#define  CLI_INT  0x04  
#define  RD_STATUS 0x05  
#define  RD_PLAY_PTR   0x06  
#define  PD   0x07  
#define  RD_REC_PTR   0x08  
#define  RD_DEVID 0x09  
#define  G_ERASE 0x43  
#define  RD_APC   0x44  
#define  WR_APC1   0x45  
#define  WR_APC2   0x65  
#define  WR_NVCFG   0x46  
#define  CHK_MEM 0x49  
#define  SET_PLAY   0x80  
#define  SET_REC   0x81  
#define  SET_ERASE   0x82  

#define   NOP  _nop_()

#define  HIGH 1  
#define  LOW 0  
/*  
#define  RIGHT 1  
#define  ERROR 0  

//#define SET_BIT(x,y)  (x|=(1<<y)) //x的y位置1  
//#define CLR_BIT(x,y)  (x&=~(1<<y)) //清x的y位  
//#define GET_BIT(x,y)  (x&(1<<y)) //读x的y位  
/*-----------------------------------------------------------------------  
//SR0_L 0 1 2 3 4 5 6 7  
//  CMD_Err   FULL     PU    EOM    INT     A0 A1 A2  

//SR0_H 8  9 10 11 12 13 14 15  
// A3 A4 A5 A6 A7 A8 A9 A10  

//SR1 0 1 2 3 4 5 6 7  
//    RDY    ERASE    PLAY    REC     SE1     SE2     SE3    SE4  

//APC 0 1 2 3 4 5 6 7  
//   VOL0   VOL1    VOL2  MON_IN   MIX_IN  SE_EDIT  SPI_FT  AUD/AUX(AUD线路输出,AUX直接驱动喇叭)  

//APC 8  9 10 11  
//   PWM_SPK  PU_AO  VALERT  EOM_EN(在SETPLAY模式下,置1遇到EOM则结束,否则继续播放)  
----------------------------------------------------------------------------*/  
/*  
sbit INT_1700 = SR0_L^4;  
sbit EOM = SR0_L^3;  
sbit PU_1700 = SR0_L^2;  
sbit FULL = SR0_L^1;  
sbit CMD_ERR = SR0_L^0;  

sbit REC_1700 = SR1^3;  
sbit PLAY_1700 = SR1^2;  
sbit ERASE_1700 = SR1^1;  
sbit RDY = SR1^0;  
*/  
sbit SS = P1^0;  
sbit SCLK = P1^1;  
sbit MOSI = P1^2;  
sbit MISO = P1^3;  


extern void  I_delay(void);  
extern void delay_ms(register unsigned int Count);  
extern void DogReset(void) reentrant;  

/**************************************************************************  
*    函数原型: void GetToneAdd(uchar cNum, Uint * ipStartAdd, Uint * ipEndAdd);  
*    功    能: 取出当前语音的首末地址  
**************************************************************************/  
void GetToneAdd(unsigned char cNum, unsigned int * ipStartAdd, unsigned int * ipEndAdd);  

/**************************************************************************  
*    函数原型: void ISD_Init(void);  
*    功    能: 初始化  
**************************************************************************/  
void  ISD_Init(void);  

/**************************************************************************  
*    函数原型: void ISD_PU(void);  
*    功    能: 上电  
**************************************************************************/  
void ISD_CHK_MEM(void);  

/**************************************************************************  
*    函数原型: void ISD_Up(void);  
*    功    能: 上电  
**************************************************************************/  
void  ISD_PU(void);  

/**************************************************************************  
*    函数原型: void ISD_Stop(void);  
*    功    能: 停止  
**************************************************************************/  
void ISD_Stop(void);  

/**************************************************************************  
*    函数原型: void ISD_Reset(void);  
*    功    能: 复位  
**************************************************************************/  
void ISD_Reset(void);  

/**************************************************************************  
*    函数原型: void ISD_PD(void);  
*    功    能: 掉电  
**************************************************************************/  
void ISD_PD(void);  

/**************************************************************************  
*    函数原型: void ISD_SendData(uchar BUF_ISD);  
*    功    能: 发送数据  
**************************************************************************/  
unsigned char ISD_SendData(unsigned char BUF_ISD);  

/**************************************************************************  
*    函数原型: void RdStatus(void);  
*    功    能: 读取状态  
**************************************************************************/  
void RdStatus(void);  

/**************************************************************************  
*    函数原型: void RdStatus(void);  
*    功    能: 读取ID  
**************************************************************************/  
unsigned char RD_DevID(void);  

/**************************************************************************  
*    函数原型: void RD_APC(void);  
*    功    能: 读取APC  
**************************************************************************/  
void RdAPC(void);  

/**************************************************************************  
*    函数原型: void ClrInt(void);  
*    功    能: 清除中断  
**************************************************************************/  
void ClrInt(void);  

/**************************************************************************  
*    函数原型: void ISD_WR_APC2(uchar voiceValue);  
*    功    能: WR_APC2  
**************************************************************************/  
void ISD_WR_APC2(unsigned char voiceValue);  

/**************************************************************************  
*    函数原型: void ISD_WR_NVCFG(void);  
*    功    能: 永久写入寄存器  
**************************************************************************/  
void ISD_WR_NVCFG(void);  

/**************************************************************************  
*    函数原型: void SetPLAY(uchar cNum);  
*    功    能: 定点播放  
**************************************************************************/  
void SetPLAY(unsigned char cNum);  

/**************************************************************************  
*    函数原型: void SetREC(uchar cNum);  
*    功    能: 定点录音  
**************************************************************************/  
void SetREC(unsigned char cNum);  

/**************************************************************************  
*    函数原型: void SetERASE(uchar cNum);  
*    功    能: 定点删除  

**************************************************************************/  
/*  
void SetERASE(uchar cNum);  

/**************************************************************************  
*    函数原型: void Erase_All(void);  
*    功    能: 全部删除  
**************************************************************************/  
void Erase_All(void);  

/**************************************************************************  
*    END  
*    END  
**************************************************************************/  
#endif



---------------ISD1760.C----------------------------------------------------------------------
/**************************************************************************  
*    SPI操作ISD1760  
*    SPI操作ISD1760  
**************************************************************************/  

#include<SPI.H>  
#include <intrins.h>


uchar bdata SR0_L;  
uchar bdata SR0_H;  
uchar bdata SR1;  
uchar ID,APCL=0,APCH=0;  

//-------------------------------------------------------------
//每10秒大约是80个十进制地址,即十六进制0x50,后一段声音越界
//就只会播前段声音的后面的一部分,遇到“EOM”停止.所以根据
//录的秒数乘以8,转化成十六进制数,得到大概地址,后面进行微调。
//-------------------------------------------------------------
uint caToneAdd[8]={0x0010,0x01ff};//0x007b,0x007c,0x009f,0x00a0,0x00ea,0x00fa,0x014f};
void I_delay(void)
{
  NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
//  NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
}
//----------------------------------------------------------------
//函数名称:Delay        
//入口参数:Z      
//出口参数:无
//函数功能:实现MS级的延时,Z为延时的MS数        
//----------------------------------------------------------------
void delay_ms( uint z )
{
  uint x,y;
  for ( x = z; x > 0; x-- )
  {
   for ( y = 110; y > 0; y-- );
  }
}
/**************************************************************************  
*    函数原型: void ISD_Init(void);  
*    功    能: 初始化  
**************************************************************************/  
void   ISD_Init(void){  
ISD_Reset();  
do{  
ISD_PU();  
RdStatus();  

}while((SR0_L&0x01)||(!(SR1&0x01))); //if(SR0_L^0==1){system Err}<CMD_Err==1>  

SBUF=RD_DevID();//读取芯片ID,----1760为0xa0  
ClrInt();  
ISD_WR_APC2(0xaf);  
RdAPC();  
}  

/**************************************************************************  
*    函数原型: void ISD_PU(void);  
*    功    能: 空间检查  
**************************************************************************/  
void ISD_CHK_MEM(void){  
ISD_SendData(CHK_MEM);  
ISD_SendData(0x00);  
SS=1;  
delay_ms(10);  
}  

/**************************************************************************  
*    函数原型: void ISD_PU(void);  
*    功    能: 上电  
**************************************************************************/  
void  ISD_PU(void){  
ISD_SendData(PU);  
ISD_SendData(0x00);  
SS=1;  
    delay_ms(50);  
}  

/**************************************************************************  
*    函数原型: void ISD_Stop(void);  
*    功    能: 停止  
**************************************************************************/  
/*  
void ISD_Stop(void){  
ISD_SendData(STOP);  
ISD_SendData(0x00);  
SS=1;  
    delay_ms(50);  
}  

/**************************************************************************  
*    函数原型: void ISD_Reset(void);  
*    功    能: 复位  
**************************************************************************/  
void ISD_Reset(void){  
ISD_SendData(RESET);  
ISD_SendData(0x00);  
SS=1;  
    delay_ms(50);  
}  

/**************************************************************************  
*    函数原型: void ISD_PD(void);  
*    功    能: 掉电  
**************************************************************************/  
/*  
void ISD_PD(void){  
ISD_SendData(PD);  
ISD_SendData(0x00);  
SS=1;  
}  

/**************************************************************************  
*    函数原型: void ISD_SendData(uchar BUF_ISD);  
*    功    能: 发送数据  
**************************************************************************/  
uchar ISD_SendData(uchar BUF_ISD){  
uchar i,dat=BUF_ISD;  
SCLK=1;  
SS=0;  
for(i=0;i<8;i++){  
SCLK=0;  
I_delay();  
if(dat&0x01){  
MOSI=1;  
}  
else{  
MOSI=0;  
}  
dat>>=1;  
if(MISO){  
dat|=0x80;  
}  
SCLK=1;  
I_delay();  
}  
MOSI=0;  
// SS=1;  
return(dat);  
}  

/**************************************************************************  
*    函数原型: void RdStatus(void);  
*    功    能: 读取状态  
**************************************************************************/  
void RdStatus(void){  
ISD_SendData(RD_STATUS);  
ISD_SendData(0x00);  
ISD_SendData(0x00);  
SS=1;  
delay_ms(10);               //延迟10ms  
SR0_L =ISD_SendData(RD_STATUS);  
SR0_H =ISD_SendData(0x00);  
SR1 =ISD_SendData(0x00);  
SS=1;  
delay_ms(10);  

}  

/**************************************************************************  
*    函数原型: void RdStatus(void);  
*    功    能: 读取ID  
**************************************************************************/  
uchar RD_DevID(void){  
ISD_SendData(RD_DEVID);  
ISD_SendData(0x00);  
ISD_SendData(0x00);  
SS=1;  
delay_ms(10);               //延迟10ms  
SR0_L =ISD_SendData(RD_DEVID);  
SR0_H =ISD_SendData(0x00);  
ID =ISD_SendData(0x00);  
SS=1;  
delay_ms(10);  
return(ID);  
}  

/**************************************************************************  
*    函数原型: void RD_APC(void);  
*    功    能: 读取APC  
**************************************************************************/  
void RdAPC(void){  
ISD_SendData(RD_APC);  
ISD_SendData(0x00);  
ISD_SendData(0x00);  
ISD_SendData(0x00);  
SS=1;  
delay_ms(10);               //延迟10ms  

SR0_L =ISD_SendData(RD_APC);  
SR0_H =ISD_SendData(0x00);  
APCL =ISD_SendData(0x00);  
APCH =ISD_SendData(0x00);  
SS=1;  
delay_ms(10);               //延迟10ms  
/*  
SBUF=SR0_L;  
delay_ms(1);  
SBUF=SR0_H;  
delay_ms(1);  
SBUF=APCL;  
delay_ms(1);  
SBUF=APCH;  
*/  
}  

/**************************************************************************  
*    函数原型: void ClrInt(void);  
*    功    能: 清除中断  
**************************************************************************/  
void ClrInt(void){  
ISD_SendData(CLI_INT);  
ISD_SendData(0x00);  
SS=1;  
delay_ms(10);               //延迟10ms  
}  

/**************************************************************************  
*    函数原型: void ISD_WR_APC2(uchar voiceValue);  
*    功    能: 设置APC2  
**************************************************************************/  
void ISD_WR_APC2(uchar voiceValue){  
ISD_SendData(WR_APC2);  
ISD_SendData(0xa8|voiceValue); //0xa8声音最大,0xaf声音最小  
ISD_SendData(0x0c); //D11=1,在SETPLAY模式下,执行到EOM自动结束。或者在连续两个SET_PLAY命令后,执行到第一个EOM自动跳到第二段开始  
SS=1;  
delay_ms(10);               //延迟10ms  
ISD_WR_NVCFG(); //永久写入寄存器  
}  

/**************************************************************************  
*    函数原型: void ISD_WR_NVCFG(void);  
*    功    能: 永久写入寄存器  
**************************************************************************/  
void ISD_WR_NVCFG(void){  
ISD_SendData(WR_NVCFG);  
ISD_SendData(0x00);  
SS=1;  
delay_ms(10);               //延迟10ms  
}  

/**************************************************************************  
*    函数原型: void GetToneAdd(uchar cNum, Uint * ipStartAdd, Uint * ipEndAdd);  
*    功    能: 取出当前语音的首末地址  
**************************************************************************/  
  
void GetToneAdd(uchar cNum, uint * ipStartAdd, uint * ipEndAdd)
{  

*ipStartAdd=caToneAdd[cNum*2];  
*ipEndAdd=caToneAdd[cNum*2+1];  
}  

/**************************************************************************  
*    函数原型: void SetPLAY(uchar cNum);  
*    功    能: 定点播放  
**************************************************************************/  
void SetPLAY(uchar cNum){  

uint Add_ST, Add_ED;  
uchar Add_ST_H, Add_ST_L, Add_ED_H, Add_ED_L;  

do{  
RdStatus();  

}while((SR0_L&0x01)||(!(SR1&0x01))); //if(SR0_L^0==1){system Err}<CMD_Err==1>  

ClrInt();  

GetToneAdd(cNum, &Add_ST, &Add_ED);  

Add_ST_L=(uchar)(Add_ST&0x00ff);  
Add_ST_H=(uchar)((Add_ST>>8)&0x00ff);  
Add_ED_L=(uchar)(Add_ED&0x00ff);  
Add_ED_H=(uchar)((Add_ST>>8)&0x00ff);  
/*  
delay_ms(1);  
SBUF=Add_ST_L;  
delay_ms(1);  
SBUF=Add_ST_H;  
delay_ms(1);  
SBUF=Add_ED_L;  
delay_ms(1);  
SBUF=Add_ED_H;  
delay_ms(1);  
*/  
ISD_SendData(SET_PLAY);  
ISD_SendData(0x00);  
ISD_SendData(Add_ST_L);          //S7:S0  开始地址  
ISD_SendData(Add_ST_H);           //S10:S8  
ISD_SendData(Add_ED_L);           //E7:E0  结束地址  
ISD_SendData(Add_ED_H);           //E10:E8  
ISD_SendData(0x00);  
SS=1;  
delay_ms(10);               //延迟10ms  

do{  
RdStatus();  

}while((SR0_L&0x01)||((SR1&0x04))); //if(SR0_L^0==1){system Err}<CMD_Err==1>  

}  

/**************************************************************************  
*    函数原型: void SetREC(uchar cNum);  
*    功    能: 定点录音  
**************************************************************************/  
void SetREC(uchar cNum){  

uint Add_ST, Add_ED;  
uchar Add_ST_H, Add_ST_L, Add_ED_H, Add_ED_L;  

do{  
RdStatus();  

}while((SR0_L&0x01)||(!(SR1&0x01))); //if(SR0_L^0==1){system Err}<CMD_Err==1>  

ClrInt();  

GetToneAdd(cNum, &Add_ST, &Add_ED);  

Add_ST_L=(uchar)(Add_ST&0x00ff);  
Add_ST_H=(uchar)((Add_ST>>8)&0x00ff);  
Add_ED_L=(uchar)(Add_ED&0x00ff);  
Add_ED_H=(uchar)((Add_ST>>8)&0x00ff);  

ISD_SendData(SET_REC);  
ISD_SendData(0x00);  
ISD_SendData(Add_ST_L);           //S7:S0  开始地址  
ISD_SendData(Add_ST_H);           //S10:S8  
ISD_SendData(Add_ED_L);           //E7:E0  结束地址  
ISD_SendData(Add_ED_H);          //E10:E8  
ISD_SendData(0x00);  
SS=1;  
delay_ms(10);               //延迟10ms  

do{  
RdStatus();  

// }while((SR0_L&0x01)||((SR1&0x08))); //if(SR0_L^0==1){system Err}<CMD_Err==1>  
}while((SR0_L&0x01)||(!(SR1&0x01))); //if(SR0_L^0==1){system Err}<CMD_Err==1>  
}  

/**************************************************************************  
*    函数原型: void SetERASE(uchar cNum);  
*    功    能: 定点删除,容易破坏存储结构(CMA),所以不用  
**************************************************************************/  
/*  
void SetERASE(uchar cNum){  

uchar Add_ST_H, Add_ST_L, Add_ED_H, Add_ED_L;  

Add_ST_L=(uchar)(Add_ST&0xff);  
Add_ST_H=(uchar)(Add_ST>>8);  
Add_ED_L=(uchar)(Add_ED&0xff);  
Add_ED_H=(uchar)(Add_ED>>8);  

ISD_SendData(SET_ERASE);  
ISD_SendData(0x00);  
ISD_SendData(Add_ST_L);          //S7:S0  开始地址  
ISD_SendData(Add_ST_H);          //S10:S8  
ISD_SendData(Add_ED_L);          //E7:E0  结束地址  
ISD_SendData(Add_ED_H);          //E10:E8  
ISD_SendData(0x00);  
// SS=1;  
//  delay_ms(120);  
}  

/**************************************************************************  
*    函数原型: void Erase_All(void);  
*    功    能: 全部删除  
**************************************************************************/  
void Erase_All(void){  
ISD_SendData(G_ERASE);  
ISD_SendData(0x00);  
SS=1;  
delay_ms(100);               //延迟10ms  
}  

/**************************************************************************  
*    END  
*    END  
**************************************************************************/  
main()
{
        ISD_Init();
        SetPLAY(0);
        while(1);

}

还请用过的前辈多多指教,问题出在哪里?? 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
4条回答
jjliang
2019-03-25 06:03
上面的代码我是懒得看了,有这么几个点要注意:
1.扬声器接的是SP+/-输出还是AUD/AUX+功放输出。1760内部的APC寄存器的默认值是0x0440,表示PWM和AUD输出是使能的。我的功放电路只有在AUX输出时才是正常的,所以必须把APC的设置为0x04C0以打开AUX输出。当然如果用的是PWM输出就不用修改了。
2.上电后第一次发送SPI命令前必须先发一个PU命令。
3.ISD1760的参考设计上复位脚直接了个0.1uF到地,没有上拉电阻构成阻容复位,同时容易受到干扰意外复位。复位后:1760在接收SPI命令前要再执行一次PU;另外还会把NVCFG的内容传送到APC,所以如果用的是AUX输出,一定要把NVCFG的值改为0x04C0,避免控制单片机正常而1760复位关掉AUX。
当然,好像1760的参考控制代码总是以PU命令开始,以PD命令结束的。

一周热门 更多>