本帖最后由 studying123 于 2013-3-30 21:33 编辑
用ATMEGA16与ISD1760语音芯片想做一个录/放功能的电路,可是程序和电路都弄好。就是看不到效果,求大神费时帮我看下是哪里出错了,急着要交的。谢谢! 调试的时候一直循环在给ISD1760上电的程序中
#include <iom16v.h>
#include <macros.h>
#define uint16 unsigned int
#define uchar16 unsigned char
uchar16 flag=0x00; //标志位
/*ISD1760状态寄存器及各个标志位定义*/
uchar16 SR0_L; //SR0寄存器
uchar16 SR0_H;
uchar16 SR1; //SR1寄存器
uchar16 APCL=0,APCH=0;//APC寄存器
uchar16 PlayAddL=0,PlayAddH=0;//放音指针低位,高位
uchar16 RecAddL=0,RecAddH=0;//录音指针低位,高位
#define CMD (SR0_L&0x01) //SPI指令错误标志
#define FULL (SR0_L&0x02) //芯片存储空间满标志
#define PU (SR0_L&0x04) //上电标志位
#define EOM (SR0_L&0x08) //EOM标志位
#define INTT (SR0_L&0x10) //操作完成标志位
#define RDY (SR1&0x01) //准备接受指令标志位
#define ERASE (SR1&0x02) //擦除标志位
#define PLAY (SR1&0x04) //播放标志位
#define REC (SR1&0x08) //录音标志位
/*标志位定义*/
//#define flag (PORTA&0X0E)
#define flag PORTA
/*#define PR_flag1 (flag|=0x02)
#define PR_flag0 (flag&=~0x02)
#define Erase_flag1 (flag|=0x10)
#define Erase_flag0 (flag~=0x10)
#define Stop_flag1 (flag|=0x80)
#define Stop_flag0 (flag~=0x80)*/
#define Switch_PR1 (PORTA&0x02) //判断录音还是放音与0x02比较
#define Switch_PR0 (PORTA&0x02)
/*端口定义*/
#define LED_ON (PORTA&=0xFE)
#define LED_OFF (PORTA|=0x01)
#define SS_H PORTB|=0x10
#define SS_L PORTB&=~0x10
#define Key_STOP (PORTA&0x04)
#define Key_AN (PORTA&0x08)
//延时程序(ms)
void delay (uint16 ms)
{
uint16 i,j;
for(i=0;i<ms;i++)
for(j=0;j<143;j++);
}
//spi主机发送
unsigned char ISD_SendData(uchar16 cData)
{
SS_L; //片选信号使能
SPDR=cData;//启动数据传输
while(!SPSR&(1<<SPIF));//等待数据发送结束
return SPDR;
}
/*ISD1760上电*/
void ISD_PU(void)
{
ISD_SendData(0x01); //发送PU命令
ISD_SendData(0x00);
SS_H;
}
/*ISD1760下电*/
void ISD_PD(void)
{
ISD_SendData(0x07); //发送PD命令
ISD_SendData(0x00);
SS_H;
}
/*停止当前操作*/
void ISD_STOP(void)
{
ISD_SendData(0x02); //发送STOP命令
ISD_SendData(0x00);
SS_H;
}
/*ISD1760复位*/
void ISD_Reset(void)
{
ISD_SendData(0x03); //发送RESET命令
ISD_SendData(0x00);
SS_H;
}
/*清除中断标志*/
void ISD_Clr_Int(void)
{
ISD_SendData(0x04);
ISD_SendData(0x00);
SS_H;
}
/*ISD1760放音*/
void ISD_Play(void)
{
ISD_SendData(0x40); //发送放音命令
ISD_SendData(0x00);
SS_H;
}
/*定点播放*/
void ISD_SET_PLAY(uchar16 Saddl,uchar16 Saddh,uchar16 Eaddl, uchar16 Eaddh)
{
ISD_SendData(0x80);
ISD_SendData(0x00);
ISD_SendData(Saddl); //开始地址低8位
ISD_SendData(Saddh); //开始地址高8位
ISD_SendData(Eaddl); //结束地址低8位
ISD_SendData(Eaddh); //结束地址高8位
ISD_SendData(0x00);
SS_H;
}
/*ISD1760录音*/
void ISD_Rec(void)
{
ISD_SendData(0x41); //发送录音命令
ISD_SendData(0x00);
SS_H;
}
/*定点录音*/
void ISD_SET_Rec(uchar16 Saddl,uchar16 Saddh,uchar16 Eaddl, uchar16 Eaddh)
{
ISD_SendData(0x81);
ISD_SendData(0x00);
ISD_SendData(Saddl); //开始地址低8位
ISD_SendData(Saddh); //开始地址高8位
ISD_SendData(Eaddl); //结束地址低8位
ISD_SendData(Eaddh); //结束地址高8位
ISD_SendData(0x00);
SS_H;
}
/*ISD1760擦除*/
void ISD_Erase(void)
{
ISD_SendData(0x42); //发送擦除命令
ISD_SendData(0x00);
SS_H;
}
/*定点擦除*/
void ISD_SET_Erase(uchar16 Saddl,uchar16 Saddh,uchar16 Eaddl, uchar16 Eaddh)
{
ISD_SendData(0x82);
ISD_SendData(0x00);
ISD_SendData(Saddl); //开始地址低8位
ISD_SendData(Saddh); //开始地址高8位
ISD_SendData(Eaddl); //结束地址低8位
ISD_SendData(Eaddh); //结束地址高8位
ISD_SendData(0x00);
SS_H;
}
/*ISD1760全体擦除*/
void ISD_G_Erase(void)
{
ISD_SendData(0x43); //发送全体擦除命令
ISD_SendData(0x00);
SS_H;
}
/*读取状态寄存器内容*/
void ISD_Rd_Status(void)
{
unsigned char i;
ISD_SendData(0x05); //发送
ISD_SendData(0x00);
ISD_SendData(0x00);
SS_H;
for(i=2;i>0;i--) //延迟
{;}
SR0_L=ISD_SendData(0x05); //从MISO读出状态
SR0_H=ISD_SendData(0x00);
SR1=ISD_SendData(0x00);
SS_H;
}
/*读取放音指针*/
void ISD_Rd_Playptr(void)
{
uchar16 i;
ISD_SendData(0x06); //发送
ISD_SendData(0x00);
ISD_SendData(0x00);
ISD_SendData(0x00);
SS_H;
for(i=2;i>0;i--) //延迟
{;}
SR0_L=ISD_SendData(0x06); //从MISO读出状态
SR0_H=ISD_SendData(0x00);
PlayAddL=ISD_SendData(0x00); //读取放音指针低8位
PlayAddH=ISD_SendData(0x00); //读取放音指针高8位
SS_H;
}
/*读取录音指针*/
void ISD_Rd_Recptr(void)
{
uchar16 i;
ISD_SendData(0x08); //发送
ISD_SendData(0x00);
ISD_SendData(0x00);
ISD_SendData(0x00);
SS_H;
for(i=2;i>0;i--) //延迟
{;}
SR0_L=ISD_SendData(0x08); //从MISO读出状态
SR0_H=ISD_SendData(0x00);
RecAddL=ISD_SendData(0x00); //读录音指针低8位
RecAddH=ISD_SendData(0x00); //读录音指针高8位
SS_H;
}
/*将APC数据写入NVCFG寄存器中*/
void ISD_WR_NVCFG(uchar16 apcdatl,uchar16 apcdath)
{
ISD_SendData(0x46);
ISD_SendData(apcdatl); //发送低8位数据
ISD_SendData(apcdath); //发送高8位数据
SS_H;
}
/*将NVCFG数据写入APC寄存器中*/
void ISD_LD_NVCFG(void)
{
ISD_SendData(0x47);
ISD_SendData(0x00);
SS_H;
}
/*放音指针下跳一段,指向下一段语音的起始地址*/
void ISD_FWD(void)
{
ISD_SendData(0x48);
ISD_SendData(0x00);
SS_H;
}
/*空间检查*/
void ISD_CHK_MEM(void)
{
ISD_SendData(0x49);
ISD_SendData(0x00);
SS_H;
}
/*启用/关闭 外部时钟模式*/
void ISD_EXTCLK(void)
{
ISD_SendData(0x4a);
ISD_SendData(0x00);
SS_H;
}
/*读取APC寄存器内容*/
unsigned char ISD_Devid(void)
{
uchar16 DeviceNO,i;
ISD_SendData(0x09); //发送
ISD_SendData(0x00);
ISD_SendData(0x00);
SS_H;
for(i=2;i>0;i--) //延迟
{;}
ISD_SendData(0x09);
ISD_SendData(0x00);
DeviceNO=ISD_SendData(0x00);
SS_H;
return DeviceNO;
}
/*设置APC2*/
void ISD_WR_APC2(uchar16 apcdatl,uchar16 apcdath)
{
ISD_SendData(0x65);
ISD_SendData(apcdatl); //发送低8位数据
ISD_SendData(apcdath); //发送高8位数据
SS_H;
}
/*ISD1760初始化*/
void ISD_init(void)
{
unsigned char i=2;
do
{
ISD_PU(); //上电
delay(50);
ISD_Rd_Status(); //读取状态
}while(CMD||(!PU)); //if(CMD_Err==1)||(PU!=1)则再次发送上电指令
ISD_WR_APC2(0x40,0x04); //将0x0440写入APC寄存器,此时语音提示关
do
{
ISD_Rd_Status();
} //等待RDY置位1
while (RDY==0);
do
{
LED_ON;
delay(300);
LED_OFF;
delay(300);
i--;
}
while(i>0);
}
//SPI通信初始化
void spi_init()
{
DDRB|=0xB0;//PB7,5,4设置为输出
SPCR=0x7F;//主机模式,LSB先发送,fosc/128
//SPCR=0x7C;
}
/*ISD1760进行相关操作*/
void ISDWORK(void)
{
unsigned char i;
switch(flag)
{
case 0x06: //放音
do {ISD_Rd_Status();}while(RDY==0); //读取状态寄存器内容,RDY=O表示忙
delay(10);
ISD_Play(); //发送放音命令
delay(2);
LED_ON;
do {ISD_Rd_Status();
if(Key_STOP==0)
{
delay(20);
if(Key_STOP==0) /*暂停键*/
{
ISD_Clr_Int(); //清除中断标志
ISD_STOP(); //停止当前操作
return;
}
}
}while(PLAY==1);
LED_OFF;
ISD_Clr_Int();
do {ISD_Rd_Status();
}while(RDY==0);
delay(10);
ISD_FWD(); //放音指针下跳一段
do {ISD_Rd_Status();
}while(RDY==0);
break;
case 0x04: //录音
ISD_Clr_Int();
do {ISD_Rd_Status();
}while(RDY==0);
LED_ON;
ISD_Rec(); //录音
do {ISD_Rd_Status();
if(FULL==1) //存储空间满
{
for(i=3;i>0;i--)
{ LED_ON;
delay(300);
LED_OFF;
delay(200);
}
}
}while(Key_AN==0); /*录音键*/
ISD_Clr_Int();
ISD_STOP();
LED_OFF;
break;
case 0x08: //全体擦除
do {ISD_Rd_Status();
}while(RDY==0);
delay(2);
ISD_G_Erase();
do {ISD_Rd_Status();
}while(RDY==0);
for(i=3;i>0;i--)
{ LED_ON;
delay(300);
LED_OFF;
delay(200);
}
break;
case 0x0A: //全体擦除
do {ISD_Rd_Status();
}while(RDY==0);
delay(2);
ISD_G_Erase();
do {ISD_Rd_Status();
}while(RDY==0);
for(i=3;i>0;i--)
{ LED_ON;
delay(300);
LED_OFF;
delay(200);
}
break;
case 0x80: //复位下电
ISD_Clr_Int();
ISD_STOP();
ISD_Reset();
ISD_PD();
break;
}
}
void main(void)
{
uchar16 i;
DDRB|=0x10; //SS口设置为输出
DDRA|=0X01; //A0口设置为输出
DDRA&=~0X0E; //A1,A2,A3设置为输入
delay(1);
spi_init(); //SPI通信初始化
ISD_init();
while(1)
{
if(Key_AN==0) /*AN按键按下,若Switch_PR=1则录音,=0则放音*/
{
delay(10);
if(Key_AN==0)
{
if(Switch_PR1==0x02)
{
flag&=0x0E; //flag 值只取A1A2A3三口的值
//PR_flag1;
}
else
{
flag&=0x0E;
//PR_flag0;
}
ISDWORK();
}
}
if(Key_STOP==0) //Key_STOP快速按一次则下电,长按住则全擦除
{
delay(20);
if(Key_STOP==0)
{
for(i=100;i>0;i--)
{
if(Key_STOP==1)
{
flag=0x80; //下电标志
ISDWORK();
ISD_init();
break;
}
delay(30);
}
if(flag==0x80)
{
flag=0x00; //放音标志
continue;
}
flag&=0x0E; //全擦标志
//Erase_flag1;
ISDWORK();
}
}
}
}
|