This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] PCM1808:需要帮助了解为什么我的 I2S 控制型 ADC 不适用't 与 STM32F103 搭配使用

Guru**** 2635075 points

Other Parts Discussed in Thread: PCM1808

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/audio-group/audio/f/audio-forum/1587469/pcm1808-need-help-figuring-out-why-my-i2s-controlled-adc-isn-t-work-with-stm32f103

器件型号: PCM1808

我设计了一个板、该板从经过调节的+/–5Vpp 输入将数据输入到 PCM1808 ADC 芯片中、但我无法让 I2S 使用 STM32F103 处理器。 我附上了 schamatics 和用于在 STM32F103 上启动 I2S 数据流的代码片段。

PCM1808 Schematic.png

 

代码:

/*
I2S_ADC.c
*/

#include “includes.h"</s>“

静态 GPIO_InitTypeDef         GPIO_INIT_struct;
静态 DMA_InitTypeDef           DMA_INIT_STRUCT;
静态 TIM_TimeBaseInitTypeDef  TIMER_InitStruct;
静态 NVIC_InitTypeDef           NVIC_InitStruct;
静态 I2S_InitTypeDef           I2S_INIT_struct;

//去隔行到左和右进程缓冲区
void start_process (uint16_t start_val)

  for (uint16_t i = start_val;i < start_val + audio_half_size;i ++)
  {
      Process_Buffer[I/2][I%2]= Audio_Rx_Buffer [i];
  }
}

// ADC 初始化

void SPIADC_Configuration (void)

  //配置 GPIO
  GPIO_PinRemapConfig (GPIO_Remap_SPI3、ENABLE);
   
  //设置引脚 GPIOA I2S
  GPIO_init_struct.GPIO_Pin = GPIO_PIN_15;
  GPIO_INIT_STRUCT.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_init_struct.GPIO_Speed = 50MHz;
  GPIO_Init (GPIOA、&GPIO_init_struct);
   
  //设置引脚 GPIOB I2S
  GPIO_init_struct.GPIO_Pin = GPIO_PIN_3;
  GPIO_INIT_STRUCT.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_init_struct.GPIO_Speed = 50MHz;
  GPIO_Init (GPIOB、&GPIO_init_struct);
   
  //设置引脚 GPIOB I2S
  GPIO_init_struct.GPIO_Pin = GPIO_PIN_5;
  GPIO_init_struct.GPIO_Mode = GPIO_Mode_in_float;
  GPIO_init_struct.GPIO_Speed = 50MHz;
  GPIO_Init (GPIOB、&GPIO_init_struct);
   
  //设置引脚 GPIOC MCK
  GPIO_init_struct.GPIO_Pin = GPIO_PIN_7;
  GPIO_INIT_STRUCT.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_init_struct.GPIO_Speed = 50MHz;
  GPIO_Init (GPIOC、&GPIO_init_struct);
   
   
  //将 NVIC 设置为 DMA 传输
  NVIC_InitStruct.NVIC_IRQChannel = DMA2_Channel1_IRQn;
  NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
  NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStruct.NVIC_IRQChannelCmd =启用;   
  NVIC_Init (&NVIC_InitStruct);
   
  //配置 I2S (SPI3)
  DMA_DeInit (DMA2_Channel1);
  DMA_StructInit (&DMA_init_struct);
  DMA_init_struct.DMA_BufferSize = AUDIO_BUFFER_SIZE;
  DMA_init_struct.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_init_struct.DMA_M2M = DMA_M2M_Disable;
  DMA_INIT_STRUCT.DMA_MemoryBaseAddr =(u32) 和 Audio_Rx_Buffer [0];
  DMA_init_struct.DMA_MemoryDataSize = DMA_MemoryData Size_Word;
  DMA_init_struct.DMA_MemoryInc = Inc_Enable;
  DMA_init_struct.DMA_Mode = DMA_DMA_DMA Mode_Circular;
  DMA_init_struct.DMA_PeripheralBaseAddr =(u32)&SPI3 -> DR;
  DMA_init_struct.DMA_PeripheralDataSize = DMA_PeripheralData Size_Word;
  DMA_init_struct.DMA_PeripheralInc = DMA_Peripheral Inc_Disable;
  DMA_INIT_STRUCT.DMA_PRIORITY = DMA_HIGH; Priority_Very
   
  DMA_Init (DMA2_Channel1、&DMA_init_struct);
   
  //初始化 SPI
  SPI_I2S_DeInit (SPI3);
  I2S_StructInit (&I2S_INIT_struct);
   
  I2S_init_struct.I2S_AudioFreq  = I2S_AudioFreq_96k;
  I2S_init_struct.I2S_CPOL         = I2S_CPOL_Low;
  I2S_init_struct.I2S_DataFormat  = I2S_DataFormat_24b;
  I2S_init_struct.I2S_MCLKOutput  = I2S_MCLK Output_Enable;
  I2S_init_struct.I2S_Mode         = I2S_Rx Mode_Master;
  I2S_init_struct.I2S_Standard    = I2S_Standard_MSB;
   
  I2S_Init (SPI3、&I2S_init_struct);

  //为 I2S 启用 DMA
  SPI_I2S_DMACmd (SPI3、SPI_I2S_DMA Req_Rx、ENABLE);
   
  //启用 I2S
  I2S_Cmd (SPI3、ENABLE);
   
  //启用 DMA 中断
  DMA_ITConfig (DMA2_Channel1、DMA_IT_TC、ENABLE);
  DMA_ITConfig (DMA2_Channel1、DMA_IT_HT、ENABLE);
  DMA_ITConfig (DMA2_Channel1、DMA_IT_TE、ENABLE);
   
  DMA2_Channel1、ENABLE);
}

