音乐播放器课程设计报告1Word格式.docx

上传人:b****4 文档编号:18004038 上传时间:2022-12-12 格式:DOCX 页数:9 大小:168KB
下载 相关 举报
音乐播放器课程设计报告1Word格式.docx_第1页
第1页 / 共9页
音乐播放器课程设计报告1Word格式.docx_第2页
第2页 / 共9页
音乐播放器课程设计报告1Word格式.docx_第3页
第3页 / 共9页
音乐播放器课程设计报告1Word格式.docx_第4页
第4页 / 共9页
音乐播放器课程设计报告1Word格式.docx_第5页
第5页 / 共9页
点击查看更多>>
下载资源
资源描述

音乐播放器课程设计报告1Word格式.docx

《音乐播放器课程设计报告1Word格式.docx》由会员分享,可在线阅读,更多相关《音乐播放器课程设计报告1Word格式.docx(9页珍藏版)》请在冰豆网上搜索。

音乐播放器课程设计报告1Word格式.docx

下一首)。

利用硬件ARM嵌入式开发平台、用于ARM7TDMI的JTAG仿真器、PC机Pentium100开发实现实现音频播放。

主要实现:

上一首按键:

当点击上一首按键时,当前播放歌曲的上一首歌首被播放。

下一首按键:

当点击下一首按键时,当前播放歌曲的下一首歌曲即被播放。

当点击停止键时,当前歌曲即会被停止。

播放界面设计:

在歌曲进行播放时,界面应包含所有的按键,并且要歌曲的曲目单。

二、实践原理

WAV播放器系统要求能够对mp3、wav格式的音频文件进行解码,处理起来速度是有要求的,尤其是对320Kbps的MP3格式数据流的处理,必须非常快,才能实现MP3的流畅播放,可供选择的八位机有AVR、PIC,可供选择的32位处理器有SAMSUNG、STM32、ATMEL等。

选择MCU优先考虑于拥有丰富的RAM,八位机RAM主要靠扩展,内部RAM一般在4Kbyte以内,32位机里面,SAMSUNG一般不内带RAM,也要外扩。

本实验使用了ARM7处理器,MP3解码可以有两种方法,一是通过ARM处理器软解码,通过对MP3数据格式的解析实现MP3播放,二是通过外部解码芯片直接解码。

第一种方法在解码高码率的MP3时,ARM7处理能力吃紧,而且STM32还需要外部DAC来做音频输出,所以采用第二种方法进行解码。

MP3常见的解码芯片有VS100X系列和STA01系列,STA01需要外接DAC做音频输出,而VS1003自带DAC,且解码的文件格式包含mp3和wav,另外它还可以实现录音功能,方便以后进行功能的拓展应用。

三、实践步骤

3.1功能设计

开机后,先初始化各外设,然后检测字库文件夹是否存在,如果有问题,则提示Error,如果检测无问题,则开始循环播放SD卡内MUSIC文件夹里面的歌曲,在TFTLCD上显示歌曲名字、播放时间、歌曲总时间、歌曲数目、当前歌曲的编号等信息。

KEY0选择下一首,KEY2选择上一首,KEY_UP控制暂停/继续播放。

3.2实验步骤

1)初始化WM8978,这个过程包括软复位、DAC设置、输出设置和音量设置等。

2)初始化I2S,此过程主要设置SPI_I2SCFGR寄存器,设置I2S模式、I2S标准、时钟空闲电平和数据帧长等,最后开启I2STXDMA,使能I2S外设。

在库函数中初始化I2S调用的函数为:

voidI2S_Init(SPI_TypeDef*SPIx,I2S_InitTypeDef*I2S_InitStruct);

结构体I2S_InitTypeDef的定义为:

typedefstruct

{uint16_tI2S_Mode;

uint16_tI2S_Standard;

uint16_tI2S_DataFormat;

uint16_tI2S_MCLKOutput;

uint32_tI2S_AudioFreq;

uint16_tI2S_CPOL;

}I2S_InitTypeDef;

