STM32
直播中

张丽

8年用户 1581经验值
私信 关注
[问答]

NUCLEO-H743ZI2上使用SAI PDM采集Infineon-IM69D120失败是哪里出了问题?

第一次用MEMS麦克风,参考ProjectsSTM32H743I-EVALExamplesSAISAI_AudioPlayback和把两颗IM69D120连到NUCLEO-H743ZI2的PE2和PE6,得到的PCM数据异常,请帮忙看看是哪里问题?

系统时钟配置如下:


  • /**
  •   * @brief  System Clock Configuration
  •   *         The system Clock is configured as follow :
  •   *            System Clock source            = PLL (HSE BYPASS)
  •   *            SYSCLK(Hz)                     = 400000000 (CPU Clock)
  •   *            HCLK(Hz)                       = 200000000 (AXI and AHBs Clock)
  •   *            AHB Prescaler                  = 2
  •   *            D1 APB3 Prescaler              = 2 (APB3 Clock  100MHz)
  •   *            D2 APB1 Prescaler              = 2 (APB1 Clock  100MHz)
  •   *            D2 APB2 Prescaler              = 2 (APB2 Clock  100MHz)
  •   *            D3 APB4 Prescaler              = 2 (APB4 Clock  100MHz)
  •   *            HSE Frequency(Hz)              = 8000000
  •   *            PLL_M                          = 4
  •   *            PLL_N                          = 400
  •   *            PLL_P                          = 2
  •   *            PLL_Q                          = 4
  •   *            PLL_R                          = 2
  •   *            VDD(V)                         = 3.3
  •   *            Flash Latency(WS)              = 4
  •   * @param  None
  •   * @retval None
  •   */
  • static void SystemClock_Config(void)
  • {
  •   RCC_ClkInitTypeDef RCC_ClkInitStruct;
  •   RCC_OscInitTypeDef RCC_OscInitStruct;
  •   HAL_StatusTypeDef ret = HAL_OK;

  •   /*!< Supply configuration update enable */
  •   HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);

  •   /* The voltage scaling allows optimizing the power consumption when the device is
  •      clocked below the maximum system frequency, to update the voltage scaling value
  •      regarding system frequency refer to product datasheet.  */
  •   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  •   while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}

  •   /* Enable HSE Oscillator and activate PLL with HSE as source */
  •   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  •   RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
  •   RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
  •   RCC_OscInitStruct.CSIState = RCC_CSI_OFF;
  •   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  •   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

  •   RCC_OscInitStruct.PLL.PLLM = 4;
  •   RCC_OscInitStruct.PLL.PLLN = 400;
  •   RCC_OscInitStruct.PLL.PLLFRACN = 0;
  •   RCC_OscInitStruct.PLL.PLLP = 2;
  •   RCC_OscInitStruct.PLL.PLLR = 2;
  •   RCC_OscInitStruct.PLL.PLLQ = 4;

  •   RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
  •   RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_1;
  •   ret = HAL_RCC_OscConfig( RCC_OscInitStruct);
  •   if(ret != HAL_OK)
  •   {
  •     Error_Handler();
  •   }

  • /* Select PLL as system clock source and configure  bus clocks dividers */
  •   RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_PCLK1 |
  •                                  RCC_CLOCKTYPE_PCLK2  | RCC_CLOCKTYPE_D3PCLK1);

  •   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  •   RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
  •   RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
  •   RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
  •   RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
  •   RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
  •   RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
  •   ret = HAL_RCC_ClockConfig( RCC_ClkInitStruct, FLASH_LATENCY_4);
  •   if(ret != HAL_OK)
  •   {
  •     Error_Handler();
  •   }

  •   /*activate CSI clock mondatory for I/O Compensation Cell*/
  •   __HAL_RCC_CSI_ENABLE() ;

  •   /* Enable SYSCFG clock mondatory for I/O Compensation Cell */
  •   __HAL_RCC_SYSCFG_CLK_ENABLE() ;

  •   /* Enables the I/O Compensation Cell */
  •   HAL_EnableCompensationCell();

  • }


