wdh2152 发表于 2011-1-15 09:29:55

语音芯片ISD1730,SPI程序,完全可用

参考论坛里高人的程序,我稍加修改,有Atmega128完全可用,使用AVR其他单片机的,只需修改头文件即可
    后面的函数bofang()实现的是,语音0,1,2,3,4,5,6,7,8,9,的播放,能够提示水位的高低
    传感器使用的是麦克公司的压力传感器


#ifndef __ISD_H__
#define __ISD_H__

//定义ISD操作的各种命令, 全部开启D4,外部指示灯点亮
#define PU            0x11//上电命令
#define STOP          0x12//停止当前操作命令
#define RESET         0x13//复位命令
#define CLI_INT       0x14// 清除中断与EOM标志

#define RD_STATUS   0x15//读取状态寄存器和当前地址
#define RD_PLAY_PTR   0x16//读取状态寄存器和当前地址和播放指针
#define PD            0x17//下电命令
#define RD_REC_PTR    0x18//读取状态寄存器和当前地址和录音指针
#define RD_DEVID      0x19//读取器件ID
#define PLAY   0x50   //播放当前曲目命令
#define REC      0x51   //从当前地址开始录音
#define ERASE    0x52   //擦除当前段语音命令
#define G_ERASE0x53   //擦除全部语音命令(global_erase)

#define RD_APC    0x54    //读取当前状态寄存器,当前地址和APC寄存器

#define   WR_APC1   0x55    //将《D11:D0》的数据写入APC寄存器,并有VOL脚调节音量
#define   WR_APC2   0x75    //将《D11:D0》的数据写入APC寄存器,并有<D2:D2>脚调节音量
#define   WR_NVCFG   0x56//将APC的内容写到NVCFG

#define   LD_NVCFG   0x57//将NVCFG的内容写到APC
#define   FWD         0x58//将放音指针指向下一段语音起始地址命令
#define   CHK_MEM   0x59//检查环形存储结构

#defineSET_PLAY    0x90 //从<S10:S0>开始播放,直到《E10。E0》
#defineSET_REC   0x91 //从<S10:S0>开始录音,直到《E10。E0》
#defineSET_ERASE   0x92 //擦除<S10:S0>,直到《E10。E0》



#include "config.h"

//语音段选编码定义
#defineshi10
#definebai11
#defineqian 12
#definedian 13
uchar SR0_L;
uchar SR0_H;
uchar SR1;
uchar ID,APCL=0,APCH=0;
//-------------------------------------------------------------
//每10秒大约是80个十进制地址,即十六进制0x50,后一段声音越界
//就只会播前段声音的后面的一部分,遇到“EOM”停止.所以根据
//录的秒数乘以8,转化成十六进制数,得到大概地址,后面进行微调。
//-------------------------------------------------------------
//uint caToneAdd={0x0010,0x007b,0x007c,0x009f,0x00a0,0x00ea,0x00fa,0x014f};
uint caToneAdd[ ]={0x10,0x18,0x20,0x26,0x2D,0x34,0x3C,0x44,0x4A,0x52,0x59,0x60,0x68,0x6E,0x76};
/*
*/
/**************************************************************************
*    函数原型: void RdStatus(void);
*    功    能: 读取状态
**************************************************************************/
voidRdStatus(void)
{
   SS_L();
   delay_nms(10);
   SPI_MasterTransmit(RD_STATUS);//先发命令
   SPI_MasterTransmit(0x00);   //
   SPI_MasterTransmit(0x00);   //
   SS_H();
   delay_nms(10);
   
   SS_L();
   delay_nms(10);
   //读数据时,ISD MISO输出状态
   /*
   Status Register0(SR0)
状态寄存器SR0是两字节数据,由MISO返回。它包括5个状态位 (D4:
D0)以及11个地址位(A10:A0)
   */
   SR0_L = SPI_Master_TR(RD_STATUS);
   SR0_H = SPI_Master_TR(0x00);
   /*
   Status Register1(SR1)
   */
   SR1   = SPI_Master_TR(0x00);
   SS_H();
   delay_nms(10);
          
}