第一个参数用来设置I2S的模式,也就是设置SPI_I2SCFGR寄存器的I2SCFG相关位。

可以配置为主模式发送I2S_Mode_MasterTx,主模式接受I2S_Mode_MasterRx,从模式发送I2S_Mode_SlaveTx以及从模式接受I2S_Mode_SlaveRx四种模式。

第二个参数

I2S_Standard用来设置I2S标准,这个前面已经讲解过。

可以设置为:

飞利浦标准

I2S_Standard_Phillips,MSB对齐标准I2S_Standard_MSB,LSB对齐标准

I2S_Standard_LSB以及PCM标准I2S_Standard_PCMShort。

第三个参数I2S_DataFormat用来设置I2S的数据通信格式。

这里实际包含设置SPI_I2SCFGR寄存器的HCLEN位(通道长度)以及DATLEN位(传输的数据长度)。

当我们设置为16位标准格式

I2S_DataFormat_16b的时候,实际上传输的数据长度为16位,通道长度为16位。

当我们设置为其他值的时候,通道长度都为32位。

第四个参数I2S_MCLKOutput用来设置是否使能主时钟输出。

我们实验会使能主时钟输出。

第五个参数I2S_AudioFreq用来设置I2S

频率。

实际根据输入的频率值,会来计算SPI预分频寄存器SPI_I2SPR的预分频奇数因子以及I2S线性预分频器的值。

这里支持10中频率:

#defineI2S_AudioFreq_192k((uint32_t)192000)

#defineI2S_AudioFreq_96k((uint32_t)96000)

#defineI2S_AudioFreq_48k((uint32_t)48000)

#defineI2S_AudioFreq_44k((uint32_t)44100)

#defineI2S_AudioFreq_32k((uint32_t)32000)

#defineI2S_AudioFreq_22k((uint32_t)22050)

#defineI2S_AudioFreq_16k((uint32_t)16000)

#defineI2S_AudioFreq_11k((uint32_t)11025)

#defineI2S_AudioFreq_8k((uint32_t)8000)

#defineI2S_AudioFreq_Default((uint32_t)2)

第六个参数I2S_CPOL用来设置空闲状态时钟电平,取值为高电平I2S_CPOL_High以及低电平I2S_CPOL_Low。

3)解析WAV文件,获取音频信号采样率和位数并设置I2S时钟分频器这里,要先解析WAV文件,取得音频信号的采样率(fs)和位数(16位或32位),根据这两个参数,来设置I2S的时钟分频,这里我们用前面介绍的查表法来设置即可。

这是我们单独写了一个设置频率的函数为I2S2_SampleRate_Set。

4)设置DMAI2S播放音频的时候,一般都是通过DMA来传输数据的,所以必须配置DMA,本章我们用I2S2,其TX是使用的DMA1数据流4的通道0来传输的。

并且STM32F4的DMA具有双缓冲机制,这样可以提高效率,大大方便了我们的数据传输,本章将DMA1数据流4设置为:

双缓冲循环模式,外设和存储器都是16位宽,并开启DMA传输完成中断(方便填充数据)。

5)编写DMA传输完成中断服务函数为了方便填充音频数据,我们使用DMA传输完成中断,每当一个缓冲数据发送完后,硬件自动切换为下一个缓冲,同时进入中断服务函数,填充数据到发送完的这个缓冲。

6)开启DMA传输,填充数据最后,我们就只需要开启DMA传输,然后及时填充WAV数据到DMA的两个缓存区即可。

此时,就可以在WM8978的耳机和喇叭通道听到所播放音乐了。

操作方法为:

DMA_Cmd(DMA1_Stream4,ENABLE);

//开启DMATX传输,开始播放。

3.3流程图

3.4关键代码

I2s.c代码:

#include"

i2s.h"

usart.h"

voidI2S2_Init(u16I2S_Standard,u16I2S_Mode,u16I2S_Clock_Polarity,u16I2S_DataFormat)

{

I2S_InitTypeDefI2S_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);

//使能SPI2时钟

RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2,ENABLE);

//复位SPI2

RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2,DISABLE);

//结束复位