SAI+PDM部分代码如下:

  • /******************************************************
  • *                      Macros
  • ******************************************************/
  • /* SAI PDM input definitions */
  • /* SAI input peripheral configuration defines */
  • #define MIC_IN_SAI_PDMx                           SAI4_Block_A
  • #define MIC_IN_SAI_PDMx_CLK_ENABLE()              __HAL_RCC_SAI4_CLK_ENABLE()
  • #define MIC_IN_SAI_PDMx_CLK_DISABLE()             __HAL_RCC_SAI4_CLK_DISABLE()
  • //#define MIC_IN_SAI_PDMx_FS_SCK_AF                 GPIO_AF8_SAI4
  • //#define MIC_IN_SAI_PDMx_FS_SCK_ENABLE()           __HAL_RCC_GPIOE_CLK_ENABLE()
  • //#define MIC_IN_SAI_PDMx_FS_SCK_GPIO_PORT          GPIOE
  • //#define MIC_IN_SAI_PDMx_FS_PIN                    GPIO_PIN_4
  • //#define MIC_IN_SAI_PDMx_SCK_PIN                   GPIO_PIN_5

  • #define MIC_IN_SAI_PDMx_CLK_IN_ENABLE()           __HAL_RCC_GPIOE_CLK_ENABLE()
  • #define MIC_IN_SAI_PDMx_CLK_IN_PIN                GPIO_PIN_2
  • #define MIC_IN_SAI_PDMx_CLK_IN_PORT               GPIOE
  • #define MIC_IN_SAI_PDMx_CLK_AF                    GPIO_AF10_SAI4
  • #define MIC_IN_SAI_PDMx_DATA_IN_ENABLE()          __HAL_RCC_GPIOE_CLK_ENABLE()
  • #define MIC_IN_SAI_PDMx_DATA_IN_PIN               GPIO_PIN_6
  • #define MIC_IN_SAI_PDMx_DATA_IN_PORT              GPIOE
  • #define MIC_IN_SAI_PDMx_DATA_AF                   GPIO_AF9_SAI4
  • #define MIC_IN_SAI_PDMx_IRQHandler                SAI4_IRQHandler
  • #define MIC_IN_SAI_PDMx_IRQ                       SAI4_IRQn
  • #define MIC_IN_SAI_IRQ_PREPRIO                    ((uint32_t)0x0E)

  • /* SAI PDM DMA Stream definitions */
  • #define MIC_IN_SAI_PDMx_DMAx_CLK_ENABLE()         __HAL_RCC_BDMA_CLK_ENABLE()
  • #define MIC_IN_SAI_PDMx_DMAx_STREAM               BDMA_Channel1
  • #define MIC_IN_SAI_PDMx_DMAx_REQUEST              BDMA_REQUEST_SAI4_A
  • #define MIC_IN_SAI_PDMx_DMAx_IRQ                  BDMA_Channel1_IRQn
  • #define MIC_IN_SAI_PDMx_DMAx_PERIPH_DATA_SIZE     DMA_PDATAALIGN_HALFWORD
  • #define MIC_IN_SAI_PDMx_DMAx_MEM_DATA_SIZE        DMA_MDATAALIGN_HALFWORD

  • /* Private define ------------------------------------------------------------*/
  • #define AUDIO_FREQUENCY       SAI_AUDIO_FREQUENCY_16K
  • #define AUDIO_CHANNEL_NUMBER  2U
  • #define AUDIO_BUFFER_SIZE     256U//128U//256U
  • #define AUDIO_PCM_CHUNK_SIZE  32U

  • /* Private macro -------------------------------------------------------------*/
  • /* Audio PDM FS frequency = 128KHz = 8 * 16KHz = 8 * FS_Freq */
  • #define AUDIO_PDM_GET_FS_FREQUENCY(FS)  (FS * 8)

  • /* Private typedef -----------------------------------------------------------*/
  • typedef enum {
  •   BUFFER_OFFSET_NONE = 0,
  •   BUFFER_OFFSET_HALF,
  •   BUFFER_OFFSET_FULL,
  •   BUFFER_OFFSET_ERROR,
  • } BUFFER_StateTypeDef;

  • /* SAI input Handle */
  • SAI_HandleTypeDef         hSaiMic;
  • DMA_HandleTypeDef         hSaiMicDma;

  • /* Buffer containing the PDM samples */
  • #if defined ( __CC_ARM )  /* !< ARM Compiler */
  •   /* Buffer location should aligned to cache line size (32 bytes) */
  •   ALIGN_32BYTES (uint16_t audioPdmBuf[AUDIO_BUFFER_SIZE]) __attribute__((section(".RAM_D3")));
  • #elif defined ( __ICCARM__ )  /* !< ICCARM Compiler */
  •   #pragma location=0x38000000
  •   /* Buffer location should aligned to cache line size (32 bytes) */
  •   ALIGN_32BYTES (uint16_t audioPdmBuf[AUDIO_BUFFER_SIZE]);
  • #elif defined ( __GNUC__ )  /* !< GNU Compiler */
  •   /* Buffer location should aligned to cache line size (32 bytes) */
  •   ALIGN_32BYTES (uint16_t audioPdmBuf[AUDIO_BUFFER_SIZE]) __attribute__((section(".RAM_D3")));
  • #endif

  • /* Buffer containing the PCM samples
  •    Buffer location should aligned to cache line size (32 bytes) */
  • ALIGN_32BYTES (uint16_t audioPcmBuf[AUDIO_BUFFER_SIZE]);
  • //ALIGN_32BYTES (uint16_t pcmChBuf[2][AUDIO_BUFFER_SIZE]);

  • /* PDM Filters params */
  • PDM_Filter_Handler_t  PDM_FilterHandler[2];
  • PDM_Filter_Config_t   PDM_FilterConfig[2];

  • /* Pointer to PCM data */
  • __IO uint32_t pcmPtr;//, pcmChPtr;
  • /* Buffer status variable */
  • __IO BUFFER_StateTypeDef bufferStatus = BUFFER_OFFSET_NONE;

  • /**
  • * @brief  Init PDM Filters.
  • * @param  AudioFreq: Audio sampling frequency
  • * @param  ChannelNumber: Number of audio channels in the PDM buffer.
  • * @retval None
  • */
  • static void AUDIO_IN_PDMToPCM_Init(uint32_t AudioFreq, uint32_t ChannelNumber)
  • {
  •   uint32_t index = 0;

  •   /* Enable CRC peripheral to unlock the PDM library */
  •   __HAL_RCC_CRC_CLK_ENABLE();

  •   for(index = 0; index < ChannelNumber; index++)
  •   {
  •     /* Init PDM filters */
  •     PDM_FilterHandler[index].bit_order  = PDM_FILTER_BIT_ORDER_LSB;//PDM_FILTER_BIT_ORDER_MSB;
  •     PDM_FilterHandler[index].endianness = PDM_FILTER_ENDIANNESS_LE;
  •     PDM_FilterHandler[index].high_pass_tap = 2122358088;
  •     PDM_FilterHandler[index].out_ptr_channels = ChannelNumber;
  •     PDM_FilterHandler[index].in_ptr_channels  = ChannelNumber;
  •     PDM_Filter_Init((PDM_Filter_Handler_t *)( PDM_FilterHandler[index]));

  •     /* Configure PDM filters */
  •     PDM_FilterConfig[index].output_samples_number = AudioFreq/1000;
  •     PDM_FilterConfig[index].mic_gain = 24;
  •     PDM_FilterConfig[index].decimation_factor = PDM_FILTER_DEC_FACTOR_64;
  •     PDM_Filter_setConfig((PDM_Filter_Handler_t *) PDM_FilterHandler[index],  PDM_FilterConfig[index]);
  •   }
  • }

  • /**
  •   * @brief  Convert audio format from PDM to PCM.
  •   * @param  PDMBuf: Pointer to PDM buffer data
  •   * @param  PCMBuf: Pointer to PCM buffer data
  •   * @param  ChannelNumber: PDM Channels number.
  •   * @retval None
  • */
  • static void AUDIO_IN_PDMToPCM(uint16_t *PDMBuf, uint16_t *PCMBuf, uint32_t ChannelNumber)
  • {
  •   uint32_t index = 0;

  •   /* Invalidate Data Cache to get the updated content of the SRAM*/
  •   SCB_InvalidateDCache_by_Addr((uint32_t *)PDMBuf, AUDIO_BUFFER_SIZE);

  •   for(index = 0; index < ChannelNumber; index++)
  •   {
  •     PDM_Filter( ((uint8_t*)(PDMBuf))[index], (uint16_t*) (PCMBuf[index]),  PDM_FilterHandler[index]);
  •   }

  •   /* Clean Data Cache to update the content of the SRAM */
  •   SCB_CleanDCache_by_Addr((uint32_t*)PCMBuf, AUDIO_PCM_CHUNK_SIZE*2);
  • }

  • /**
  •   * @brief  Microphone SAI interface initialization
  •   * @param  None
  •   * @retval None
  •   */
  • void MIC_SAI_Init(void)
  • {
  •   GPIO_InitTypeDef  GPIO_Init;

  •   RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct;

  •   /* Configure PLLSAI4A prescalers */
  •   /* SAI4A: PLL2P = 8MHz/4*128/125 = 2.048MHz */
  •   RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI4A;
  •   RCC_PeriphCLKInitStruct.Sai4AClockSelection = RCC_SAI4ACLKSOURCE_PLL2;
  •   RCC_PeriphCLKInitStruct.PLL2.PLL2P = 125; // 107--2.4MHz, 125--2.048MHz
  •   RCC_PeriphCLKInitStruct.PLL2.PLL2Q = 2;
  •   RCC_PeriphCLKInitStruct.PLL2.PLL2R = 2;
  •   RCC_PeriphCLKInitStruct.PLL2.PLL2N = 128;
  •   RCC_PeriphCLKInitStruct.PLL2.PLL2FRACN = 6144.0;
  •   RCC_PeriphCLKInitStruct.PLL2.PLL2M = 4;
  •   RCC_PeriphCLKInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_1;
  •   RCC_PeriphCLKInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;

  •   if(HAL_RCCEx_PeriphCLKConfig( RCC_PeriphCLKInitStruct) != HAL_OK)
  •   {
  •     Error_Handler();
  •   }

  •   //---------------------------------------------------------------------------
  •   /* SAI MSP Init */
  •   //---------------------------------------------------------------------------
  •   /* Enable SAI clock */
  •   MIC_IN_SAI_PDMx_CLK_ENABLE();

  •   MIC_IN_SAI_PDMx_CLK_IN_ENABLE();
  •   MIC_IN_SAI_PDMx_DATA_IN_ENABLE();

  •   GPIO_Init.Pin = MIC_IN_SAI_PDMx_CLK_IN_PIN;
  •   GPIO_Init.Mode = GPIO_MODE_AF_PP;
  •   GPIO_Init.Pull = GPIO_NOPULL;
  •   GPIO_Init.Speed = GPIO_SPEED_FREQ_HIGH;
  •   GPIO_Init.Alternate = MIC_IN_SAI_PDMx_CLK_AF;
  •   HAL_GPIO_Init(MIC_IN_SAI_PDMx_CLK_IN_PORT,  GPIO_Init);

  •   GPIO_Init.Pull = GPIO_PULLUP;
  •   GPIO_Init.Speed = GPIO_SPEED_FREQ_MEDIUM;
  •   GPIO_Init.Pin = MIC_IN_SAI_PDMx_DATA_IN_PIN;
  •   GPIO_Init.Alternate = MIC_IN_SAI_PDMx_DATA_AF;
  •   HAL_GPIO_Init(MIC_IN_SAI_PDMx_DATA_IN_PORT,  GPIO_Init);

  •   //MIC_IN_SAI_PDMx_FS_SCK_ENABLE();

  •   /* CODEC_SAI pins configuration: FS, SCK, MCK and SD pins
  •   GPIO_Init.Pin = MIC_IN_SAI_PDMx_FS_PIN | MIC_IN_SAI_PDMx_SCK_PIN;
  •   GPIO_Init.Mode = GPIO_MODE_AF_PP;
  •   GPIO_Init.Pull = GPIO_NOPULL;
  •   GPIO_Init.Speed = GPIO_SPEED_FREQ_HIGH;
  •   GPIO_Init.Alternate = MIC_IN_SAI_PDMx_FS_SCK_AF;
  •   HAL_GPIO_Init(MIC_IN_SAI_PDMx_FS_SCK_GPIO_PORT,  GPIO_Init); */

  •   /* Enable the DMA clock */
  •   MIC_IN_SAI_PDMx_DMAx_CLK_ENABLE();

  •   /* Configure the hdma_sai_rx handle parameters */
  •   hSaiMicDma.Init.Request             = MIC_IN_SAI_PDMx_DMAx_REQUEST;
  •   hSaiMicDma.Init.Direction           = DMA_PERIPH_TO_MEMORY;
  •   hSaiMicDma.Init.PeriphInc           = DMA_PINC_DISABLE;
  •   hSaiMicDma.Init.MemInc              = DMA_MINC_ENABLE;
  •   hSaiMicDma.Init.PeriphDataAlignment = MIC_IN_SAI_PDMx_DMAx_PERIPH_DATA_SIZE;
  •   hSaiMicDma.Init.MemDataAlignment    = MIC_IN_SAI_PDMx_DMAx_MEM_DATA_SIZE;
  •   hSaiMicDma.Init.Mode                = DMA_CIRCULAR;
  •   hSaiMicDma.Init.Priority            = DMA_PRIORITY_HIGH;
  •   hSaiMicDma.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
  •   hSaiMicDma.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
  •   hSaiMicDma.Init.MemBurst            = DMA_MBURST_SINGLE;
  •   hSaiMicDma.Init.PeriphBurst         = DMA_MBURST_SINGLE;

  •   hSaiMicDma.Instance = MIC_IN_SAI_PDMx_DMAx_STREAM;

  •   /* Associate the DMA handle */
  •   __HAL_LINKDMA( hSaiMic, hdmarx, hSaiMicDma);

  •   /* Deinitialize the Stream for new transfer */
  •   HAL_DMA_DeInit( hSaiMicDma);

  •   /* Configure the DMA Stream */
  •   HAL_DMA_Init( hSaiMicDma);

  •   /* SAI DMA IRQ Channel configuration */
  •   HAL_NVIC_SetPriority(MIC_IN_SAI_PDMx_DMAx_IRQ, MIC_IN_SAI_IRQ_PREPRIO, 0);
  •   HAL_NVIC_EnableIRQ(MIC_IN_SAI_PDMx_DMAx_IRQ);
  •   //---------------------------------------------------------------------------

  •   /* SAI PDM Input init */
  •   __HAL_SAI_RESET_HANDLE_STATE( hSaiMic);

  •   hSaiMic.Instance                 = MIC_IN_SAI_PDMx;
  •   hSaiMic.Init.AudioMode           = SAI_MODEMASTER_RX;
  •   hSaiMic.Init.Synchro             = SAI_ASYNCHRONOUS;
  •   hSaiMic.Init.SynchroExt          = SAI_SYNCEXT_DISABLE;
  •   hSaiMic.Init.OutputDrive         = SAI_OUTPUTDRIVE_DISABLE;
  •   hSaiMic.Init.NoDivider           = SAI_MASTERDIVIDER_DISABLE;
  •   hSaiMic.Init.FIFOThreshold       = SAI_FIFOTHRESHOLD_HF;//SAI_FIFOTHRESHOLD_EMPTY;//SAI_FIFOTHRESHOLD_HF;
  •   hSaiMic.Init.AudioFrequency      = AUDIO_PDM_GET_FS_FREQUENCY(AUDIO_FREQUENCY);//AUDIO_FREQUENCY;//AUDIO_PDM_GET_FS_FREQUENCY(AUDIO_FREQUENCY);
  •   hSaiMic.Init.Mckdiv              = 0;
  •   hSaiMic.Init.MckOverSampling     = SAI_MCK_OVERSAMPLING_DISABLE;
  •   hSaiMic.Init.MonoStereoMode      = SAI_STEREOMODE;//SAI_MONOMODE;//SAI_STEREOMODE;
  •   hSaiMic.Init.CompandingMode      = SAI_NOCOMPANDING;
  •   hSaiMic.Init.TriState            = SAI_OUTPUT_NOTRELEASED;
  •   hSaiMic.Init.PdmInit.Activation  = ENABLE;
  •   hSaiMic.Init.PdmInit.MicPairsNbr = 1;
  •   hSaiMic.Init.PdmInit.ClockEnable = SAI_PDM_CLOCK1_ENABLE;
  •   hSaiMic.Init.Protocol            = SAI_FREE_PROTOCOL;
  •   hSaiMic.Init.DataSize            = SAI_DATASIZE_16;
  •   hSaiMic.Init.FirstBit            = SAI_FIRSTBIT_LSB;//SAI_FIRSTBIT_MSB;//SAI_FIRSTBIT_LSB;
  •   hSaiMic.Init.ClockStrobing       = SAI_CLOCKSTROBING_FALLINGEDGE;//SAI_CLOCKSTROBING_RISINGEDGE;

  •   hSaiMic.FrameInit.FrameLength       = 16;
  •   hSaiMic.FrameInit.ActiveFrameLength = 1;
  •   hSaiMic.FrameInit.FSDefinition      = SAI_FS_STARTFRAME;
  •   hSaiMic.FrameInit.FSPolarity        = SAI_FS_ACTIVE_HIGH;
  •   hSaiMic.FrameInit.FSOffset          = SAI_FS_FIRSTBIT;

  •   hSaiMic.SlotInit.FirstBitOffset = 0;
  •   hSaiMic.SlotInit.SlotSize       = SAI_SLOTSIZE_DATASIZE;
  •   hSaiMic.SlotInit.SlotNumber     = 1;
  •   hSaiMic.SlotInit.SlotActive     = 0x0000FFFF;//SAI_SLOTACTIVE_0;

  •   /* DeInit SAI PDM input */
  •   HAL_SAI_DeInit( hSaiMic);

  •   /* Init SAI PDM input */
  •   if(HAL_OK != HAL_SAI_Init( hSaiMic))
  •   {
  •     Error_Handler();
  •   }

  •   /* Enable SAI to generate clock used by audio driver */
  •   __HAL_SAI_ENABLE( hSaiMic);

  •   /* Init PDM Filters */
  •   AUDIO_IN_PDMToPCM_Init(AUDIO_FREQUENCY, AUDIO_CHANNEL_NUMBER);

  •   /* Initialize Rx buffer status */
  •   bufferStatus = BUFFER_OFFSET_NONE;
  • }

  • void MIC_Receive_Start(void)
  • {
  •   /* Start the PDM data reception process */
  •   if(HAL_OK != HAL_SAI_Receive_DMA( hSaiMic, (uint8_t*)audioPdmBuf, AUDIO_BUFFER_SIZE))
  •   {
  •     Error_Handler();
  •   }
  • }

  • void MIC_Data_Process(void)
  • {
  •   uint16_t i;

  •   /* Wait Rx half transfer event */
  •   if (bufferStatus == BUFFER_OFFSET_HALF) {

  •     /* Convert the first half of PDM data to PCM */
  •     AUDIO_IN_PDMToPCM((uint16_t*) audioPdmBuf[0],  audioPcmBuf[pcmPtr], AUDIO_CHANNEL_NUMBER);
  • /*
  •     for (i =0; i= AUDIO_BUFFER_SIZE)
  •     {
  •       //qst_util_printf("P:%drn", pcmPtr);
  •       pcmPtr = 0;
  •       //pcmChPtr = 0;
  •       qst_util_serial_send((uint8_t *)audioPcmBuf, 2*AUDIO_BUFFER_SIZE);
  •       //qst_util_serial_send((uint8_t *)pcmChBuf[0], AUDIO_BUFFER_SIZE);
  •     }

  •     /* Toggle LED1 */
  •     BSP_LED_Toggle(LED1);
  •   } else if (bufferStatus == BUFFER_OFFSET_ERROR) {
  •     qst_util_printf("SAI Error: %drn", HAL_SAI_GetError( hSaiMic));

  •     /* Initialize Rx buffer status */
  •     bufferStatus  = BUFFER_OFFSET_NONE;
  •   }

  • }

  • /**
  •   * @brief  Rx Transfer completed callbacks.
  •   * @param  hsai : pointer to a SAI_HandleTypeDef structure that contains
  •   *                the configuration information for SAI module.
  •   * @retval None
  •   */
  • void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai)
  • {

  •   bufferStatus = BUFFER_OFFSET_FULL;
  • }

  • /**
  •   * @brief  Rx Transfer Half completed callbacks
  •   * @param  hsai : pointer to a SAI_HandleTypeDef structure that contains
  •   *                the configuration information for SAI module.
  •   * @retval None
  •   */
  • void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai)
  • {

  •   bufferStatus = BUFFER_OFFSET_HALF;
  • }


  • /**
  •   * @brief SAI error callback.
  •   * @param  hsai pointer to a SAI_HandleTypeDef structure that contains
  •   *              the configuration information for SAI module.
  •   * @retval None
  •   */
  • void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai)
  • {
  •   /* Prevent unused argument(s) compilation warning */
  •   UNUSED(hsai);

  •   bufferStatus = BUFFER_OFFSET_ERROR;
  • }