/**************************************************************************
*    函数原型: void Clr_Int(void);
*    功    能: 清除中断
**************************************************************************/
void ClrInt(void)
{
SS_L();
delay_nms(10);
SPI_MasterTransmit(CLI_INT);
SPI_MasterTransmit(0x00);
SS_H();
delay_nms(10);
}
/**************************************************************************
*    函数原型: void ISD_WR_NVCFG(void);
*    功    能: 永久写入寄存器
**************************************************************************/
void ISD_WR_NVCFG(void)
{

SS_L();
delay_nms(10);
SPI_MasterTransmit(WR_NVCFG);
SPI_MasterTransmit(0x00);
SS_H();
delay_nms(10);
}
/**************************************************************************
*    函数原型: void ISD_WR_APC2(uchar voiceValue);
*    功    能: 设置APC2
**************************************************************************/
void ISD_WR_APC2(void)
{
    SS_L();
    delay_nms(10);
    SPI_MasterTransmit(WR_APC2);
    SPI_MasterTransmit(0x73);//0b01110011 ,AUD电流输出,关闭音效编辑,MIC录音,关闭监听,声音最大
    SPI_MasterTransmit(0x04);//0b0000,0100,D11=1,在SETPLAY模式下,执行到EOM自动结束。或者在置0
//SET_PLAY命令后,执行到第一个EOM自动跳到第二段开始 ,直到结束地址
      SS_H();
   delay_nms(10);
       
   ISD_WR_NVCFG();//永久写入寄存器

}

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

   SS_L();
delay_nms(10);
SPI_MasterTransmit(RD_APC);
SPI_MasterTransmit(0x00);
SPI_MasterTransmit(0x00);
SPI_MasterTransmit(0x00);
SS_H();
delay_nms(10);               //延迟10ms

   SS_L();
delay_nms(10);

SR0_L = SPI_Master_TR(RD_APC);
SR0_H = SPI_Master_TR(0x00);
APCL =SPI_Master_TR(0x00);
APCH =SPI_Master_TR(0x00);
SS_H();
delay_nms(10);
}
/****************************************************************
*    函数原型: void ISD_Reset(void);
*    功    能: 复位
*****************************************************************/
void ISD_Reset(void)
{
   SS_L();
delay_nms(10);
SPI_MasterTransmit(RESET);
SPI_MasterTransmit(0x00);
   SS_H();
delay_nms(50);
}
/**************************************************************************
*    函数原型: 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_E
/*状态寄存器SR第一位MD_ERR 此位置1表示上一个SPI命令无效
状态寄存器SR1第一位,RDY=1时表示空闲,可以接收SPI命令;RDY=0
时为忙,不接受新的命令*/
ClrInt();
ISD_WR_APC2( );
RdAPC();
}

/**************************************************************************
*    函数原型: void ISD_CHK_MEM(void);
*    功    能: 空间检查
**************************************************************************/
void ISD_CHK_MEM(void)
{
   SS_L();
delay_nms(10);
SPI_MasterTransmit(CHK_MEM);
SPI_MasterTransmit(0x00);
   SS_H();
delay_nms(10);
}
/********************************************************************
*    函数原型: void ISD_Stop(void);
*    功    能: 停止
*********************************************************************/
void ISD_Stop(void)
{
      SS_L();
delay_nms(10);
SPI_MasterTransmit(STOP);
SPI_MasterTransmit(0x00);
   SS_H();
delay_nms(10);
}
/*********************************************************************
*    函数原型: void ISD_PU(void);
*    功    能: 上电
**********************************************************************/
voidISD_PU(void)
{
      SS_L();
delay_nms(10);
SPI_MasterTransmit(PU);
SPI_MasterTransmit(0x00);
   SS_H();
delay_nms(10);
}
/***************************************************************
*    函数原型: void ISD_PD(void);
*    功    能: 掉电
****************************************************************/
void ISD_PD(void)
{
      SS_L();
delay_nms(10);
SPI_MasterTransmit(PD);
SPI_MasterTransmit(0x00);
   SS_H();
delay_nms(10);
}

/**************************************************************************
*    函数原型: uchar RD_DevID(void);
*    功    能: 读取ID
**************************************************************************/
uchar RD_DevID(void)
{
      SS_L();
delay_nms(10);
SPI_MasterTransmit(RD_DEVID);
SPI_MasterTransmit(0x00);
SPI_MasterTransmit(0x00);
       SS_H();
delay_nms(10);               //延迟10ms

      SS_L();
delay_nms(10);
SR0_L = SPI_Master_TR(RD_DEVID);
SR0_H = SPI_Master_TR(0x00);
ID =SPI_Master_TR(0x00);
      SS_H();
delay_nms(10);
return(ID);
}

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

