音乐播放器课程设计报告Word下载.docx
- 文档编号:22700978
- 上传时间:2023-02-05
- 格式:DOCX
- 页数:25
- 大小:38.81KB
音乐播放器课程设计报告Word下载.docx
《音乐播放器课程设计报告Word下载.docx》由会员分享,可在线阅读,更多相关《音乐播放器课程设计报告Word下载.docx(25页珍藏版)》请在冰豆网上搜索。
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.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采样率
{3200,213,2,6,1},//32Khz采样率
{4800,258,3,3,1},//48Khz采样率
{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<
(sizeof(I2S_PSC_TBL)/10);
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|=1<
<
26;
//开启I2S时钟
while((RCC->
CR&
1<
27)==0);
//等待I2S时钟开启成功.
tempreg=I2S_PSC_TBL[i][3]<
0;
//设置I2SDIV
tempreg|=I2S_PSC_TBL[i][4]<
8;
//设置ODD位
tempreg|=1<
9;
//使能MCKOE位,输出MCK
SPI2->
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)&
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;
//存储器数据长度:
16位
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;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOC,ENABLE);
//使能外设GPIOB,GPIOC时
//PB12/13复用功效输出
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12|GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
//复用功效
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
//推挽
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
//100MHz
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
//上拉
GPIO_Init(GPIOB,&
GPIO_InitStructure);
//初始化
//PC2/PC3/PC6复用功效输出
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_6;
GPIO_Init(GPIOC,&
GPIO_PinAFConfig(GPIOB,GPIO_PinSource12,GPIO_AF_SPI2);
//PB12,AF5I2S_LRCK
GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_SPI2);
//PB13,AF5I2S_SCLK
GPIO_PinAFConfig(GPIOC,GPIO_PinSource3,GPIO_AF_SPI2);
//PC3,AF5I2S_DACDATA
GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_SPI2);
//PC6,AF5I2S_MCK
GPIO_PinAFConfig(GPIOC,GPIO_PinSource2,GPIO_AF6_SPI2);
//PC2,AF6I2S_ADCDATAI2S2ext_SD是AF6!
!
IIC_Init();
//初始化IIC接口
res=WM8978_Write_Reg(0,0);
//软复位WM8978
if(res)return1;
//发送指令掉败,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 音乐 播放 课程设计 报告