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

STM32 双ADC同步注入转换模式,模块ADC2没有数据。

[复制链接]
lzylzy1212 提问时间:2025-1-7 15:02 / 未解决

我使用的是stm32g431这款芯片,现在想采样两路模拟信号,为了采样速度更快,想用adc1和adc2两个模块分别对这两路进行采样。使用ADC_DUALMODE_INJECSIMULT(双AD同步注入模式),CUBE配置如下所示,使用定时器更新事件触发ADC注入转换。

ADC1模块配置:

1736232344955_F09FE833-FAC9-4632-8036-845807E21DAE.png

ADC2模块配置(ADC1配置了同步触发,此时ADC2配置页面中无触发源选项配置,其他与ADC1保持不变)

1736232315418_29C1AB7A-97BC-4bcc-8F21-7E38DC237B3D.png

在CUBE生成的初始化代码后添加一些ADC启动代码:

image.png

image.png

问题出现:

只有ADC1的注入通道有数据,ADC2的注入通道无数据。

image.png

想问一下这个是什么情况呢?我试过两个ADC模块都使用独立模式(ADC_MODE_INDEPENDENT),触发源与模块ADC1一致,这样是有数据的。如下:

image.png

修改的代码如下:

1736233243661_61BBA575-3E93-4550-96CE-C58A37A1251B.png

1736233300089_A8E09E0F-EBC8-4249-BA41-33007EF9DCDC.png

收藏 评论4 发布时间:2025-1-7 15:02

举报

4个回答
lzylzy1212 回答时间:昨天 15:04

使用上述配置的双ADC模式同步注入转换,CUBE生成的代码如下:(ADC2无数据)

/* ADC1 init function */
void MX_ADC1_Init(void)
{

  /* USER CODE BEGIN ADC1_Init 0 */

  /* USER CODE END ADC1_Init 0 */

  ADC_MultiModeTypeDef multimode = {0};
  ADC_InjectionConfTypeDef sConfigInjected = {0};

  /* USER CODE BEGIN ADC1_Init 1 */

  /* USER CODE END ADC1_Init 1 */

  /** Common config
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.GainCompensation = 0;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.DMAContinuousRequests = DISABLE;
  hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc1.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure the ADC multi-mode
  */
  multimode.Mode = ADC_DUALMODE_INJECSIMULT;
  multimode.DMAAccessMode = ADC_DMAACCESSMODE_DISABLED;
  multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_1CYCLE;
  if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
  {
    Error_Handler();
  }
  //修改为独立模式
//  multimode.Mode = ADC_MODE_INDEPENDENT;
//  multimode.DMAAccessMode = ADC_DMAACCESSMODE_DISABLED;
//  multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_1CYCLE;
//  if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
//  {
//    Error_Handler();
//  } 
  /** Configure Injected Channel
  */
  sConfigInjected.InjectedChannel = ADC_CHANNEL_1;
  sConfigInjected.InjectedRank = ADC_INJECTED_RANK_1;
  sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_2CYCLES_5;
  sConfigInjected.InjectedSingleDiff = ADC_SINGLE_ENDED;
  sConfigInjected.InjectedOffsetNumber = ADC_OFFSET_NONE;
  sConfigInjected.InjectedOffset = 0;
  sConfigInjected.InjectedNbrOfConversion = 1;
  sConfigInjected.InjectedDiscontinuousConvMode = DISABLE;
  sConfigInjected.AutoInjectedConv = DISABLE;
  sConfigInjected.QueueInjectedContext = DISABLE;
  sConfigInjected.ExternalTrigInjecConv = ADC_EXTERNALTRIGINJEC_T1_TRGO;
  sConfigInjected.ExternalTrigInjecConvEdge = ADC_EXTERNALTRIGINJECCONV_EDGE_RISING;
  sConfigInjected.InjecOversamplingMode = DISABLE;
  if (HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */

  if(HAL_ADCEx_Calibration_Start(&hadc1,ADC_SINGLE_ENDED) != HAL_OK )//ADC模块的自校正(单端信号)
  {
    Error_Handler();
  }
  __HAL_ADC_ENABLE_IT(&hadc1,ADC_IT_JEOC);
  HAL_ADCEx_InjectedStart(&hadc1);
  /* USER CODE END ADC1_Init 2 */

}
/* ADC2 init function */
void MX_ADC2_Init(void)
{

  /* USER CODE BEGIN ADC2_Init 0 */

  /* USER CODE END ADC2_Init 0 */

  ADC_InjectionConfTypeDef sConfigInjected = {0};

  /* USER CODE BEGIN ADC2_Init 1 */

  /* USER CODE END ADC2_Init 1 */

  /** Common config
  */
  hadc2.Instance = ADC2;
  hadc2.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
  hadc2.Init.Resolution = ADC_RESOLUTION_12B;
  hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc2.Init.GainCompensation = 0;
  hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc2.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc2.Init.LowPowerAutoWait = DISABLE;
  hadc2.Init.ContinuousConvMode = DISABLE;
  hadc2.Init.NbrOfConversion = 1;
  hadc2.Init.DiscontinuousConvMode = DISABLE;
  hadc2.Init.DMAContinuousRequests = DISABLE;
  hadc2.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc2.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc2) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Injected Channel
  */
  sConfigInjected.InjectedChannel = ADC_CHANNEL_2;
  sConfigInjected.InjectedRank = ADC_INJECTED_RANK_1;
  sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_2CYCLES_5;
  sConfigInjected.InjectedSingleDiff = ADC_SINGLE_ENDED;
  sConfigInjected.InjectedOffsetNumber = ADC_OFFSET_NONE;
  sConfigInjected.InjectedOffset = 0;
  sConfigInjected.InjectedNbrOfConversion = 1;
  sConfigInjected.InjectedDiscontinuousConvMode = DISABLE;
  sConfigInjected.AutoInjectedConv = DISABLE;
  sConfigInjected.QueueInjectedContext = DISABLE;
  //修改成独立模式后,手动添加以下2行触发源配置代码。
//  sConfigInjected.ExternalTrigInjecConv = ADC_EXTERNALTRIGINJEC_T1_TRGO;
//  sConfigInjected.ExternalTrigInjecConvEdge = ADC_EXTERNALTRIGINJECCONV_EDGE_RISING;  

  sConfigInjected.InjecOversamplingMode = DISABLE;
  if (HAL_ADCEx_InjectedConfigChannel(&hadc2, &sConfigInjected) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC2_Init 2 */
  if(HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED) != HAL_OK )
  {
    Error_Handler();
  }
  HAL_ADCEx_InjectedStart(&hadc2);
  /* USER CODE END ADC2_Init 2 */

}
xmshao 回答时间:昨天 17:05
我这边配置跟你基本一样,启动ADC1 ADC2的注入转换,启动定时器。


