cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with ADC on custom board

IlliaGx
Associate III

Hello.
I have a problem with the ADC on the custom board with the STM32WB55 chip. I am using a divider and should get something around 2V, but I always get the maximum value - 4095.
I am using this code that I saw in the ST examples.

  HAL_GPIO_WritePin(ADC_OUT_GPIO_Port, ADC_OUT_Pin, GPIO_PIN_SET);
  HAL_Delay(50);

  if (HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED) != HAL_OK)
  {
	  Error_Handler();
  }

  if (HAL_ADC_Start_DMA(&hadc1, (uint32_t*)aADCxConvertedData, BATTERY_ARRAY_SIZE) != HAL_OK) {

	  HAL_GPIO_WritePin(ADC_OUT_GPIO_Port, ADC_OUT_Pin, GPIO_PIN_RESET);
	  Error_Handler();
  }

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {
    if(hadc->Instance == ADC1) {

        if (HAL_ADC_Stop_DMA(&hadc1) != HAL_OK) {
        	Error_Handler();
        }
        HAL_GPIO_WritePin(ADC_OUT_GPIO_Port, ADC_OUT_Pin, GPIO_PIN_RESET);
        uint32_t sum_mv = 0;
        for (uint32_t i = 0; i < BATTERY_ARRAY_SIZE; i++) {
            aADCxConvertedData_Voltage_mVolt[i] = __ADC_CALC_DATA_VOLTAGE(VDDA_APPLI, aADCxConvertedData[i]);
            sum_mv += aADCxConvertedData_Voltage_mVolt[i];
        }

        uint16_t avg_mv = sum_mv / BATTERY_ARRAY_SIZE;

        ubDmaTransferStatus = 1;
    }
}

I put a breakpoint on ubDmaTransferStatus and see what it measures.

I use this same code on the nucleo board by shorting PC1 and PC0 with a wire and seeing normal results, around 3294-3296 mV.

This is not a hardware problem, I measured the output of the divider on the pin with an oscilloscope and saw around 2V. I also tested it on two devices.

I attach a project that works with nucleo, maybe this will help somehow.
Please help me.
Regards.

19 REPLIES 19

@IlliaGx wrote:

It's internally connected to the VDDA.


Only on packages which do not have a VREF+ pin.

Your schematic shows that you do have the pin - so you do need to connect it.

This is why it's always important to show the full schematic!

Similarly only last week: https://community.st.com/t5/stm32-mcus-embedded-software/adc-just-giving-raw-value-of-4095-on-all-channels/m-p/800046/highlight/true#M63103

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
IlliaGx
Associate III

Yes, you were right. Thank you very much! Can you please tell me how to configure VREFBUF? I don't have this parameter in the cube.

The settings for VREFBUF are under SYS.

TDK_0-1747160733728.png

 

If you feel a post has answered your question, please click "Accept as Solution".
IlliaGx
Associate III

I think I did it. Thank you very much!

IlliaGx
Associate III

Now it shows something more realistic. If instead of the real 1.72 V the ADC reads 1.1 V (at VDDA_APPLI 2500), is this a problem, or is it normal and I just need to adjust the correction factor?

If the voltage is 1.72 V, you should be reading 1.72 V, within perhaps 50 mV or so. The debugging process goes a lot better if you show us what you're doing.

General tips for ADC accuracy are here:

How to optimize the ADC accuracy in the STM32 MCUs - Application note

If you feel a post has answered your question, please click "Accept as Solution".
IlliaGx
Associate III

Hello.
Thanks for your reply.
I use the same functions that I described at the beginning of the post (check the collected array with the debugger). I also used the VREFBUF setting that you provided me.


@IlliaGx wrote:

Now it shows something more realistic. If instead of the real 1.72 V the ADC reads 1.1 V (at VDDA_APPLI 2500), is this a problem, or is it normal and I just need to adjust the correction factor?


VDDA_APPLI should be renamed to avoid confusion. In the macro the argument is called __VREFANALOG_VOLTAGE__. VDDA has nothing to do with it.


If you followed the link @TDK send you, then you would have known that reading from a high impedance source affects the measurement. Increasing the sampling time would help a bit. But it's better to use a buffer.

Kudo posts if you have the same problem and kudo replies if the solution works.
Click "Accept as Solution" if a reply solved your problem. If no solution was posted please answer with your own.

Yes, I did ADC_SAMPLETIME_640CYCLES_5, and now I get 1.64V. Thanks!

Adding a capacitor can help too. This would absorb some of the current from the sampling and hold phase of acquisition. This might improve it even further. It will also double as a low pass filter.

Kudo posts if you have the same problem and kudo replies if the solution works.
Click "Accept as Solution" if a reply solved your problem. If no solution was posted please answer with your own.