我使用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");
}
}
}
|