然后循环查询转换结果,没有什么问题。


   if( HAL_ADCEx_InjectedPollForConversion(&hadc1,  0xaaaa)== HAL_OK)
   {
   
   ResultADC1=  HAL_ADCEx_InjectedGetValue(&hadc1,  ADC_INJECTED_RANK_1);
   
   ResultADC2=   HAL_ADCEx_InjectedGetValue(&hadc2,  ADC_INJECTED_RANK_1);
     
      __HAL_ADC_CLEAR_FLAG(&hadc1, ADC_FLAG_JEOS);
     
        __HAL_ADC_CLEAR_FLAG(&hadc2, ADC_FLAG_JEOS);
   
   }

rrr.png

我也是ADC1 ADC2各用1个通道,ADC1的通道信号稳定,所以结果稳定。ADC2通道悬空,结果飘动。
lzylzy1212 回答时间:3 小时前

xmshao 发表于 2025-1-7 17:05
我这边配置跟你基本一样,启动ADC1 ADC2的注入转换,启动定时器。</p>
<p>

谢谢回答!

请问你用的也是G431这款芯片验证的吗?我之前有用过F407的双ADC模块同步注入,印象中没出现过问题。。

还有就是,如果你的程序中不加你写的"循环查询转换结果"代码段,只从Watch里面去看寄存器数据hadc1.Instance->JDR1和hadc1.Instance->JDR2,这两个数据是不是也应该一直在刷新呢?我的程序中没有写ADC_IT_JEOS标志位的清除语句,但我觉得这对寄存器中的数据没有影响。

xmshao 回答时间:1 小时前
我也是使用STM32G474芯片,ADC这块474 和 431是一样的。


我把主循环代码 完全 屏蔽掉,只启动ADC1 /2 和TIMER,


依然可以看到结果的变化:


rrr.png




不行,你通过私信把邮件给我,我把配置给你参考下。

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版