isd4004录音播放时错乱播放,可能是地址分配调用错误,可是我不懂改,求教

2019-07-16 15:46发布

//#include "stc15f2k60s2.h"
#include "reg51.h"
#include <intrins.h>


#define uchar unsigned  char
#define uint  unsigned  int

bit playbit,recbit;        //定义两个位变量,放音和录音位
uint playcout,reccout;         //放音和录音次数

////////定义放音命令,定义常量//////
#define ISDPOWERUP      0X20           //ISD4004上电
#define ISDSTOP         0X10           //ISD4004下电
#define OPERSTOP        0X30           //ISD4004停止当前操作
#define PLAYSET         0XE0           //ISD4004从指定地址开始放音
#define PLAYCUR         0XF0           //ISD4004从当前地址开始放音
#define RECSET          0XA0                 //ISD4004从指定地址开始录音
#define RECCUR          0XB0                   //ISD4004从当前地址开始录音

sbit   SS=P1^5;            //定义引脚
sbit   MOSI=P1^1;
sbit   MISO=P1^7;
sbit   SCLK=P1^4;

sbit key1=P0^0;     //时间
sbit key2=P0^1;     //温度湿度
sbit key3=P0^2;     //GPS
sbit key4=P0^3;      //录音


void delay(unsigned int i)  //延时程序
{
  while(i--);
}
void delayms(uchar ms)          
{                                               
        uchar j;
        while(ms--)
        {
                for(j = 0; j < 120; j++);
        }
}

/*
void stop()    //停止程序
{
    uchar y;
        SS=1;
        SS=0;          //ss=0时芯片才是有效的
        MOSI=0;        //放音
        SCLK=0;
        for(y=0;y<8;y++)
        {
                SCLK=0;
                if((0x30>>y)&0x01)  //停止当前操作指令地址0x30,从最低位读取数据
                   MOSI=1;
                else
                   MOSI=0;
                _nop_();
                _nop_();
                _nop_();
                SCLK=1;            //一个上升沿  时钟
                _nop_();
                _nop_();
                _nop_();
        }
        SS=1;
}
*/

//////////////////////////lu音部分子程序,地址由ADDR决定/////////////////////////
void luyin(addr)               
{         uint y;       
        SS=0;
        MOSI=0;         //发送开始
        SCLK=0;
        for(y=0;y<8;y++)
        {
                SCLK=0;
                if((0x20>>y)&0x01)
                       MOSI=1;
                else
                       MOSI=0;
                _nop_();
                _nop_();
                _nop_();
                SCLK=1;
                _nop_();
                _nop_();
                _nop_();
        }                      //发送结束
        SS=1;                  //上电结束
        delayms(50);

/*        SS=0;
        MOSI=0;                //发送开始
        SCLK=0;
        for(y=0;y<8;y++)
        {
                SCLK=0;
                if((0x20>>y)&0x01)        //应该是下电?
                         MOSI=1;
                else
                          MOSI=0;
                _nop_();
                _nop_();
                _nop_();
                SCLK=1;
                _nop_();
                _nop_();
                _nop_();
        }
        SS=1;//上电结束
        delayms(50);
        delayms(50);                  */
       
        SS=0;
        MOSI=0;              //发送地址
        SCLK=0;
        for(y=0;y<16;y++)
        {
                SCLK=0;
                if((addr>>y)&0x01)
                  MOSI=1;
                else
                  MOSI=0;
                _nop_();
                _nop_();
                _nop_();
                SCLK=1;
                _nop_();
                _nop_();
                _nop_();
        }                   //发送地址结束

        MOSI=0;
        SCLK=0;
        for(y=0;y<8;y++)           //从当前地址录音
        {
                SCLK=0;
                if((0xa0>>y)&0x01)
                    MOSI=1;
                else
                    MOSI=0;
                _nop_();
                _nop_();
                _nop_();
                SCLK=1;
                _nop_();
                _nop_();
                _nop_();
        }
        SS=1;

        SS=0;
        MOSI=0;
        SCLK=0;
        for(y=0;y<8;y++)            //从指定地址录音
        {
                SCLK=0;
                if((0xb0>>y)&0x01)
                     MOSI=1;
                else
                     MOSI=0;
                _nop_();
                _nop_();
                _nop_();
                SCLK=1;
                _nop_();
                _nop_();
                _nop_();
        }
        SS=1;          
}

