2022-05-13 03:41 AM
I'm having some ADC+DMA sampling problems with the H750.
When the ADC+DMA is working, in continuous mode, PC2_C(ADC3_CH0) gets 16bit sampling data which is unstable and constantly jumps between 10000+ and 30000+. I guess there is a problem with the code configuration.
However, the channel PF9(ADC3_CH2) with the same configuration is very stable with only a very small fluctuation.
The ADC clock frequency is 10Mhz.
I checked the errata but could not find a solution.
In HW, both VDDA and Vref+ have a pair of decoupling capacitors near H750, and each ADC channel also has a low-pass filter.
The following is the sample data of PC2_C
bsp_adc.c
#include "bsp_adc.h"
ADC_HandleTypeDef hadc3;
DMA_HandleTypeDef hdma_adc3;
/* ADC3 init function */
void MX_ADC3_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
/** Common config
*/
hadc3.Instance = ADC3;
hadc3.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV16;
hadc3.Init.Resolution = ADC_RESOLUTION_16B;
hadc3.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc3.Init.EOCSelection = ADC_EOC_SEQ_CONV;
hadc3.Init.LowPowerAutoWait = DISABLE;
hadc3.Init.ContinuousConvMode = ENABLE;
hadc3.Init.NbrOfConversion = 6;
hadc3.Init.DiscontinuousConvMode = DISABLE;
hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc3.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;
hadc3.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
hadc3.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
hadc3.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&hadc3) != HAL_OK)
{
////Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_REGULAR_RANK_1;
//sConfig.SamplingTime = ADC_SAMPLETIME_810CYCLES_5;
sConfig.SamplingTime = ADC_SAMPLETIME_387CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
{
////Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
{
////Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = ADC_REGULAR_RANK_3;
if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
{
////Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_8;
sConfig.Rank = ADC_REGULAR_RANK_4;
if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
{
////Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_3;
sConfig.Rank = ADC_REGULAR_RANK_5;
if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
{
//////Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_13;
sConfig.Rank = ADC_REGULAR_RANK_6;
if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
{
////Error_Handler();
}
}
static uint32_t HAL_RCC_ADC12_CLK_ENABLED=0;
void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(adcHandle->Instance==ADC3)
{
/* USER CODE BEGIN ADC3_MspInit 0 */
/* USER CODE END ADC3_MspInit 0 */
/* ADC3 clock enable */
__HAL_RCC_ADC3_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/**ADC3 GPIO Configuration
PF6 ------> ADC3_INP8
PF7 ------> ADC3_INP3
PF9 ------> ADC3_INP2
PH2 ------> ADC3_INP13
PC2_C ------> ADC3_INP0
PC3_C ------> ADC3_INP1
*/
GPIO_InitStruct.Pin = RCB_REV_Pin|IF_BOARD_REV_Pin|VAA5_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
GPIO_InitStruct.Pin = AEC_REV_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(AEC_REV_GPIO_Port, &GPIO_InitStruct);
HAL_SYSCFG_AnalogSwitchConfig(SYSCFG_SWITCH_PC2, SYSCFG_SWITCH_PC2_OPEN);
HAL_SYSCFG_AnalogSwitchConfig(SYSCFG_SWITCH_PC3, SYSCFG_SWITCH_PC3_OPEN);
/* ADC3 DMA Init */
/* ADC3 Init */
hdma_adc3.Instance = DMA1_Stream2;
hdma_adc3.Init.Request = DMA_REQUEST_ADC3;
hdma_adc3.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_adc3.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_adc3.Init.MemInc = DMA_MINC_ENABLE;
hdma_adc3.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_adc3.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_adc3.Init.Mode = DMA_CIRCULAR;
hdma_adc3.Init.Priority = DMA_PRIORITY_LOW;
hdma_adc3.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_adc3) != HAL_OK)
{
////Error_Handler();
}
__HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc3);
/* USER CODE BEGIN ADC3_MspInit 1 */
/* USER CODE END ADC3_MspInit 1 */
}
}
void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
{
if(adcHandle->Instance==ADC3)
{
/* USER CODE BEGIN ADC3_MspDeInit 0 */
/* USER CODE END ADC3_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_ADC3_CLK_DISABLE();
/**ADC3 GPIO Configuration
PF6 ------> ADC3_INP8
PF7 ------> ADC3_INP3
PF9 ------> ADC3_INP2
PH2 ------> ADC3_INP13
PC2_C ------> ADC3_INP0
PC3_C ------> ADC3_INP1
*/
HAL_GPIO_DeInit(GPIOF, RCB_REV_Pin|IF_BOARD_REV_Pin|VAA5_Pin);
HAL_GPIO_DeInit(AEC_REV_GPIO_Port, AEC_REV_Pin);
/* ADC3 DMA DeInit */
HAL_DMA_DeInit(adcHandle->DMA_Handle);
/* USER CODE BEGIN ADC3_MspDeInit 1 */
/* USER CODE END ADC3_MspDeInit 1 */
}
}
2022-05-13 07:00 AM
What is the source of the ADC "async" clock?
There is a nasty Cube bug in ADC clock source configuration.
If your init code is affected, will have to wait for fix.
2022-05-13 07:31 AM
Are you sure about 10Mhz sampling frequency?
Check DM00609692 and dm00628458:
in Cube IDE configurator: SystemCore → RCC → Product Revision → rev.Y / rev.V
(must provide 2x frequency revision V compared to revision Y).
2022-05-16 02:49 AM
Thanks for your reply. The ASYNC clock source is adc_ker_ck_input. This project was created with MX 5, so the bug in MX 6.5 and IDE 1.9 shouldn't exist.
2022-05-16 02:50 AM
Sorry, 10Mhz sampling frequency is my mistake, 10Mhz should be Fadc_ker_ck. The configuration of Rev V and Rev Y in RCC is something I didn't pay attention to before, and I also chose the wrong Rev. Thank you for reminding me. I will do some tests to see if this change solves my problem.
2022-05-16 05:17 AM
You can attach your IOC file if problem still exists. Make sure that "PC2_C(ADC3_CH0)" is not connected to something else (some IC). Also, some glitches may occur if you configure input as differential, but input signal do not satisfy this:
There is still possibility that there is some bug in your code. Have you tried simplest possible read of ADC value without DMA?
2022-05-18 09:34 AM
Thanks for your reply.
PC2_C(ADC3_CH0) is indeed connected to other circuits at the same time, but the possibility of causing problem has been ruled out by disconnecting other circuit.
ADC is configured in single-ended input mode in ioc.
ADC data is OK without DMA mode, which is one of the methods I'm trying.