STM32 USB AUDIO 基础篇①——通过STM32CubeMX生成USB Speaker音频播放Demo(史上最简单)

怼烎@ 2022-09-04 06:50 830阅读 0赞

文章目录

  • 一、硬件原理
  • 二、STM32CubeMX配置
    • 2.1 RCC
    • 2.2 SYS
    • 2.3 I2C1
    • 2.4 USART1
    • 2.5 USB_OTG_FS
    • 2.6 I2S2
    • 2.7 USB_DEVICE
    • 2.8 Clock Configuration
    • 2.9 Project Manager
    • 2.10 生成代码
  • 三、代码完善
    • 3.1 WM8978
    • 3.2 usbd_audio_if
  • 四、程序流程图
    • 4.1 初始化流程
    • 4.2 播放流程

一、硬件原理

基于正点原子STM32F407探索者开发板,其中音频部分硬件原理图如下

其中WM8978是一款全功能音频处理器,STM32通过控制WM8978即可实现扬声器/喇叭的音频播放,麦克风的音频录制等功能。

主要控制两个接口

  • IIC控制接口,实现WM8978寄存器的读写
  • I2S数字音频接口,实现音频数据传输(接收和发送)
    在这里插入图片描述

二、STM32CubeMX配置

2.1 RCC

开发板外接了两个晶振

  • 8MHz的高速晶振
  • 32.768kHz的低速晶振

在这里插入图片描述

2.2 SYS

Debug Serial Wire
在这里插入图片描述

2.3 I2C1

  • GPIO口是PB8/PB9
    在这里插入图片描述
    在这里插入图片描述

2.4 USART1

  • 用来打印调试日志,波特率调到1000000,加快日志打印
  • Data Direction: Transmit Only
  • DMA Settings: USART1_TX
  • PA9 / PA10
    在这里插入图片描述
    在这里插入图片描述

2.5 USB_OTG_FS

  • Mode:Device Only
  • global interrupt 勾选
    在这里插入图片描述

2.6 I2S2

  • mode: Full-Duplex Master
  • Audio Frequency: 48KHz
  • DMA Setting: SPI2_TX / I2S2_EXT_RX
  • GPIO Setting
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述

2.7 USB_DEVICE

  • Class For FS IP: Audio Device Class
  • USBD_AUDIO_FREQ: 48000 sample/s
  • 描述符有些部分可以自定义
    在这里插入图片描述
    在这里插入图片描述

2.8 Clock Configuration

在这里插入图片描述
在这里插入图片描述

2.9 Project Manager

  • 堆栈调大0x4000
    在这里插入图片描述

2.10 生成代码

  • 右上角 GENERATE CODE

三、代码完善

在这里插入图片描述

3.1 WM8978

main.c

  • main函数增加WM8978_Init();

    int main(void)
    {
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_DMA_Init();
    MX_I2C1_Init();
    MX_I2S2_Init();
    MX_USART1_UART_Init();
    MX_USB_DEVICE_Init();
    WM8978_Init();
    while (1)
    {
    }
    }

wm8978.c

  1. #define DEVICE_ADDRESS 0x1A
  2. #define WIRTE_ADDRESS (DEVICE_ADDRESS << 1 | 0)
  3. extern I2C_HandleTypeDef hi2c1;
  4. uint8_t WM8978_Write(uint8_t reg_addr, uint16_t data)
  5. {
  6. uint8_t pData[10] = { 0 };
  7. pData[0] = (reg_addr << 1) | ((data >> 8) & 0x01);
  8. pData[1] = data & 0xFF;
  9. return HAL_I2C_Master_Transmit(&hi2c1, WIRTE_ADDRESS, pData, 2, 1000);
  10. }
  11. uint32_t WM8978_Init(void)
  12. {
  13. WM8978_Reset();
  14. WM8978_Write(1, 0x0F); // 模拟放大器使能, 使能输出输入缓存区
  15. WM8978_Write(3, 0x7F); // 使能左右声道和L\ROUT2
  16. WM8978_Write(4, 0x10); // I2S 16bit
  17. WM8978_Write(6, 0x00); // MCU提供时钟
  18. WM8978_Write(10, 0x08); // 输出音质最好
  19. WM8978_Write(43, 0x10); // ROUT2反相
  20. WM8978_VolumeCtl(0x3F);
  21. return 0;
  22. }
  23. uint32_t WM8978_Reset(void)
  24. {
  25. if(WM8978_Write(0, 0)!= HAL_OK)// 软复位
  26. return 1;
  27. HAL_Delay(10);
  28. return 0;
  29. }

3.2 usbd_audio_if

  • AUDIO_AudioCmd_FS中对应AUDIO_CMD_STARTAUDIO_CMD_PLAYAUDIO_CMD_STOP的操作
  • HAL_I2S_TxCpltCallback对应传输完成的USB同步操作

    extern I2S_HandleTypeDef hi2s2;
    /* @brief Handles AUDIO command. @param pbuf: Pointer to buffer of data to be sent @param size: Number of data to be sent (in bytes) @param cmd: Command opcode @retval USBD_OK if all operations are OK else USBD_FAIL /
    static int8_t AUDIO_AudioCmd_FS(uint8_t
    pbuf, uint32_t size, uint8_t cmd)
    {
    switch(cmd)
    {

    1. case AUDIO_CMD_START:
    2. HAL_I2S_Transmit_DMA(&hi2s2, (uint16_t*)pbuf, size);
    3. break;
    4. case AUDIO_CMD_PLAY:
    5. HAL_I2S_Transmit_DMA(&hi2s2, (uint16_t*)pbuf, size);
    6. break;
    7. case AUDIO_CMD_STOP:
    8. HAL_I2S_DMAStop(&hi2s2);
    9. break;

    }
    return (USBD_OK);
    }

    void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
    {

    1. HalfTransfer_CallBack_FS();

    }

    void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
    {

    1. TransferComplete_CallBack_FS();

    }

四、程序流程图

4.1 初始化流程

mainhal库stm32f4xx_hal_mapwx8978usb_deviceSTM32_USB_DEVICE_LibraryHAL_Init()SystemClock_Config()HAL_Delay(100)MX_GPIO_Init()MX_DMA_Init()MX_I2C1_Init()HAL_I2C_Init()HAL_I2C_MspInit()MX_I2S2_Init()HAL_I2S_Init()HAL_I2S_MspInit()WM8978_Init()MX_USB_DEVICE_Init()USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS)USBD_RegisterClass(&hUsbDeviceFS, &USBD_AUDIO)USBD_AUDIO_RegisterInterface(&hUsbDeviceFS, &USBD_AUDIO_fops_FS)USBD_Start(&hUsbDeviceFS)HAL_Delay(100)while(1)mainhal库stm32f4xx_hal_mapwx8978usb_deviceSTM32_USB_DEVICE_Library

4.2 播放流程

STM32_USB_DEVICE_Libraryusbd_audio_ifhal库AudioCmd(uint8_t *pbuf, uint32_t size, uint8_t cmd)HAL_I2S_Transmit_DMASTM32_USB_DEVICE_Libraryusbd_audio_ifhal库

觉得好,就一键三连呗(点赞+收藏+关注)

发表评论

表情:
评论列表 (有 0 条评论,830人围观)

还没有评论,来说两句吧...

相关阅读

    相关 [STM32]USB调试枚举

    方法1: 插上目标USB,就可以看到目标USB的配置,然后把自己的USB配置成一模一样就行,如下图: ![watermark_type_ZmFuZ3poZW5naGVpdGk