You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32H7+FreeRTOS下SAI播放SD卡WAV卡顿失真求助

STM32H7+FreeRTOS下WAV播放卡顿、音质脏污问题排查

在STM32H7控制器搭配FreeRTOS环境中,尝试用单声道扬声器播放SD卡中的WAV文件,目前能出声,但存在音质脏污和播放卡顿的问题。

WAV文件关键参数

  • 格式:PCM
  • 声道:单声道
  • 采样率:44100Hz
  • 采样位深:16bit

SAI2 Block A初始化代码

void MX_SAI2_Init(void)
{

  /* USER CODE BEGIN SAI2_Init 0 */

  /* USER CODE END SAI2_Init 0 */

  /* USER CODE BEGIN SAI2_Init 1 */

  /* USER CODE END SAI2_Init 1 */

  hsai_BlockA2.Instance = SAI2_Block_A;
  hsai_BlockA2.Init.AudioMode = SAI_MODEMASTER_TX;
  hsai_BlockA2.Init.Synchro = SAI_ASYNCHRONOUS;
  hsai_BlockA2.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;
  hsai_BlockA2.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
  hsai_BlockA2.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_EMPTY;
  hsai_BlockA2.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_44K;
  hsai_BlockA2.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
  hsai_BlockA2.Init.MonoStereoMode = SAI_MONOMODE;
  hsai_BlockA2.Init.CompandingMode = SAI_NOCOMPANDING;
  hsai_BlockA2.Init.TriState = SAI_OUTPUT_NOTRELEASED;
  if (HAL_SAI_InitProtocol(&hsai_BlockA2, SAI_I2S_STANDARD, SAI_PROTOCOL_DATASIZE_16BIT, 2) != HAL_OK)
  {
    Error_Handler();
  }

  /* USER CODE BEGIN SAI2_Init 2 */

  /* USER CODE END SAI2_Init 2 */

}

读取文件并DMA发送至SAI的代码片段

//Before infinite loop I extract the overall file size in bytes.

// Infinite Loop
    for(;;)
    {
        if(drv_sdcard_getDmaTransferComplete()==true)
        {
//          BufferRead[0]=0xAA;
//          BufferRead[1]=0xAA;
//
//          ret = HAL_SAI_Transmit_DMA(&hsai_BlockA2, (uint8_t*)BufferRead, 2);
//          drv_sdcard_resetDmaTransferComplete();
            if((firstBytesDiscarded == true)&& (remainingBytes>0))
            {
                //read the next BufferRead size audio samples
                if(remainingBytes < sizeof(BufferAudio))
                {
                    remainingBytes -= drv_sdcard_readDataNoRewind(file_audio1_index, BufferAudio, remainingBytes);
                }
                else
                {
                    remainingBytes -= drv_sdcard_readDataNoRewind(file_audio1_index, BufferAudio, sizeof(BufferAudio));
                }
                //send them by the SAI through DMA
                ret = HAL_SAI_Transmit_DMA(&hsai_BlockA2, (uint8_t*)BufferAudio, sizeof(BufferAudio));
                //reset transmit flag for forbidding next transmit
                drv_sdcard_resetDmaTransferComplete();
            }
            else
            {
                //discard header size first bytes
                //I removed this part here because it works properly on my side
                firstBytesDiscarded = true;
            }
        }

已尝试的优化措施

  • 测试过SAI配置为SAI_I2S_STANDARD及对应PCM的协议参数,两者播放效果均不佳
  • 实测帧同步时钟为43kHz(最接近44.1kHz),认为时钟频率设置正确
  • 尝试用RC滤波器优化音质,测试过20kHz和44kHz截止频率,但滤除信号过多,后续计划尝试其他频率

卡顿现象描述

播放时能听到少量旋律,随后出现杂音[krrrrrrr],接着短暂静音,如此循环至文件结束。当前BufferAudio大小为16*1024字节,恳请协助解决该问题。

内容的提问来源于stack exchange,提问作者Raphlouk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 04:21:48