你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32H7+SAI+DMA双缓冲配置失败.

[复制链接]
Zzzzwq 提问时间:2025-8-23 11:38 / 未解决

我使用STM32H743IIT6配置了SAI1_blockA进行一个音频采集,然后配置了一个DMA进行数据搬运,开始我配置的DMA是手动模式,每次搬运完就进入中断,更换指针地址然后继续开始DMA搬运,但是这个方案在后期似有音频掉点的现象,所以现在想配置一个自动采集的双缓冲模式,使用的函数是HAL_DMAEx_MultiBufferStart_IT,但是就是驱动不起来,是否有大神可以指导一下? 以下是配置代码

int PLL2N_T = 393; 
int PLL2P_T = 32; 
int PLL2FRACN_T = 1770;

void MX_SAI1_Init(void)
{

  /* USER CODE BEGIN SAI1_Init 0 */

  /* USER CODE END SAI1_Init 0 */

  /* USER CODE BEGIN SAI1_Init 1 */

  /* USER CODE END SAI1_Init 1 */

  hsai_BlockA1.Instance = SAI1_Block_A;
  hsai_BlockA1.Init.AudioMode = SAI_MODEMASTER_RX;
  hsai_BlockA1.Init.Synchro = SAI_ASYNCHRONOUS;
  hsai_BlockA1.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
  hsai_BlockA1.Init.NoDivider = SAI_MCK_OVERSAMPLING_DISABLE;
  hsai_BlockA1.Init.MckOverSampling = SAI_MCK_OVERSAMPLING_DISABLE;
  hsai_BlockA1.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_EMPTY;
  hsai_BlockA1.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_MCKDIV;
  hsai_BlockA1.Init.Mckdiv = 1;
  hsai_BlockA1.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
  hsai_BlockA1.Init.MonoStereoMode = SAI_STEREOMODE;
  hsai_BlockA1.Init.CompandingMode = SAI_NOCOMPANDING;
    hsai_BlockA1.Init.MckOutput = SAI_MCK_OUTPUT_ENABLE;

  if (HAL_SAI_InitProtocol(&hsai_BlockA1, SAI_I2S_STANDARD, SAI_PROTOCOL_DATASIZE_24BIT, 2) != HAL_OK)
  {
        printf("error.\r\n");
//    Error_Handler();
  }

    hsai_BlockA1.Init.Mckdiv = 1;

  // 最后再次调用 HAL_SAI_Init 来真正初始化硬件
  if (HAL_SAI_Init(&hsai_BlockA1) != HAL_OK)
  {
      printf("SAI init error.\r\n");
  }
}

void HAL_SAI_MspInit(SAI_HandleTypeDef* saiHandle)
{
HAL_StatusTypeDef state=0;
//  __HAL_RCC_DMAMUX1_CLK_ENABLE();
  GPIO_InitTypeDef GPIO_InitStruct;
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
/* SAI1 */
    if(saiHandle->Instance==SAI1_Block_A)
    {
    /* SAI1 clock enable */

  /** Initializes the peripherals clock
  */
            PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
            PeriphClkInitStruct.PLL2.PLL2M = 1;
            PeriphClkInitStruct.PLL2.PLL2N = PLL2N_T;
            PeriphClkInitStruct.PLL2.PLL2P = PLL2P_T;
            PeriphClkInitStruct.PLL2.PLL2Q = 2;
            PeriphClkInitStruct.PLL2.PLL2R = 2;
            PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_0;
            PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
            PeriphClkInitStruct.PLL2.PLL2FRACN = PLL2FRACN_T;
            PeriphClkInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLL2;
            if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
            {
                printf("PLL init fail.\r\n");
    //      Error_Handler();
            }

            if (SAI1_client == 0)
            {
                 __HAL_RCC_SAI1_CLK_ENABLE();

                /* Peripheral interrupt init*/
                HAL_NVIC_SetPriority(SAI1_IRQn, 0, 0);
                HAL_NVIC_EnableIRQ(SAI1_IRQn);
            }
            SAI1_client ++;

            /**SAI1_A_Block_A GPIO Configuration
            PE2     ------> SAI1_MCLK_A
            PE4     ------> SAI1_FS_A
            PE5     ------> SAI1_SCK_A
            PE6     ------> SAI1_SD_A
            */
            GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6;
            GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
            GPIO_InitStruct.Pull = GPIO_NOPULL;
            GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
            GPIO_InitStruct.Alternate = GPIO_AF6_SAI1;
            HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
            __HAL_RCC_DMA1_CLK_ENABLE();
            /* Peripheral DMA init*/

            hdma_sai1_a.Instance = DMA1_Stream0;
            hdma_sai1_a.Init.Request = DMA_REQUEST_SAI1_A;
            hdma_sai1_a.Init.Direction = DMA_PERIPH_TO_MEMORY;
            hdma_sai1_a.Init.PeriphInc = DMA_PINC_DISABLE;
            hdma_sai1_a.Init.MemInc = DMA_MINC_ENABLE;
            hdma_sai1_a.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
            hdma_sai1_a.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
            hdma_sai1_a.Init.Mode = DMA_CIRCULAR;
            hdma_sai1_a.Init.Priority = DMA_PRIORITY_VERY_HIGH;

            hdma_sai1_a.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
            hdma_sai1_a.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
            hdma_sai1_a.Init.MemBurst = DMA_MBURST_SINGLE;
            hdma_sai1_a.Init.PeriphBurst = DMA_PBURST_SINGLE;

            HAL_DMA_RegisterCallback(&hdma_sai1_a,HAL_DMA_XFER_CPLT_CB_ID,dma_m0_rxcplt_callback);
            HAL_DMA_RegisterCallback(&hdma_sai1_a,HAL_DMA_XFER_M1CPLT_CB_ID,dma_m1_rxcplt_callback);

            if (HAL_DMA_Init(&hdma_sai1_a) != HAL_OK)
            {
                printf("SAI init fail.\r\n");
            }

//          HAL_SAI_Receive_DMA(&hsai_BlockA1, (uint8_t *)mem_info_ctr.Buffer1Pointer, 5120); //5632*4/1024 = 22

            __HAL_LINKDMA(saiHandle,hdmarx,hdma_sai1_a);

            HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 5, 0);
            HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);

            state = HAL_DMAEx_MultiBufferStart_IT(&hdma_sai1_a, (uint32_t)&SAI1_Block_A->DR, (uint32_t)mem_info_ctr.Buffer1Pointer, (uint32_t)mem_info_ctr.Buffer2Pointer, 5120);/* 开启双缓冲 */
            if(state == HAL_OK)
            {
                printf("Multi config success.\r\n");
            }

    }
}
收藏 评论0 发布时间:2025-8-23 11:38

举报

0个回答

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版