您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 其它行业文档 > 基于STC12单片机的WAV播放器
基于STC12单片机的WAV播放器物电学院电信二班小组成员:张景宝、李镇宇、周方嫒一、设计特点1、采用PWM调制方式,使硬件简单,实现容易。2、由于没有专用解码芯片,所以只能播放WAV音轨。3、通过软件自动适应音乐采样率。4、设计电池接口,可便携。5、声音大小可通过硬件调整。二、基本原理将PCM文件结合采样率调制到PWM,采取适当滤波,驱动耳机即可还原音乐文件。三、硬件设计1、电源部分2、SD卡部分3、音频接口部分4、CPU部分四、软件设计1、编译平台:KEILV9.09级优化2、使用资源情况3、SD卡低层驱动/*************************************************************-功能描述:向SD卡写命令-隶属模块:SD卡模块-函数属性:内部-参数说明:SD卡的命令是6个字节,pcmd是指向命令字节序列的指针-返回说明:命令写入后,SD卡的回应值,调用不成功,将返回0xff*************************************************************/u8SD_SendCommand(u8cmd,u32arg,u8crc){unsignedcharr1;unsignedcharRetry=0;//SPI_ReadWriteByte(0xff);//片选端置低,选中SD卡SD_CS=0;//打开片选//发送SPI_ReadWriteByte(cmd|0x40);//分别写入命令SPI_ReadWriteByte(arg24);SPI_ReadWriteByte(arg16);SPI_ReadWriteByte(arg8);SPI_ReadWriteByte(arg);SPI_ReadWriteByte(crc);//等待响应,或超时退出while((r1=SPI_ReadWriteByte(0xFF))==0xFF){Retry++;if(Retry200){break;}}//关闭片选//在总线上额外增加8个时钟,让SD卡完成剩下的工作SPI_ReadWriteByte(0xFF);SD_CS=1;//打开片选//返回状态值returnr1;}/*************************************************************-功能描述:初始化SD卡,使用CMD1-隶属模块:SD卡模块-函数属性:内部-参数说明:无-返回说明:调用成功,返回0x00,否则返回INIT_CMD1_ERROR(sd.h中有定义)*************************************************************/u8SD_Init(){unsignedchartime,temp,i;SPI_Init();SPI_SetSpeed(3);//设置到低速模式SD_CS=1;//打开片选for(i=0;i0x0A;i++)//初始时,首先要发送最少74个时钟信号,这是必须的!!!{SPI_ReadWriteByte(0xff);//120个时钟}SD_CS=0;//打开片选time=0;do{temp=SD_SendCommand(CMD0,0,0x95);//写入CMD0复位SD卡time++;if(time==200){SD_CS=1;//打开片选}}while(temp!=0x01);time=0;do{temp=SD_SendCommand(CMD1,0,0xff);//写入CMD1激活SD卡time++;if(time==200){SD_CS=1;//打开片选}}while(temp!=0);SPI_SetSpeed(0);temp=SD_SendCommand(CMD59,0,0x01);if(temp!=0x00){returntemp;//命令错误,返回r1}temp=SD_SendCommand(CMD16,512,0xff);if(temp!=0x00){returntemp;//命令错误,返回r1}SD_CS=1;//打开片选SPI_ReadWriteByte(0xff);//按照SD卡的操作时序在这里补8个时钟return0;}/*----------------------------------------------------------*//*InitializeDiskDrive*//*----------------------------------------------------------*/DSTATUSdisk_initialize(void){DSTATUSstat;stat=SD_Init();returnstat;}/*----------------------------------------------------------*//*ReadPartialSector*//*----------------------------------------------------------*/DRESULTdisk_readp(BYTE*buff,/*Pointertothedestinationobject*/DWORDsector,/*Sectornumber(LBA)*/WORDoffset,/*Offsetinthesector*/WORDcount/*Bytecount(bit15:destination)*/){DRESULTres;ucharresponse=0xff;uintbyteLeft,retry=0;byteLeft=512-offset-count;//接收数据后,跳过的字节数if((offset+count)512)returnRES_PARERR;//读取字节超出扇区if(SD_SendCommand(CMD17,sector9,0))returnRES_ERROR;//读命令发送失败SD_CS_ASSERT;do//等待起始数据块起始标志0xfe(0x11111110){response=SPI_ReadWriteByte(0xff);if(retry++0xfffe)//超时错误{SD_CS_DEASSERT;returnRES_ERROR;}}while(response!=0xfe);//等待回应if(offset)//跳过offset(偏移字节数)个数据{do{SPI_ReadWriteByte(0xff);}while(--offset);}if(buff){do//接收到的数据块数据存入缓冲区{*buff++=SPI_ReadWriteByte(0xff);}while(--count);}else{//dummy}if(byteLeft)//跳过byteLeft个数据{do{SPI_ReadWriteByte(0xff);}while(--byteLeft);}SPI_ReadWriteByte(0xff);//忽略CRC校验(两个字节)SPI_ReadWriteByte(0xff);res=RES_OK;SD_CS_DEASSERT;SPI_ReadWriteByte(0xff);//等待8个clkreturnres;}4、数据缓冲区设计BYTExdataCache0[SIZE];BYTExdataCache1[SIZE];LPBYTEdataCache;LPBYTEdataAudioCache=Cache0;if(Cache==Cache0)Cache=Cache1;elseCache=Cache0;5、音乐还原过程voidTimer0(void)interrupt1{CCAP0L=CCAP0H=AudioCache[AudioPos];AudioPos++;if(AudioPos=SIZE){play_f=1;AudioPos=0;if(AudioCache==Cache0)AudioCache=Cache1;elseAudioCache=Cache0;}}6、WAV文件格式与自适应采样率staticDWORDload_header(void)/*0:Invalidformat,1:I/Oerror,=1024:Numberofsamples*/{DWORDsz,f;BYTEb,al=0;if(pf_read(Cache,12,&rb))return1;/*Loadfileheader(12bytes)*/if(rb!=12||LD_DWORD(Cache+8)!=FCC('W','A','V','E'))return0;for(;;){pf_read(Cache,8,&rb);/*GetChunkIDandsize*/if(rb!=8)return0;sz=LD_DWORD(&Cache[4]);/*Chunksize*/switch(LD_DWORD(&Cache[0])){/*FCC*/caseFCC('f','m','t',''):/*'fmt'chunk*/if(sz&1)sz++;/*Alignchunksize*/if(sz100||sz16)return0;/*Checkchunksize*/pf_read(Cache,sz,&rb);/*Getcontent*/if(rb!=sz)return0;if(Cache[0]!=1)return0;/*Checkcodingtype(LPCM)*/b=Cache[2];if(b!=1&&b!=2)return0;/*Checkchannels(1/2)*/b=Cache[14];if(b!=8&&b!=16)return0;/*Checkresolution(8/16bit)*/if(b&16)al=1;f=LD_DWORD(&Cache[4]);/*Checksamplingfreqency(8k-48k)*/if(f8000||f8000)return4;TH0=-(FOSC/12/f);break;caseFCC('d','a','t','a'):/*'data'chunk*/if(!al)return0;/*Checkifformatvalid*/if(sz1024||(sz&(al-1)))return0;/*Checksize*/if(Fs.fptr&(al-1))return0;/*Checkoffset*/returnsz;/*Starttoplay*/caseFCC('D','I','S','P'):/*'DISP'chunk*/SendString(disp\n);caseFCC('L','I','S','T'):/*'LIST'chunk*/caseFCC('f','a','c','t'):/*'fact'chunk*/if(sz&1)sz++;/*Alignchunksize*/pf_lseek(Fs.fptr+sz);/*Skipthischunk*/break;default:/*Unknownchunk*/return0;}}return0;}五、附录1、WAV文件格式偏移地址字节数数据类型内容文件头00H4char“RIFF”;RIFF标志04H4longint0x0001060A(注意数据存储顺序);文件长度08H4char“WAVE”;WAVE标志0CH4char“fmt”;fmt标志,最后一位为空10H4longint0x12;sizeof(PCMWAVEFORMAT)14H2int1(WAVE_FORMAT_PCM);格式类别,1表示为PCM形式的声音数据16H2int2;通道数,单声道为1,双声道为218H2int44100;采样频率(每秒样本数)1CH4longint0x10B10000;每秒数据量;其值为通道数×每秒数据位数×每样本的数据位数/8。播放软件利用此值可以估计缓冲区的大小。20H2int数
本文标题:基于STC12单片机的WAV播放器
链接地址:https://www.777doc.com/doc-2572216 .html