cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 ADC with DMA output alternating between accurate input values and fixed wrong value.

PKamm.1
Associate

Hello.

I'm having some issues while trying to acquire a simple ADC value. I'm using a single channel ADC with DMA enabled.

My MCU is the STM32F030K6Tb and i'm using a custom board.

I'm trying to use ADC to read stable and continuous battery voltage. To do that, I sample a single channel ADC 32 times (copying the memory from ADC's buffer to a list), and return their mean value, to read any value inconsistencies cause by the system.

The problem is that my ADC's buffer sometimes read the right value and others return an almost constant value between 1700 and 1800, practically in an alternate pattern.

I already checked the input signal and it is really stable.

Here are a few demonstrations:

Ex. 1) ADC Pin connected to VRef (expected value: 4096)

0693W00000VOM6cQAH.png 

Ex. 2) ADC Pin connected to Gnd (expected value: 0)

0693W00000VOM7pQAH.png 

Ex. 3) ADC Pin connected to 2.29V Battery (expected value: 2755)0693W00000VOM9vQAH.png 

Can anyone tell me why this is happening? I would be most grateful.

Here is the main code to the class MyAdc, where I initialize ADC DMA and overwrite HAL_ADC_ConvCpltCallback to input ADC's buffer to a list. (Already tried using the original calls, and got the same results)

void MyADC::start_DMA() {

HAL_ADCEx_Calibration_Start(_hadc_static);

HAL_ADC_Start_DMA(_hadc_static, buffer, channel_length);

}

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {

if(!first_count) {

first_count = true;

for(uint16_t i = 0 ; i < ADC_DMA_READ_AVG; i++) {

memcpy(MyADC::read_buffer_all[i], MyADC::buffer, sizeof(uint32_t) * MyADC::channel_length);

}

}

memcpy(MyADC::read_buffer_all[circular_counter], MyADC::buffer, sizeof(uint32_t) * MyADC::channel_length);

circular_counter = circular_counter + 1 >= ADC_DMA_READ_AVG ? 0 : circular_counter + 1;

}

1 REPLY 1
LCE
Principal

I guess there's another channel enabled, that's why you get the alternating values.

OR that the DMA is set not to half-word, but to word, so you see 2 half-word values.

In case of doubt, throw away tha HAL stuff and set the registers directly.

Much safer, and then you will know what's happening. Hopefully. 😉