Bad ADC values STM32G0B1
I have problem with the result from ADC. I divide it into two problems and will try to describe them good below. First some facts about the design, software and ADC configuration.
Device: STM32G0B1CCU6
Software using: STM32CubeG0 MCU Firmware Package V1.5.0
Config: HSE=24MHz SYSCLK=40MHz HCLK=APB=20MHz PLLQ=ToUSB=48MHz
SYSCLK=40MHz->ToADC(async) ADC=async/2=20MHz tS=3.5 tCONV=tS+12.5=16 fS=1.25MSps
25000 samples via DMA
PA3 connected to a light sensor, OPT101 via a RC filter (100ohm 1nF).
void HAL_MspInit(void)
{
__HAL_RCC_SYSCFG_CLK_ENABLE();
__HAL_RCC_PWR_CLK_ENABLE();
HAL_SYSCFG_VREFBUF_VoltageScalingConfig(SYSCFG_VREFBUF_VOLTAGE_SCALE1); // Internal voltage reference 2.5V
HAL_SYSCFG_EnableVREFBUF();
HAL_SYSCFG_VREFBUF_HighImpedanceConfig(SYSCFG_VREFBUF_HIGH_IMPEDANCE_DISABLE);
HAL_SYSCFG_StrobeDBattpinsConfig(SYSCFG_CFGR1_UCPD1_STROBE | SYSCFG_CFGR1_UCPD2_STROBE);
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if (hadc->Instance == ADC1) {
__HAL_RCC_ADC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_3; // PA3
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
hDmaAdc.Instance = DMA1_Channel1;
hDmaAdc.Init.Request = DMA_REQUEST_ADC1;
hDmaAdc.Init.Direction = DMA_PERIPH_TO_MEMORY;
hDmaAdc.Init.PeriphInc = DMA_PINC_DISABLE;
hDmaAdc.Init.MemInc = DMA_MINC_ENABLE;
hDmaAdc.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hDmaAdc.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hDmaAdc.Init.Mode = DMA_NORMAL;
hDmaAdc.Init.Priority = DMA_PRIORITY_HIGH;
if (HAL_DMA_Init(&hDmaAdc) != HAL_OK) {
Error_Handler();
}
__HAL_LINKDMA(hadc, DMA_Handle, hDmaAdc);
}
}
static void InitAdc(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
hAdc.Instance = ADC1;
hAdc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2; // ADC Clock Mux
hAdc.Init.Resolution = ADC_RESOLUTION_12B;
hAdc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hAdc.Init.ScanConvMode = ADC_SCAN_SEQ_FIXED;
hAdc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hAdc.Init.LowPowerAutoWait = DISABLE;
hAdc.Init.LowPowerAutoPowerOff = DISABLE;
hAdc.Init.ContinuousConvMode = ENABLE;
hAdc.Init.NbrOfConversion = 1;
hAdc.Init.DiscontinuousConvMode = DISABLE;
hAdc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hAdc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hAdc.Init.DMAContinuousRequests = DISABLE;
hAdc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hAdc.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_3CYCLES_5;
hAdc.Init.OversamplingMode = DISABLE;
hAdc.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
if (HAL_ADC_Init(&hAdc) != HAL_OK) {
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_3;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
if (HAL_ADC_ConfigChannel(&hAdc, &sConfig) != HAL_OK) {
Error_Handler();
}
}#1 Slow rising
I early discover that the first sample seems to be lower than the others. However after looking at curves I noted that is was more than the first sample. Signal is slowly rising. I have made a workaround for this, by sample 1000 extra sample and discard them. The picture show with different serie resistor on the analog input. This is from prototype no 1. The second have different DC level (around 200).
#2 DC offset
It is some kind of DC offset. DC level measured with oscilloscope isn't that low from the ADC. I think that this mysterious DC offset level keep the ADC from see low level signal and therefor give curves like this:
The level is different betwen the two prototype boards I have and seems to differ if I change the RC filter in front of ADC input pin.
#3 Overshoot
It will for some level of signals be a heavy overshoot in the curves from the ADC. Note that the 50 Hz square wave signal to the ADC isn't straight square wave. It is bandwidth limited by the light sensor. So the upper corner to the left of the rising signal shouldn't be sharp, it will round off little like the curves down to right in the pictures. However overshoot and ringing as in these curves shouldn't exist. These cuvres are from prototype number 2 and the DC offset differ from previous curves above.
What have I done wrong?
//Michael
