STM32 同步 ADC 仅从 ADC 1 读取值

Posted

技术标签:

【中文标题】STM32 同步 ADC 仅从 ADC 1 读取值【英文标题】:STM32 Simultaneous ADC only reads the values from ADC 1 【发布时间】:2020-11-12 10:14:48 【问题描述】:

我正在尝试让两个 ADC 同时在 STM32H743 上进行采样。但是,我似乎无法正确读取 ADC2 的值。据我了解,在双同步模式下运行时,来自两个 ADC 转换的数据以 32 位字的形式写入缓冲区。我已经设置 STM32CubeMonitor 来读取缓冲区的前 16 位和后 16 位并绘制它们。然而,尽管每个 adc 有不同的输入(一个方波和一个三角形),我只看到 ADC1 上的输入。 ADC2 的值反映了 ADC1 的输入。我不完全确定我做错了什么,因为我尝试了几乎所有我能想到的设置组合。如果有任何见解,我将不胜感激。

我已尝试过 NUCLEO 板和 EVAL 板,但都没有取得多大成功。我正在使用 STM32CubeIDE 来配置所有内容,并使用 STM32CubeMonitor 来监控读取的值。

这是两个 ADC 的配置。

ADC1/ADC2

    static void MX_ADC1_Init(void)


  /* USER CODE BEGIN ADC1_Init 0 */

  /* USER CODE END ADC1_Init 0 */

  ADC_MultiModeTypeDef multimode = 0;
  ADC_ChannelConfTypeDef sConfig = 0;

  /* USER CODE BEGIN ADC1_Init 1 */

  /* USER CODE END ADC1_Init 1 */
  /** Common config 
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  hadc1.Init.Resolution = ADC_RESOLUTION_16B;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.ContinuousConvMode = ENABLE;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;
  hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
  hadc1.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  
    Error_Handler();
  
  /** Configure the ADC multi-mode 
  */
  multimode.Mode = ADC_DUALMODE_REGSIMULT;
  multimode.DualModeData = ADC_DUALMODEDATAFORMAT_32_10_BITS;
  multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_1CYCLE;
  if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
  
    Error_Handler();
  
  /** Configure Regular Channel 
  */
  sConfig.Channel = ADC_CHANNEL_19;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  
    Error_Handler();
  
  /* USER CODE BEGIN ADC1_Init 2 */

  /* USER CODE END ADC1_Init 2 */



/**
  * @brief ADC2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_ADC2_Init(void)


  /* USER CODE BEGIN ADC2_Init 0 */

  /* USER CODE END ADC2_Init 0 */

  ADC_ChannelConfTypeDef sConfig = 0;

  /* USER CODE BEGIN ADC2_Init 1 */

  /* USER CODE END ADC2_Init 1 */
  /** Common config 
  */
  hadc2.Instance = ADC2;
  hadc2.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  hadc2.Init.Resolution = ADC_RESOLUTION_16B;
  hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc2.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc2.Init.LowPowerAutoWait = DISABLE;
  hadc2.Init.ContinuousConvMode = ENABLE;
  hadc2.Init.NbrOfConversion = 1;
  hadc2.Init.DiscontinuousConvMode = DISABLE;
  hadc2.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;
  hadc2.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  hadc2.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
  hadc2.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc2) != HAL_OK)
  
    Error_Handler();
  
  /** Configure Regular Channel 
  */
  sConfig.Channel = ADC_CHANNEL_18;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
  
    Error_Handler();
  
  /* USER CODE BEGIN ADC2_Init 2 */

  /* USER CODE END ADC2_Init 2 */


【问题讨论】:

I'm using STM32CubeIDE to configure everything HAL 是问题的最大可能来源。 【参考方案1】:

你需要这些全局变量:

ALIGN_32BYTES(__IO uint32_t   ADCDualConvertedValues[4]); //array size of your adc ranks
/* dual values */
uint32_t    poz_0_dual          = 0;    //Variable holding ADC1 ADC2 values
uint32_t    poz_1_dual          = 0;    //Variable holding ADC1 ADC2 values
uint32_t    poz_2_dual          = 0;    //Variable holding ADC1 ADC2 values
uint32_t    poz_3_dual          = 0;    //Variable holding ADC1 ADC2 values

/* single VALUES */
uint16_t    poz_0_a             = 0;
uint16_t    poz_0_b             = 0;
uint16_t    poz_1_a             = 0;
uint16_t    poz_1_b             = 0;
uint16_t    poz_2_a             = 0;
uint16_t    poz_2_b             = 0;
uint16_t    poz_3_a             = 0;
uint16_t    poz_3_b             = 0;

您需要将以下代码添加到您的int main(void)

if(HAL_ADC_Start(&hadc2) != HAL_OK)Error_Handler();
if(HAL_ADCEx_MultiModeStart_DMA(&hadc1,(uint32_t *)ADCDualConvertedValues, 4)  != HAL_OK)Error_Handler();             //Must use multimode!

在你的时候(1)

/* passing values */
poz_0_dual                          =   ADCDualConvertedValues[0];
poz_1_dual                          =   ADCDualConvertedValues[1];
poz_2_dual                          =   ADCDualConvertedValues[2];
poz_3_dual                          =   ADCDualConvertedValues[3];
    
/* shifting 32 to 16 */
poz_0_a                             =   (uint16_t) poz_0_dual;
poz_0_b                             =   (uint16_t) (poz_0_dual >> 16);
poz_1_a                             =   (uint16_t) poz_1_dual;
poz_1_b                             =   (uint16_t) (poz_1_dual >> 16);
poz_2_a                             =   (uint16_t) poz_2_dual;
poz_2_b                             =   (uint16_t) (poz_2_dual >> 16);
poz_3_a                             =   (uint16_t) poz_3_dual;
poz_3_b                             =   (uint16_t) (poz_3_dual >> 16);

希望对你有帮助。不要忘记您的 adc.c 中的 multimode.DualModeData = ADC_DUALMODEDATAFORMAT_32_10_BITS;

制造商 费杰斯

【讨论】:

以上是关于STM32 同步 ADC 仅从 ADC 1 读取值的主要内容,如果未能解决你的问题,请参考以下文章

STM32 ADC 值读数过高

STM32ADC同步采样

STM32ADC同步采样

STM32ADC同步采样

stm32f1adc同步模式没数据

STM32-ADC(独立模式双重模式)+DMA读取数据+部分基础知识