|
参考论坛里高人的程序,我稍加修改,有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_ERASE 0x53 //擦除全部语音命令(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 //检查环形存储结构
#define SET_PLAY 0x90 //从<S10:S0>开始播放,直到《E10。E0》
#define SET_REC 0x91 //从<S10:S0>开始录音,直到《E10。E0》
#define SET_ERASE 0x92 //擦除<S10:S0>,直到《E10。E0》
#include "config.h"
//语音段选编码定义
#define shi 10
#define bai 11
#define qian 12
#define dian 13
uchar SR0_L;
uchar SR0_H;
uchar SR1;
uchar ID,APCL=0,APCH=0;
//-------------------------------------------------------------
//每10秒大约是80个十进制地址,即十六进制0x50,后一段声音越界
//就只会播前段声音的后面的一部分,遇到“EOM”停止.所以根据
//录的秒数乘以8,转化成十六进制数,得到大概地址,后面进行微调。
//-------------------------------------------------------------
//uint caToneAdd[8]={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);
* 功 能: 读取状态
**************************************************************************/
void RdStatus(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);
* 功 能: 上电
**********************************************************************/
void ISD_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[cNum];
*ipEndAdd=caToneAdd[cNum+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();
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);
}
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|