STM32F4 USB Audio测试

主机:WIN10 64位

设备:STM32F411+PCM5102

STM32CubeMX版本:V6.0.1   

JAVA:JDK 11

______________________________________

一、硬件环境

STM32F411CEU6核心板,USB Type C直接供电

STM32F4 USB Audio测试_第1张图片

PCM5102模块,采用5V供电,I2S接口

STM32F4 USB Audio测试_第2张图片

管脚连接:

PCM5102:BCK  ------>   STM32F411:PA5

PCM5102:DIN   ------>   STM32F411:PA7

PCM5102:LCK  ------>   STM32F411:PA4

 

二、STM32CubeMX配置

1、时钟选择:采用外部晶振

STM32F4 USB Audio测试_第3张图片

 

 

2、I2S配置:半双工,只有音频播放,没有音频采集;采用48K采样率,I2S标准

STM32F4 USB Audio测试_第4张图片

3、DMA配置:I2S采用DMA进行发送数据,16bit数据宽度

STM32F4 USB Audio测试_第5张图片

4、USB配置:选择audio device class设备类型,采样率48K

STM32F4 USB Audio测试_第6张图片

 

STM32F4 USB Audio测试_第7张图片

5、时钟配置:外部晶振位8M

STM32F4 USB Audio测试_第8张图片

6、项目配置:注意堆栈大小设置,如果太小,导致程序运行异常,会电脑识别USB失败的现象

STM32F4 USB Audio测试_第9张图片

7、生成项目代码

二、打开项目代码

          CubeMX只是生成了基础框架,在usbd_audio_if.c文件里提供好了usb audio的上层接口函数,但函数里面都是空的,需要自己添加代码实现音频数据的播放,这里我们是采用DMA把音频数据发送到I2S接口,而I2S和DMA的功能函数已经由CubeMX生成好了,我们直接调用即可。

1、把音频数据通过DMA发送到I2S

         usbd_audio_if.c代码里面我们唯一需要关心的就是AUDIO_AudioCmd_FS()函数,它在收到电脑发过来的音频数据时被调用,在这个函数里我们要把音频数据通过DMA发送给I2S,需要增加如下两行代码

STM32F4 USB Audio测试_第10张图片

hi2s1是在main.c里定义的,usbd_audio_if.c在使用时要用extern声明一下。

2、DMA完成数据发送后,处理回调

        我们向I2S注册两个回调函数,一个是数据发送到一半时的回调,一个是数据完全发送后的回调,首先我们要先在stm32f4xx_hal_conf.h头文件里打开注册回调的宏

#define  USE_HAL_I2S_REGISTER_CALLBACKS         1U /* I2S register callback enable       */

      然后在main.c里面对I2S初始化时进行注册

static void MX_I2S1_Init(void)
{

  /* USER CODE BEGIN I2S1_Init 0 */

  /* USER CODE END I2S1_Init 0 */

  /* USER CODE BEGIN I2S1_Init 1 */

  /* USER CODE END I2S1_Init 1 */
  hi2s1.Instance = SPI1;
  hi2s1.Init.Mode = I2S_MODE_MASTER_TX;
  hi2s1.Init.Standard = I2S_STANDARD_PHILIPS;
  hi2s1.Init.DataFormat = I2S_DATAFORMAT_16B;
  hi2s1.Init.MCLKOutput = I2S_MCLKOUTPUT_DISABLE;
  hi2s1.Init.AudioFreq = I2S_AUDIOFREQ_48K;
  hi2s1.Init.CPOL = I2S_CPOL_LOW;
  hi2s1.Init.ClockSource = I2S_CLOCK_PLL;
  hi2s1.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_DISABLE;
  if (HAL_I2S_Init(&hi2s1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN I2S1_Init 2 */
	HAL_I2S_RegisterCallback(&hi2s1, HAL_I2S_TX_COMPLETE_CB_ID, I2S_TX_Complete_Callback);
	HAL_I2S_RegisterCallback(&hi2s1, HAL_I2S_TX_HALF_COMPLETE_CB_ID, I2S_TX_HalfComplete_Callback);
  /* USER CODE END I2S1_Init 2 */

}

       这两个回调函数的处理很简单,只是调用一下usbd_audio_if.c的传输完成的回调函数,TransferComplete_CallBack_FS()和HalfTransfer_CallBack_FS()都是调用USBD_AUDIO_Sync()函数把后续的音频数据继续通过DMA发送到I2S。

void I2S_TX_Complete_Callback(I2S_HandleTypeDef *hi2s1)
{
	TransferComplete_CallBack_FS();
}

void I2S_TX_HalfComplete_Callback(I2S_HandleTypeDef *hi2s1)
{
	HalfTransfer_CallBack_FS();
}

三、编译,下载

          如果硬件没有什么问题的话,下载后,把设备连接到电脑就可以正常识别的音频设备了

STM32F4 USB Audio测试_第11张图片

           用bus hound可以看到设备的枚举过程

STM32F4 USB Audio测试_第12张图片

把电脑的音频播放设备切换成自己的设备

STM32F4 USB Audio测试_第13张图片

可以看到已经有音频数据发送到设备了

STM32F4 USB Audio测试_第14张图片

四、遇到的问题

1、堆栈设置的太小,导致USB识别失败

STM32F4 USB Audio测试_第15张图片

2、CubeMX生成的项目代码默认的编译优化等级为LEVEL2,在USB进行get_cur获取配置时,程序异常,进入HardFault,导致USB识别失败,暂时先把优化等级设置成0

STM32F4 USB Audio测试_第16张图片

3、硬件一开始采用杜邦线连接,播放的声音失真,是由于接触不良导致信号传输不完整,最好采用焊接方式连接。

4、间隔4秒左右,声音出现一点杂音,通过调试信息输出发现,声音正常时,每次的play size为7680字节,当出现7676时,声音就有杂音,目前这个问题还不知道是什么原因。

STM32F4 USB Audio测试_第17张图片

你可能感兴趣的:(STM8/32,USB)