语音芯片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);
}
} 真的能用吗?我可要下功夫研究了 回复【楼主位】wdh2152
-----------------------------------------------------------------------
王东豪就是会搞!啊!!!
模块化编程,这习惯不错,学习了!!!! 正看这个东西,学习下 亲SS_L(); 木有看到 mark,学习一下
行吗?? 正需要这个东西呢 谢了 能不能吧这两个函数SPI_Master_TR ()和SPI_MasterTransmit();发出来瞧瞧啊?自己写的 总是返回值为0.。
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);
}
{:smile:}正好用来参考语言编程 学习一下
页:
[1]