这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » STM32 I2S播放MP3文件实验报告

共3条 1/1 1 跳转至

STM32 I2S播放MP3文件实验报告

工程师
2014-09-14 21:12:22     打赏

STM32 I2S播放MP3文件实验报告

一、实验原理

本实验主要是初始化DA芯片PCM1770后,处理器读取预先放置在处理器内部的音频文件,判断音频文件的合法性,并依据音频文件的格式设置I2S3接口的参数,然后处理器采用中断方式通过I2S3接口重复播放该音频文件。

二、I2S相关知识

I2SSPI共用3个引脚:

● SD:串行数据(映射至MOSI引脚),用来发送和接收2路时分复用通道的数据;

● WS:字选(映射至NSS引脚),主模式下作为数据控制信号输出,从模式下作为输入;

● CK:串行时钟(映射至SCK引脚),主模式下作为时钟信号输出,从模式下作为输入。

在某些外部音频设备需要主时钟时,可以另有一个附加引脚输出时钟:

● MCK:主时钟(独立映射),在I2S配置为主模式,寄存器SPI_I2SPRMCKOE位为’1’时,作为输出额外的时钟信号引脚使用。输出时钟信号的频率预先设置为256 ×Fs,其中Fs是音频信号的采样频率。

支持的音频协议

有四种可用的数据和包帧组合。可以通过以下四种数据格式发送数据:

● 16位数据打包进16位帧

● 16位数据打包进32位帧

● 24位数据打包进32位帧

● 32位数据打包进32位帧

有四种标准协议

--I2S飞利浦标准

--MSB对齐标准

--LSB对齐标准

--PCM标准

时钟发生器

I2S的比特率即确定了在I2S数据线上的数据流和I2S的时钟信号频率。

I2S比特率每个声道的比特数 × 声道数目 × 音频采样频率

对于一个具有左右声道和16位音频信号,I2S比特率计算如下

I2S比特率= 16 ××Fs

如果包长为32位,则有:I2S比特率= 32 ××Fs

I2S主模式

设置I2S工作在主模式,串行时钟由引脚CK输出,字选信号由引脚WS产生。可以通过设置寄存

SPI_I2SPRMCKOE位来选择输出或者不输出主时钟(MCK)

流程

1. 设置寄存器SPI_I2SPRI2SDIV[7:0]定义与音频采样频率相符的串行时钟波特率。同时

也要定义寄存器SPI_I2SPRODD位。

2. 设置CKPOL位定义通信用时钟在空闲时的电平状态。如果需要向外部的DAC/ADC音频器

件提供主时钟MCK,将寄存器SPI_I2SPRMCKOE位置为’1’。(按照不同的MCK输出状

态,计算I2SDIVODD的值,详见23.4.3)

3. 设置寄存器SPI_I2SCFGRI2SMOD位为’1’激活I

2

S功能,设置I2SSTD[1:0]PCMSYNC

位选择所用的I2S标准,设置CHLEN选择每个声道的数据位数。还要设置寄存器

SPI_I2SCFGRI2SCFG[1:0]选择I2S主模式和方向(发送端还是接收端)

4. 如果需要,可以通过设置寄存器SPI_CR2来打开所需的中断功能和DMA功能。

5. 必须将寄存器SPI_I2SCFGRI2SE位置为’1’。

6. 引脚WSCK需要配置为输出模式。如果寄存器SPI_I2SPRMCKOE位为’1’,引脚MCK也要配置成输出模式。

状态标志位

忙标志位(BSY)

发送缓存空标志位(TXE)

接收缓存非空标志位(RXNE)

声道标志位(CHSIDE)

三、硬件设计

PCM1770芯片是一款低电压、低功耗带耳机放大的DAC芯片,用其实现音频的DA转换。

四、软件设计

int main(void)

{

  USART_Configuration();

  printf("\n\r -----------------------------------------") ;

  printf("\n\r神舟III号音频播放实验") ;

  printf("\n\r -----------------------------------------") ;

  printf("\n\r串口初始化完成");

  /* I2S GPIO接口配置 */

  I2S_GPIO_Config();

  /*SPI2接口初始化*/

  SPI2_Config();

  PCM1770_CS_config();

  SPI2_Init_For_PCM1770();

  printf("\n\rPCM1770 SPI接口初始化完成");

  /*中断向量与中断优先级配置*/

  NVIC_Configuration();

  I2S_CODEC_Init(OutputDevice_SPEAKER, AUDIO_FILE_ADDRESS);//I2C CODEC初始化

  I2S_CODEC_Play(1);

  while(1)

  {

  }

}

在音频播放试验中采用I2S3中断方式来实现音频播放。当I2S3中断时,就进入I2S3的中断服务程序,调用音频播放程序I2S_CODEC_DataTransfer(),因此,我们可以重复听到相同的音频。

void NVIC_Configuration(void)

{

  NVIC_InitTypeDef NVIC_InitStructure;

  

  /* Set the Vector Table base address at 0x08010000 */

  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0000);

        /* SPI2 IRQ Channel configuration */

  NVIC_InitStructure.NVIC_IRQChannel = SPI3_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

}

void SPI3_IRQHandler(void)

{

  //static int IRQcounter = 0;

  if ((SPI_I2S_GetITStatus(SPI3, SPI_I2S_IT_TXE) == SET))

  {

    /* Send data on the SPI3 and Check the current commands */

    I2S_CODEC_DataTransfer();

  }

}

void I2S_CODEC_DataTransfer(void)

{

      /* Send the data read from the memory */

      SPI_I2S_SendData(SPI3, (Media_ReadHalfWord(AudioDataIndex)));

      /* Increment the index */

          //根据波形文件的通道数目增加播放文件指针地址

      IncrementVar_AudioDataIndex(WAVE_Format.NumChannels);

}

波形文件的格式:

/* .WAV file format :

Endian      Offset      Length      Contents

  big         0           4 bytes     'RIFF'             // 0x52494646

  little      4           4 bytes     

  big         8           4 bytes     'WAVE'             // 0x57415645

Next, the fmt chunk describes the sample format:

  big         12          4 bytes     'fmt '          // 0x666D7420

  little      16          4 bytes     0x00000010      // Length of the fmt data (16 bytes)

  little      20          2 bytes     0x0001          // Format tag: 1 = PCM

  little      22          2 bytes           // Channels: 1 = mono, 2 = stereo

  little      24          4 bytes        // Samples per second: e.g., 22050

  little      28          4 bytes       // sample rate * block align

  little      32          2 bytes        // channels * bits/sample / 8

  little      34          2 bytes        // 8 or 16

Finally, the data chunk contains the sample data:

  big         36          4 bytes     'data'        // 0x64617461

  little      40          4 bytes     

  little      44          *         


菜鸟
2020-08-10 16:14:14     打赏
2楼
此帖仅楼主可见

高工
2020-08-13 20:10:20     打赏
3楼

十分感谢你的分享


共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]