uint32_t DATA_LOCATION = 0;

void DMA2_Channel1_IRQHandler (void)

  //检查和处理传输完成 (TC)
  if (DMA_GetITStatus (DMA2_IT_TC1)==设置)
  {
    DATA_LOCATION = DMA_GetCurrDataCounter (DMA2_Channel1);
     
    //在完全传输 (TC) 完成时重新填充前半部分。
    start_process (audio_half_size);
     
    DM_ClearITPendingBit (DMA2_IT_TC1);
  }
   
  //检查和处理半转移 (HT)
  if (DMA_GetITStatus (DMA2_IT_HT1)==设置)
  {
    DATA_LOCATION = DMA_GetCurrDataCounter (DMA2_Channel1);
     
    //当半转接 (HT) 完成时、重新填充后半部分。
    start_process (0);
     
    DM_ClearITPendingBit (DMA2_IT_HT1);
  }
   
  //检查和清除传输错误 (TE)
  IF (DMA_GetITStatus (DMA2_IT_TE1)==设置)
  {
    DM_ClearITPendingBit (DMA2_IT_TE1);
  }
}

/*
setup.cpp
*/

#include “includes.h"</s>“

静态 NVIC_InitTypeDef NVIC_InitStructure;

void initSystem (void)

   
  NVIC_PriorityGroupConfig (NVIC_PriorityGroup_2);
   
  //NVIC_SetVectorTable (NVIC_VectTab_flash、0x200);

  /*每个 0.1ms SysTick 计数结束事件*/
  Sys Tick_Config (SystemCoreClock / 1000);
   
   
  NVIC_InitStructure.NVIC_IRQChannel = SysTick_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd =启用;  
  NVIC_Init (&NVIC_InitStructure);
  //NVIC_setpriority (SysTick _IRQn、0x0);
   
  // PCLK2 = HCLK /2  
  RCC_PCLK1Config (RCC_HCLK_Div1);
  RCC_PCLK2Config (RCC_HCLK_Div1);
   
  //启动 GPIO APB 时钟
  RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA、ENABLE);
  RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOB、ENABLE);
  RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOC、ENABLE);
  RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOD、ENABLE);
   
  //在 APB1 时钟中打开 DAC
// RCC_APB1PeriphClockCmd (RCC_APB1Periph_DAC、ENABLE);
   
  //在 APB2 时钟中打开 ADC 1 和 3
  RCC_APB2PeriphClockCmd(RCC_APB2PeriphClockCmd | RCC_APB2Periph_ADC3,启用);
   
  //在 AHB 时钟中打开 DMA 1 和 2
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 | RCC_AHBPeriph_DMA2,启用);
   
////  在 APB2 时钟中开启 SPI3
  RCC_APB1PeriphClockCmd (RCC_APB1Periph_SPI3、ENABLE);

  //在 APB1 时钟中开启 SPI2
  RCC_APB1PeriphClockCmd (RCC_APB1Periph_SPI2、ENABLE);
   
  //在 APB2 时钟中打开 AFIO
  RCC_APB2PeriphClockCmd (RCC_APB2Periph_AFIO、ENABLE);
   
   
  led_pin_configuration();
   
  button_configuration();
   
  adc_start ();
   
  SPIDAC_CONFIGURATION ();
   
  SPIADC_Configuration ();
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Luna:

    很遗憾、我无法调试您的代码、因为我不是  STM32F103 器件的专家。 对于 ADC、请对输入引脚进行范围调整以确保 PCM1808 正在接收预期的输入、并对 I2S 时钟进行范围调整以确保这些引脚也是正确的。

    此外、您的原理图未明确发布、因此我无法在此提供建议。 如果您发送 ADC 部分的清晰片段、以及 I2S 时钟和数据的示波器图像、我可以进一步提供帮助。

    此致、

    Garret

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Garret:

    我能够让 I2S 正常工作。 我现在在将数据解码为 uint32_t 格式时遇到问题、但我相信我会更详细地解决这个问题。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Luna:

    主模式将 BCK 设置为 64*fs、这将 I2S 时隙设置为 32 位。 因此、DOUT 上的数据 应该位于前 24 位、如果有用、后跟 8 个零。

    此致、

    Garret