////////////////放音部分子程序,放音地址由ADDR决定////
void fangyin(uint addr)
{         uint y;
        SS=0;
        MOSI=0;//发送开始
        SCLK=0;
        for(y=0;y<8;y++)
        {
                SCLK=0;
                if((0x20>>y)&0x01)MOSI=1;
                else MOSI=0;
                _nop_();
                _nop_();
                _nop_();
                SCLK=1;
                _nop_();
                _nop_();
                _nop_();
        }//发送结束
        SS=1;//上电结束
        delayms(50);
        SS=0;
        MOSI=0;//发送地址
        SCLK=0;
        for(y=0;y<16;y++)
        {
                SCLK=0;
                if((addr>>y)&0x01)MOSI=1;
                else MOSI=0;
                _nop_();
                _nop_();
                _nop_();
                SCLK=1;
                _nop_();
                _nop_();
                _nop_();
        }//发送地址结束
        MOSI=0;//放音
        SCLK=0;
        for(y=0;y<8;y++)
        {
                SCLK=0;
                if((0xe0>>y)&0x01)MOSI=1;
                else MOSI=0;
                _nop_();
                _nop_();
                _nop_();
                SCLK=1;
                _nop_();
                _nop_();
                _nop_();
        }
        SS=1;
        SS=0;
        MOSI=0;//放音
        SCLK=0;
        for(y=0;y<8;y++)
        {
                SCLK=0;
                if((0xf0>>y)&0x01)MOSI=1;
                else MOSI=0;
                _nop_();
                _nop_();
                _nop_();
                SCLK=1;
                _nop_();
                _nop_();
                _nop_();
        }
        SS=1;          }

////////////////////////////////
playsound()        ///录放音子函数

{


  if(recbit)                       
   {recbit=0;
    switch(reccout)
    {case 1:{luyin(0x00);}break;
     case 2:{luyin(0x100);}break;
     case 3:{luyin(0x200);}break;
     case 4:{luyin(0x300);}break;
     }
    }
}

void scankey4()
{
playsound();
}

void scankey3()
{
fangyin(0x100);
}

void scankey2()
{
fangyin(0x300);
}



void keyscan()
{
uchar value=0;
P0=0x0f;
value=P0&0x0f;
if(value!=0x0f)
{
if(key2==0)
{
  delay(10);
  while(key2==0)
  scankey2();
}

if(key3==0)
{
  delay(10);
  while(key3==0)
  scankey3();
}

if(key4==0)
{
  delay(10);
  while(key4==0)
{ recbit=1;
   reccout++;
   if(reccout>4)
   {
   reccout=0;
   break;
   }
  scankey4();
}
}
}
}


void main()
{
while(1)
{
keyscan();
}
}

新建 Microsoft Word 97-2003 文档.doc 下载积分: 积分 -1 分
39.5 KB, 下载次数: 3, 下载积分: 积分 -1 分
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
2条回答
951414
1楼-- · 2019-07-16 21:39
改动完如下
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int

//=======分段录音首地址定义======================
#define ISD_ADDS1        0x0000        //录音存放地址1
#define ISD_ADDS2        0x0100        //录音存放地址2
#define ISD_ADDS3        0x0200        //录音存放地址3
#define ISD_ADDS4        0x0300        //录音存放地址4
#define ISD_ADDS5        0x0400        //录音存放地址5
//========ISD4004指令定义========================
#define POWER_UP        0x20        //上电指令
#define SET_PLAY        0xE0        //指定放音指令
#define PLAY         0xF0        //当前放音指令
#define SET_REC        0xA0        //指定录音指令
#define REC        0xB0        //当前录音指令
#define SET_MC        0xE1        //指定快进指令
#define MC        0xF1        //快进执行指令
#define STOP        0x30        //停止当前操作
#define STOP_WRDN                 0x10        //停止当前操作并掉电
#define RINT                 0x30        //读状态:OVF和EOM
//=========ISD4004--c51接口定义=================
sbit ISD_SS =        P0^0;        //片选
sbit ISD_MOSI =        P0^1;        //数据输入
sbit ISD_MISO = P0^2;        //数据输出
sbit ISD_SCLK =        P0^3;        //ISD4004 时钟
sbit ISD_INT  = P3^2;        //溢出中断
sbit ISD_RAC  = P3^3;        //行地址时钟
//==========按键定义==========================
sbit K1 = P3^7 ;        //录音键
sbit K2 = P3^6;        //放音键
sbit LED=P2^7;
sbit K3=P3^5;
sbit K4=P3^4;
sbit K5=P3^3;
//==========ISD4004函数定义===================
void ISD_SPI_Send8( uchar isdx8 );        //spi 串行发送子程序,8位数据,从低到高
void ISD_SPI_Send16( uint isdx16 );        //spi 串行发送子程序,16位数据.从低到高
uint ISD_SPI_Radd(void);        //读取标行地址
void ISD_Stop(void);        //发送 stop 指令
void ISD_PowerUp(void);        //发送上电指令,并延迟 50ms
void ISD_PowerDown(void);        //发送掉电指令,并延迟 50ms
void ISD_Play(void);        //发送放音指令,并延迟 50ms
void ISD_SetPlay(uint add);        //发送指定放音指令,并延迟 50ms
void ISD_Rec(void);        //发送录音指令,并延迟 50ms
void ISD_SetRec(uint add);        //发送指定录音指令,并延迟 50ms
uchar ISD_Chk_Isdovf(void);

