完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
只实现了USB播放音频功能,至于USB录音和控制音量等功能,找到了相关资料,但是个人没时间往下折腾。
官方程序X-CUBE-USB-AUDIO:https://www.st.com/zh/embedded-software/x-cube-u***-audio.html 文档《UM2195 User manual USB device audio streaming Expansion Package for STM32Cube》:https://www.stmcu.org.cn/document/detail/index/id-219223 本手册与补充STM32Cube™固件库的X-CUBE-USB-AUDIO扩展包相关联,它描述了X-CUBE-USB-AUDIO固件库以及使用方法。 文档和程序要相互配合着看。 本文官方参考程序路径: ..STM32CubeRepositorySTM32Cube_FW_F4_V1.25.0ProjectsSTM324xG_EVALApplicationsUSB_DeviceAUDIO_Standalone 先看看readme.txt程序支持功能。 The device supports the following audio features: 设备支持以下音频功能: - Pulse Coded Modulation (PCM) format -脉冲编码调制(PCM)格式 - sampling rate: 48KHz. -采样率:48KHz。 - Bit resolution: 16 -位分辨率:16 - Number of channels: 2 -频道数:2 - No volume control -无音量控制 - Mute/Unmute capability -静音/取消静音功能 - Asynchronous Endpoints -异步端点 注意:不支持音量控制。即电脑无法控制硬件音量,但是可以通过音频数据控制音量。 STM32CubeIDE配置: 1、I2C控制WM8978寄存器 2、I2S 飞利浦协议,16bit数据帧,音频48KHz。配置DMA普通模式,数据宽度半个字节,使用满FIFO缓存单次传输,这样AHB总线给予DMA数据的优先最高,相对也会占用AHB总线。 3、USB配置:USB设备模式。 4、USB设备,选择为声卡模式,音频采样频率设置48KHz,PID设为0x5730。USB的中断优先级必须降到比0低。 5、时钟配置。 打开《STM32F4xx中文参考手册.pdf》755页。 由于我们使用MCK时钟输出,采样频率48KHz。故需要修改时钟树的分频。 先把PLLM VCO = 1MHz. 6、生成代码。 代码: -USB_Device / App/u***d_desc.c 生成的初始化代码 -USB_Device / App/u***d_desc.h 生成的初始化代码头文件 -USB_Device / App/u***d_audio_if.c USBD音频接口 -USB_Device / App/u***d_audio_if.h USBD音频接口头文件 -USB_Device / App/u***d_desc.c USB设备AUDIO描述符 -USB_Device / App/u***d_desc.h USB设备AUDIO描述符头文件 -USB_Device / Target/u***d_conf.c常规低层驱动程序配置 -USB_Device / Target/ u***d_conf.h USB设备驱动程序配置文件 先打开u***d_audio.c, 看生成的底层驱动特性。 不支持音量控制!!!不支持音量控制!!!不支持音量控制!!!不支持音量控制!!!不支持音量控制!!! 现在需要做的是打开u***d_audio_if.c进行填充函数。 AUDIO_Init_FS, 插入PC会初始化 AUDIO_DeInit_FS, USB在挂起后重新连接PC会调用,再调用AUDIO_Init_FS AUDIO_AudioCmd_FS, 播放控制函数。 AUDIO_VolumeCtl_FS, 音量控制,没用,底层不支持。 AUDIO_MuteCtl_FS, 静音。功能可用。 AUDIO_PeriodicTC_FS, 数据包接收完成回调。 AUDIO_GetState_FS, 获取状态。 还有两个外部函数,用于音频数据i2s半发送和发送完成后要求音频数据同步,即请求PC音频数据的。 void HalfTransfer_CallBack_FS(void) void TransferComplete_CallBack_FS(void) 用到的只有粗体3个函数就行了,初始化我使用外部初始化WM8978,不在USB连接初始化硬件。其他函数功能自己玩。 WM8978的相关函数以前博客写了好多了。跳过。 新建一个audio_player.c,添加如下代码 #include "audio_player.h" #include "wm8978.h" #include "u***d_audio_if.h" extern I2S_HandleTypeDef hi2s2; extern DMA_HandleTypeDef hdma_spi2_tx; void Audio_Player_Play(uint16_t* pBuffer, uint32_t Size) { if(Size > 0xFFFF) Size = 0xFFFF; HAL_I2S_Transmit_DMA(&hi2s2, pBuffer, Size); } void Audio_Player_Pause(void) { HAL_I2S_DMAPause(&hi2s2); } void Audio_Player_Resume(void) { HAL_I2S_DMAResume(&hi2s2); } void Audio_Player_Stop(void) { HAL_I2S_DMAStop(&hi2s2); } void Audio_Player_VolumeCtl(uint8_t vol) { WM8978_VolumeCtl(vol); } void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s) { HalfTransfer_CallBack_FS(); } void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s) { TransferComplete_CallBack_FS(); } 填充u***d_audio_if.c, AUDIO_CMD_START播放前的准备。 AUDIO_CMD_PLAY连续播放。 static int8_t AUDIO_AudioCmd_FS(uint8_t* pbuf, uint32_t size, uint8_t cmd) { /* USER CODE BEGIN 2 */ switch(cmd) { case AUDIO_CMD_START: Audio_Player_Play((uint16_t*)pbuf, size); break; case AUDIO_CMD_PLAY: Audio_Player_Play((uint16_t*)pbuf, size); break; } return (USBD_OK); /* USER CODE END 2 */ } I2S发送完数据,hU***DeviceFS.dev_state检测USB是否还连接。如果是USBD_STATE_CONFIGURED则是连接了PC。 如果不添加获取USB连接状态可能导致I2S一直在发送数据,原因就是USBD_AUDIO_Sync()即使在USB断开的情况下还是能 AUDIO_AudioCmd_FS()的AUDIO_CMD_PLAY触发,导致I2S DMA一直在发数据。 void TransferComplete_CallBack_FS(void) { if(hU***DeviceFS.dev_state == USBD_STATE_CONFIGURED) { USBD_AUDIO_Sync(&hU***DeviceFS, AUDIO_OFFSET_FULL); } } void HalfTransfer_CallBack_FS(void) { if(hU***DeviceFS.dev_state == USBD_STATE_CONFIGURED) { USBD_AUDIO_Sync(&hU***DeviceFS, AUDIO_OFFSET_HALF); } } 主函数main int main(void) { HAL_Init(); SystemClock_Config(); HAL_Delay(100); MX_GPIO_Init(); MX_DMA_Init(); MX_I2C1_Init(); MX_I2S2_Init(); MX_USART1_UART_Init(); MX_USB_DEVICE_Init(); WM8978_Init(); printf("Sudarootrn"); HAL_Delay(1000); while (1) { } } 对了,在初始化WM8978的时候,把音量开到最大。然后PC在调整音量的时候会调整音频PCM数据。故PC无法调整硬件WM8978的音量,但是通过调整发送过来的PCM数据也可以实现控制音量的效果。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1614 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1541 浏览 1 评论
970 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
682 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1592 浏览 2 评论
1863浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
644浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
515浏览 3评论
531浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
504浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 01:29 , Processed in 0.759256 second(s), Total 76, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号