I2S_InitStructure.I2S_Mode=I2S_Mode;

//IIS模式

I2S_InitStructure.I2S_Standard=I2S_Standard;

//IIS标准

I2S_InitStructure.I2S_DataFormat=I2S_DataFormat;

//IIS数据长度

I2S_InitStructure.I2S_MCLKOutput=I2S_MCLKOutput_Disable;

//主时钟输出禁止

I2S_InitStructure.I2S_AudioFreq=I2S_AudioFreq_Default;

//IIS频率设置

I2S_InitStructure.I2S_CPOL=I2S_Clock_Polarity;

//空闲状态时钟电平

I2S_Init(SPI2,&

I2S_InitStructure);

//初始化IIS

SPI_I2S_DMACmd(SPI2,SPI_I2S_DMAReq_Tx,ENABLE);

//SPI2TXDMA请求使能.

I2S_Cmd(SPI2,ENABLE);

//SPI2I2SEN使能.

}

//采样率计算公式:

Fs=I2SxCLK/[256*(2*I2SDIV+ODD)]

//I2SxCLK=(HSE/pllm)*PLLI2SN/PLLI2SR

//一般HSE=8Mhz

//pllm:

在Sys_Clock_Set设置的时候确定,一般是8

//PLLI2SN:

一般是192~432

//PLLI2SR:

2~7

//I2SDIV:

2~255

//ODD:

0/1

//I2S分频系数表@pllm=8,HSE=8Mhz,即vco输入频率为1Mhz

//表格式:

采样率/10,PLLI2SN,PLLI2SR,I2SDIV,ODD

constu16I2S_PSC_TBL[][5]=

{800,256,5,12,1},//8Khz采样率

{1102,429,4,19,0},//11.025Khz采样率

{1600,213,2,13,0},//16Khz采样率

{2205,429,4,9,1},//22.05Khz采样率

{3200,213,2,6,1},//32Khz采样率

{4410,271,2,6,0},//44.1Khz采样率

{4800,258,3,3,1},//48Khz采样率

{8820,316,2,3,1},//88.2Khz采样率

{9600,344,2,3,1},//96Khz采样率

{17640,361,2,2,0},//176.4Khz采样率

{19200,393,2,2,0},//192Khz采样率

};

//设置IIS的采样率(@MCKEN)

//samplerate:

采样率,单位:

Hz

//返回值:

0,设置成功;

1,无法设置.

u8I2S2_SampleRate_Set(u32samplerate)

u8i=0;

u32tempreg=0;

samplerate/=10;

//缩小10倍