void PLAY_now(uchar add_sect);        //按指定地址开始放音
void REC_now(uchar add_sect);        //按指定地址开始录音
//========延时函数===========================
void Delay1Ms(uchar t);        //延时t*1毫秒
void Delay();
////////////////////////////////////////////////////////////////////////
//        程序开始          //
////////////////////////////////////////////////////////////////////////
/*******************************主程序*********************************/
main ()
{
uchar i=0;//,j=0;

while (1)
{
//=========================K1录音键================================
if(K1==0)        //K1键按下。录音
{
REC_now(i++);        //录第一段
if(i>4) i = 0;       
while(K1==0)        //等待录音完毕
{
if (ISD_INT==0)        //如果芯片OVF溢出,进行 蜂鸣器 提示,如果取消录音(松开  AN  键)则停止录音,芯片复 位
{       
while(K1==0)   
{
LED=0;
}
}
}
ISD_Stop();        //发送停止命令       
ISD_PowerDown();

}
//============================K2放音键================================

if(K2==0)
{       
Delay1Ms(10);
if(K2==0)
{
PLAY_now(1);
while(ISD_INT==1);
ISD_Stop();
ISD_PowerDown();
}
}
if(K3==0)
{
Delay1Ms(10);
if(K3==0)
{
PLAY_now(2);
while(ISD_INT==1);
ISD_Stop();
ISD_PowerDown();
}
}
if(K4==0)
{        Delay1Ms(10);
if(K4==0)
{       
PLAY_now(3);
while(ISD_INT==1);
ISD_Stop();
ISD_PowerDown();
}
}
if(K5==0)
{        Delay1Ms(10);
if(K5==0)
{       
PLAY_now(4);
while(ISD_INT==1);
ISD_Stop();
ISD_PowerDown();
}
}
/*       
if(K2==0)
{
PLAY_now(j++);        //放第一段
if(j>4) j = 0;
while(ISD_INT==1);        //等待一段放音完毕的 EOM 中断信号
ISD_Stop();        //放音完毕,发送 stop 指令
ISD_PowerDown();
}        */       
}
}

void PLAY_now(uchar add_sect)
{
ISD_PowerUp();        //ISD 上电
Delay1Ms(50);       
switch (add_sect)        //发送 setplay 指令,从 0x0000 地址开始放
{
case 1:        ISD_SetPlay(ISD_ADDS1);break;        //发送地址的 SetRec 指令
case 2:        ISD_SetPlay(ISD_ADDS2);break;        //发送地址的 SetRec 指令
case 3:        ISD_SetPlay(ISD_ADDS3);break;        //发送地址的 SetRec 指令
case 4:        ISD_SetPlay(ISD_ADDS4);break;        //发送地址的 SetRec 指令
//        case 5:        ISD_SetPlay(ISD_ADDS5);break;        //发送地址的 SetRec 指令
//case 6:……
}
ISD_Play();        //发送放音指令       
}  

void REC_now(uchar add_sect)
{
ISD_PowerUp();        //ISD 上电
Delay1Ms(50);        //延迟录音
ISD_PowerUp();        //ISD 上电
Delay1Ms(100);        //延迟录音
switch (add_sect)
{
case 1:        ISD_SetRec(ISD_ADDS1);break;        //发送地址的 SetRec 指令
case 2:        ISD_SetRec(ISD_ADDS2);break;        //发送地址的 SetRec 指令
case 3:        ISD_SetRec(ISD_ADDS3);break;        //发送地址的 SetRec 指令
case 4:        ISD_SetRec(ISD_ADDS4);break;        //发送地址的 SetRec 指令
//        case 5:        ISD_SetRec(ISD_ADDS5);break;        //发送地址的 SetRec 指令
//case 6:……
}
ISD_Rec();        //发送 rec 指令       
}