复制代码
Main函数处理代码如下:

  •   MIC_SAI_Init();

  •   MIC_Receive_Start();

  •   /* Infinite loop */
  •   while (1)
  •   {
  •     MIC_Data_Process();

  •     if(ButtonState != 0)
  •     {
  •      /* Toggle LED1 */
  •       BSP_LED_Toggle(LED1);
  •       ButtonState = 0;
  •       HAL_Delay(5); /* to avoid bounce when button pressed */
  •     }
  •   }



回帖(1)

王涛

2024-4-2 16:55:32
您可以尝试的排查步骤:

1. 对比您的配置与示例代码:确保您的配置与示例代码中的配置相匹配,包括时钟配置、引脚配置等。

2. 确定硬件连接正确:确保IM69D120麦克风正确连接到PE2和PE6引脚,并且相应的引脚已正确配置为SAI功能。

3. 检查时钟源和时钟树配置:确保时钟源配置正确,包括对应的PLL配置、分频系数等。确保系统时钟频率与您预期的频率相匹配。

4. 调试SAI配置:检查SAI配置是否正确。您可以使用调试器跟踪代码执行过程,并查看SAI寄存器的值以确认配置是否正确。

5. 校准麦克风:有时,麦克风可能需要进行校准才能获得正确的输出。检查IM69D120的数据手册,了解如何正确校准该麦克风。


举报

更多回帖

×
20
完善资料,
赚取积分