for(i=0;

i{

if(samplerate==I2S_PSC_TBL[i][0])break;

RCC_PLLI2SCmd(DISABLE);

//先关闭PLLI2S

if(i==(sizeof(I2S_PSC_TBL)/10))return1;

//搜遍了也找不到

RCC_PLLI2SConfig((u32)I2S_PSC_TBL[i][1],(u32)I2S_PSC_TBL[i][2]);

//设置I2SxCLK的频率(x=2)设置PLLI2SNPLLI2SR

RCC->

CR|=1while((RCC->

CR&

1tempreg=I2S_PSC_TBL[i][3]tempreg|=I2S_PSC_TBL[i][4]tempreg|=1SPI2->

I2SPR=tempreg;

//设置I2SPR寄存器

return0;

//I2S2TXDMA配置

//设置为双缓冲模式,并开启DMA传输完成中断

//buf0:

M0AR地址.

//buf1:

M1AR地址.

//num:

每次传输数据量

voidI2S2_TX_DMA_Init(u8*buf0,u8*buf1,u16num)

NVIC_InitTypeDefNVIC_InitStructure;

DMA_InitTypeDefDMA_InitStructure;

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);

//DMA1时钟使能

DMA_DeInit(DMA1_Stream4);

while(DMA_GetCmdStatus(DMA1_Stream4)!

=DISABLE){}//等待DMA1_Stream1可配置

/*配置DMAStream*/

DMA_InitStructure.DMA_Channel=DMA_Channel_0;

//通道0SPI2_TX通道

DMA_InitStructure.DMA_PeripheralBaseAddr=(u32)&

SPI2->

DR;

//外设地址为:

(u32)&

DR

DMA_InitStructure.DMA_Memory0BaseAddr=(u32)buf0;

//DMA存储器0地址

DMA_InitStructure.DMA_DIR=DMA_DIR_MemoryToPeripheral;

//存储器到外设模式

DMA_InitStructure.DMA_BufferSize=num;

//数据传输量

DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;

//外设非增量模式

DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;

//存储器增量模式

DMA_InitStructure.DMA_PeripheralDataSize=

DMA_PeripheralDataSize_HalfWord;

//外设数据长度:

16位

DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;

//存储器数据长度:

DMA_InitStructure.DMA_Mode=DMA_Mode_Circular;

//使用循环模式

DMA_InitStructure.DMA_Priority=DMA_Priority_High;

//高优先级

DMA_InitStructure.DMA_FIFOMode=DMA_FIFOMode_Disable;

//不使用FIFO模式

DMA_InitStructure.DMA_FIFOThreshold=DMA_FIFOThreshold_1QuarterFull;

DMA_InitStructure.DMA_MemoryBurst=DMA_MemoryBurst_Single;

//外设突发单次传输

DMA_InitStructure.DMA_PeripheralBurst=DMA_PeripheralBurst_Single;

//存储器突发单次传输

DMA_Init(DMA1_Stream4,&

DMA_InitStructure);

//初始化DMAStream

DMA_DoubleBufferModeConfig(DMA1_Stream4,(u32)buf1,DMA_Memory_0);

//双缓冲模式配置

DMA_DoubleBufferModeCmd(DMA1_Stream4,ENABLE);

//双缓冲模式开启

DMA_ITConfig(DMA1_Stream4,DMA_IT_TC,ENABLE);

//开启传输完成中断

NVIC_InitStructure.NVIC_IRQChannel=DMA1_Stream4_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x00;

//抢占优先级0

NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x00;

//子优先级0

NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;

//使能外部中断通道

NVIC_Init(&

NVIC_InitStructure);

//配置

//I2SDMA回调函数指针

void(*i2s_tx_callback)(void);

//TX回调函数

//DMA1_Stream4中断服务函数

voidDMA1_Stream4_IRQHandler(void)

if(DMA_GetITStatus(DMA1_Stream4,DMA_IT_TCIF4)==SET)////DMA1_Stream4,传输完成标志

DMA_ClearITPendingBit(DMA1_Stream4,DMA_IT_TCIF4);

i2s_tx_callback();

//执行回调函数,读取数据等操作在这里面处理

//I2S开始播放

voidI2S_Play_Start(void)

DMA_Cmd(DMA1_Stream4,ENABLE);

//开启DMATX传输,开始播放

//关闭I2S播放

voidI2S_Play_Stop(void)

DMA_Cmd(DMA1_Stream4,DISABLE);

//关闭DMA,结束播放

}

wm8978代码:

wm8978.h"

myiic.h"

delay.h"

staticu16WM8978_REGVAL_TBL[58]=

0X0000,0X0000,0X0000,0X0000,0X0050,0X0000,0X0140,0X0000,0X0000,0X0000,0X0000,0X00FF,0X00FF,0X0000,0X0100,0X00FF,0X00FF,0X0000,0X012C,0X002C,0X002C,0X002C,0X002C,0X0000,0X0032,0X0000,0X0000,0X0000,0X0000,0X0000,0X0000,0X0000,0X0038,0X000B,0X0032,0X0000,0X0008,0X000C,0X0093,0X00E9,0X0000,0X0000,0X0000,0X0000,0X0003,0X0010,0X0010,0X0100,0X0100,0X0002,0X0001,0X0001,0X0039,0X0039,0X0039,0X0039,0X0001,0X0001

//WM8978初始化

0,初始化正常

//其他,错误代码

u8WM8978_Init(void)

u8res;

GPIO_InitTypeDefGPIO_InitStructure;

-全文完-

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 面试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1