/*********************************************************************
*    函数原型: 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();

   SS_L();
delay_nms(10);               //延迟10ms
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_ED>>8)&0x00ff);
SPI_MasterTransmit(SET_PLAY);
SPI_MasterTransmit(0x00);
SPI_MasterTransmit(Add_ST_L);         //S7:S0开始地址
SPI_MasterTransmit(Add_ST_H);         //S10:S8
SPI_MasterTransmit(Add_ED_L);         //E7:E0结束地址
SPI_MasterTransmit(Add_ED_H);         //E10:E8
SPI_MasterTransmit(0x00);
SS_H();
delay_nms(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();
    SS_L();
delay_nms(10);               //延迟10ms

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);

SPI_MasterTransmit(SET_REC);
SPI_MasterTransmit(0x00);
SPI_MasterTransmit(Add_ST_L);         //S7:S0开始地址
SPI_MasterTransmit(Add_ST_H);         //S10:S8
SPI_MasterTransmit(Add_ED_L);         //E7:E0结束地址
SPI_MasterTransmit(Add_ED_H);          //E10:E8
SPI_MasterTransmit(0x00);
SS_H();
delay_nms(10);               //延迟10ms

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

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

    SS_L();
delay_nms(10);               //延迟10ms
SPI_MasterTransmit(G_ERASE);
SPI_MasterTransmit(0x00);
    SS_H();
delay_nms(10);               //延迟10ms
}

void bofang(uint date)
{
uchar date1,date2,date3,date4;

      date1 = date/1000;
      date2 = date%1000/100;
      date3 = date%100/10;
      date4 = date%10;
//四位数字按每位是0或者非0,有十六种组合,以下分别写出每种组合的播放

          if((date1 == 0)&(date2 == 0)&(date3 == 0)&(date4 == 0))
          {
                  SetPLAY(0);
                }
               
          else if((date1 == 0)&(date2 == 0)&(date3 == 0)&(date4 != 0))
                {
                  SetPLAY(date4);
                }
          else if((date1 == 0)&(date2 == 0)&(date3 != 0)&(date4 == 0))
          {
                   SetPLAY(date3);
                   SetPLAY(shi);
                }
          else if((date1 == 0)&(date2 == 0)&(date3 != 0)&(date4 != 0))
          {
                   SetPLAY(date3);
                   SetPLAY(shi);
                   SetPLAY(date4);
                }
          else if((date1 == 0)&(date2 != 0)&(date3 == 0)&(date4 == 0))
          {
                   SetPLAY(date2);
                   SetPLAY(bai);
                }
       else if((date1 == 0)&(date2 != 0)&(date3 == 0)&(date4 != 0))
                {
                   SetPLAY(date2);
                   SetPLAY(bai);
                   SetPLAY(date3);
                   SetPLAY(date4);
                }
       else if((date1 == 0)&(date2 != 0)&(date3 != 0)&(date4 == 0))
                {
                   SetPLAY(date2);
                   SetPLAY(bai);
                   SetPLAY(date3);
                   SetPLAY(shi);
                }
       else if((date1 == 0)&(date2 != 0)&(date3 != 0)&(date4 != 0))
                {
                   SetPLAY(date2);
                   SetPLAY(bai);
                   SetPLAY(date3);
                   SetPLAY(shi);
                   SetPLAY(date4);
                }
       else if((date1 != 0)&(date2 == 0)&(date3 == 0)&(date4 == 0))
                {
                   SetPLAY(date1);
                   SetPLAY(qian);
                }
    else if((date1 != 0)&(date2 == 0)&(date3 == 0)&(date4 != 0))
                {
                   SetPLAY(date1);
                   SetPLAY(qian);
                   SetPLAY(date2);
                   SetPLAY(date4);
                }
        else if((date1 != 0)&(date2 == 0)&(date3 != 0)&(date4 == 0))
                {
                   SetPLAY(date1);
                   SetPLAY(qian);
                   SetPLAY(date2);
                   SetPLAY(date3);
                   SetPLAY(shi);
                }
        else if((date1 != 0)&(date2 == 0)&(date3 != 0)&(date4 != 0))
                {
                   SetPLAY(date1);
                   SetPLAY(qian);
                   SetPLAY(date2);
                   SetPLAY(date3);
                   SetPLAY(shi);
                   SetPLAY(date4);
                }
        else if((date1 != 0)&(date2 != 0)&(date3 == 0)&(date4 == 0))
                {
                   SetPLAY(date1);
                   SetPLAY(qian);
                   SetPLAY(date2);
                   SetPLAY(bai);

                }
        else if((date1 != 0)&(date2 != 0)&(date3 == 0)&(date4 != 0))
                {
                   SetPLAY(date1);
                   SetPLAY(qian);
                   SetPLAY(date2);
                   SetPLAY(bai);
                   SetPLAY(date3);
                   SetPLAY(date4);

                }
        else if((date1 != 0)&(date2 != 0)&(date3 != 0)&(date4 == 0))
                {
                   SetPLAY(date1);
                   SetPLAY(qian);
                   SetPLAY(date2);
                   SetPLAY(bai);
                   SetPLAY(date3);
                   SetPLAY(shi);

                }
        else if((date1 != 0)&(date2 != 0)&(date3 != 0)&(date4 != 0))
                {
                   SetPLAY(date1);
                   SetPLAY(qian);
                   SetPLAY(date2);
                   SetPLAY(bai);
                   SetPLAY(date3);
                   SetPLAY(shi);
                   SetPLAY(date4);

                }
}

void bofang2(float date)
{
uint temp;
uchar date1,date2,date3,date4;
if(date>99) //100.5
{
      temp = date*10;
          date1 = temp/1000;
      date2 = temp%1000/100;
      date3 = temp%100/10;
      date4 = temp%10;
          
          if((date2 != 0)&(date3 != 0))
             {
                   SetPLAY(date1);
                   SetPLAY(bai);
                   SetPLAY(date2);
                   SetPLAY(shi);
                   SetPLAY(date3);
                   SetPLAY(dian);
                   SetPLAY(date4);
               
               }
               else if((date2 != 0)&(date3 == 0))
             {
                   SetPLAY(date1);
                   SetPLAY(bai);
                   SetPLAY(date2);
                   SetPLAY(shi);
                   SetPLAY(dian);
                   SetPLAY(date4);
               }
             
               else if((date2 == 0)&(date3 != 0))
             {
                   SetPLAY(date1);
                   SetPLAY(bai);
                   SetPLAY(date2);
                   SetPLAY(date3);
                   SetPLAY(dian);
                   SetPLAY(date4);
               }
               
               else //if((date2 == 0)&(date3 == 0))
             {
                   SetPLAY(date1);
                   SetPLAY(bai);
                   SetPLAY(dian);
                   SetPLAY(date4);
               }
}

else if(date>9)
{
      temp = date*100;
          date1 = temp/1000;
      date2 = temp%1000/100;
      date3 = temp%100/10;
      date4 = temp%10;
          
          if(date2 != 0)
          {
                   SetPLAY(date1);
                   SetPLAY(shi);
                   SetPLAY(date2);
                   SetPLAY(dian);
                   SetPLAY(date3);
                   SetPLAY(date4);
                  
                }
               
                else //if(date2 != 0)
          {
                   SetPLAY(date1);
                   SetPLAY(shi);
                   SetPLAY(dian);
                   SetPLAY(date3);
                   SetPLAY(date4);
                  
                }
          
          
}

else if(date>0)
{
      temp = date*1000;
          date1 = temp/1000;
      date2 = temp%1000/100;
      date3 = temp%100/10;
      date4 = temp%10;
          
                     SetPLAY(date1);
                   SetPLAY(dian);
                   SetPLAY(date2);
                   SetPLAY(date3);
                   SetPLAY(date4);
   
}


}

lzy888 发表于 2011-3-8 15:36:50

真的能用吗?我可要下功夫研究了

fanmingming 发表于 2011-5-7 10:52:32

回复【楼主位】wdh2152
-----------------------------------------------------------------------

王东豪就是会搞!啊!!!
模块化编程,这习惯不错,学习了!!!!

PCA 发表于 2012-5-13 12:57:15

正看这个东西,学习下

竹林海宝 发表于 2012-10-14 11:22:52

亲SS_L(); 木有看到

木v风 发表于 2012-11-7 15:31:56

mark,学习一下

Foan 发表于 2012-12-11 17:28:54

行吗??

pursuer99 发表于 2012-12-13 16:24:52

正需要这个东西呢 谢了

ljc2012 发表于 2013-7-14 23:04:31

能不能吧这两个函数SPI_Master_TR ()和SPI_MasterTransmit();发出来瞧瞧啊?自己写的 总是返回值为0.。

ljc2012 发表于 2013-7-14 23:04:58

uchar ISD_SendData(uchar BUF_ISD)
{
uchar i,dat;
dat=BUF_ISD;
ISD1730_SCLK_H;
ENISD1730_SS;
for(i=0;i<8;i++)
{
      ISD1730_SCLK_L;
      I_delay();
      if(dat&0x01)
          {
             ISD1730_MOSI_H;
          }
      
      else{
            ISD1730_MOSI_L;
          }
      dat=dat>>1;
      if((ISD1730_MISO_H_IN & BIT1)==1 )
          {
            dat|=0x80;
          }
      ISD1730_SCLK_H;
      I_delay();
}
ISD1730_MOSI_L;
return(dat);
}

tian_zi 发表于 2014-4-9 17:51:32

{:smile:}正好用来参考语言编程

cui0510 发表于 2014-4-15 09:07:04

学习一下
页: [1]
查看完整版本: 语音芯片ISD1730,SPI程序,完全可用