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 读取值的主要内容,如果未能解决你的问题,请参考以下文章