void ISD_SPI_Send8( uchar isdx8 )
{       
uchar i;

ISD_SS = 0;        //选中ISD4004
ISD_SCLK = 0;
for(i=0;i<8;i++)    //先发低位再发高位,依次发送。
{
if ((isdx8 & 0x01) == 1)        //发送最低位
ISD_MOSI = 1;
else
ISD_MOSI = 0;

isdx8 >>= 1;         //右移一位

ISD_SCLK = 1;        //时钟下降沿发送
ISD_SCLK = 0;
}
}
void ISD_SPI_Send16( uint isdx16 )
{       
uchar i;

ISD_SS = 0;        //选中ISD4004
ISD_SCLK = 0;
for(i=0;i<16;i++) //先发低位再发高位,依次发送。
{
if ((isdx16&0x0001)==1)        //发送最低位
ISD_MOSI = 1;
else
ISD_MOSI = 0;

isdx16 = isdx16 >> 1;         //右移一位

ISD_SCLK=1;        //时钟下降沿发送
ISD_SCLK=0;
}
}

uint ISD_SPI_Radd(void)
{       
uchar i;
uint addsig;
ISD_SS = 0;        //选中ISD4004
ISD_SCLK = 0;
//==============读16位地址================
for(i=0;i<16;i++)         //读行地址
{
ISD_SCLK = 1;        //时钟下降沿数据移出ISD
ISD_SCLK = 0;

if (ISD_MISO == 1)       
addsig |= 0x8000;
if (i<15) addsig >>= 1;        //最先读出的是地址的低位,所以要左移,最后一次地址不用左移,否则地址溢出
}

ISD_Stop();        //发送 stop 指令
ISD_SS        = 1;        //关闭 spi 通信端

return addsig;        //返回地址值       
}
void ISD_Stop(void)
{
//ISD_SS = 0;
ISD_SPI_Send8(STOP);         
ISD_SS = 1;          //关闭片选
}
void ISD_PowerUp(void)
{       
ISD_SS = 0;          //选中ISD4004
ISD_SPI_Send8(POWER_UP);
ISD_SS = 1;
}
void ISD_PowerDown(void)
{
ISD_SS = 0;       
ISD_SPI_Send8(STOP_WRDN);
ISD_SS = 1;
}
void ISD_Play(void)
{
        ISD_SS = 0;
ISD_SPI_Send8(PLAY);
ISD_SS = 1;
}
void ISD_Rec(void)
{
ISD_SS = 0;
ISD_SPI_Send8(REC);
ISD_SS = 1;
}       
void ISD_SetPlay(uint add)
{
Delay1Ms(1);
ISD_SPI_Send16(add);        //发送放音起始地址
ISD_SPI_Send8(SET_PLAY);        //发送 setplay 指令字节
ISD_SS = 1;
}
void ISD_SetRec(uint add)
{
Delay1Ms(1);
ISD_SPI_Send16(add);        //发送录音起始地址
ISD_SPI_Send8(SET_REC);        //发送 setrec 指令字节
ISD_SS = 1;
}
//************************************
//检查芯片是否溢出(读 OVF,并返回 OVF 值)
//************************************
/*uchar ISD_Chk_Isdovf(void)
{
ISD_SS=0;
ISD_SCLK=0;  
ISD_SCLK=1;
ISD_SCLK=0;

if (ISD_MISO==1)
{       
ISD_SCLK=0;
ISD_SS        =1;        //关闭 spi 通信端
ISD_Stop();        //发送 stop 指令
return 1;        //OVF 为 1,返回 1
}
else
{       
ISD_SCLK=0;
ISD_SS        =1;        //关闭 spi 通信端
ISD_Stop();        //发送 stop 指令
return 0;        //OVF 为 0,返回 0
}
}*/

void Delay1Ms(uchar t)
{
  uchar i;
for (;t>0;t--)
{
for (i=0;i<150;i++)
{
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
}
}       
}
//========================================
void Delay()
{
    uchar i;
    uint d=5000;
    while (d--)
    {
        i=255;
        while (i--);
    }
}
真的不是我的
2楼-- · 2019-07-17 01:27
 精彩回答 2  元偷偷看……

一周热门 更多>