cancel
Showing results for 
Search instead for 
Did you mean: 

ADC value not correct for ADC_CHANNEL_12

ra.pamod
Associate III
Posted on September 29, 2017 at 14:32

Hello,

I am using STM32F446 MCU. ADC chnanel 10 & ADC channel 12.

ADC ref voltage is 3.0V.

I am getting 0 count for 0v on ADC channel 10.

But I get ADC count value 87 for ADC channel 12. which calculates to 1 V.

what could be the issue?.

Reading is taken every 10ms.

Please find the ADC code below:

#define ADC_DMA_CHANNEL2         DMA_Channel_2

#define ADC_DMA_STREAM             DMA2_Stream0

void StartAnalogReadout_STM32f4(void)

{

static CAlarmRTC alarm(0, 10);

DMA_InitTypeDef DMA_InitStruct;

ADC_CommonInitTypeDef ADC_CommonStruct;

ADC_InitTypeDef ADC_InitStruct;

GPIO_InitTypeDef GPIO_InitStruct;

uint32 addr = (uint32)adc_buffer;

/* System clocks configuration ---------------------------------------------*/

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOC, ENABLE);

RCC_APB2PeriphClockCmd(/*RCC_APB2Periph_ADC1 |*/ RCC_APB2Periph_ADC3, ENABLE);

/* GPIO configuration ------------------------------------------------------*/

// This is for revision P289Rev01c

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_2;

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;

GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_25MHz;

GPIO_Init(GPIOC, &GPIO_InitStruct);

/* DMA2 channel0 configuration ----------------------------------------------*/

// InitStructure(DMA_InitStruct);

memset(&DMA_InitStruct,0,sizeof(DMA_InitStruct));

DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;

DMA_InitStruct.DMA_Channel = ADC_DMA_CHANNEL2;

DMA_InitStruct.DMA_BufferSize = 2;

DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable;

DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;

DMA_InitStruct.DMA_Memory0BaseAddr = (uint32)addr;

DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;

DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;

DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32)&(ADC3->DR);

DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;

DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

DMA_InitStruct.DMA_Priority = DMA_Priority_Low;

DMA_Init(ADC_DMA_STREAM, &DMA_InitStruct);

/* ADC1 configuration ------------------------------------------------------*/

ADC_CommonStruct.ADC_Mode = ADC_Mode_Independent;

ADC_CommonStruct.ADC_Prescaler = ADC_Prescaler_Div8;

ADC_CommonStruct.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;

ADC_CommonStruct.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;

ADC_CommonInit(&ADC_CommonStruct);

ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b;

ADC_InitStruct.ADC_ScanConvMode = ENABLE;

ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;

ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_UNUSED;

ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;

ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;

ADC_InitStruct.ADC_NbrOfConversion = 2;

// ADC_Init(ADC1, &ADC_InitStruct);

ADC_Init(ADC3, &ADC_InitStruct);

/* ADC1 regular channel configuration */

// ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_15Cycles);

// ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 2, ADC_SampleTime_15Cycles);

ADC_RegularChannelConfig(ADC3, ADC_Channel_10, 1, ADC_SampleTime_15Cycles);

ADC_RegularChannelConfig(ADC3, ADC_Channel_12, 2, ADC_SampleTime_15Cycles);

/* Enable DMA request after last transfer (Single-ADC mode) */

// ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);

ADC_DMARequestAfterLastTransferCmd(ADC3, ENABLE);

/* Enable DMA2 channel0 */

DMA_Cmd(ADC_DMA_STREAM, ENABLE);

/* Enable ADC1/3 DMA */

//ADC_DMACmd(ADC1, ENABLE);

ADC_DMACmd(ADC3, ENABLE);

/* Enable ADC1/3 */

// ADC_Cmd(ADC1, ENABLE);

ADC_Cmd(ADC3, ENABLE);

// while( !ADC_GetFlagStatus( ADC3, ADC_FLAG_OVR ) );

ADC_SoftwareStartConv(ADC3);

/* Start the ADC trigger alarm */

alarm.SetAlarm(ADC_Conversion, NULL);

// /*printdbg(DEBUG_SHOW_ALWAYS,*/trace_printf('StartAnalogReadout_STM32f4: ADC starting (%d ms)', cyg_current_millies());

}

static void ADC_Conversion(void* data)

{

static uint8 index = 0;

// Update ADC3.4/5

adc_values[0] = adc_buffer[s_idx_mapping[0]];

adc_values[1] = adc_buffer[s_idx_mapping[1]];

// // Stop DMA transfer

ADC3->CR2 &= ~(uint32)ADC_CR2_DMA;

// Overrun happens?

if (ADC3->SR & ADC_SR_OVR) {

ADC3->SR &= ~ADC_SR_OVR;

}

// Trigger Conversion again

ADC3->CR2 |= (ADC_CR2_SWSTART | ADC_CR2_DMA);

/*printdbg(DBG_SHOW_ALWAYS, 'ADC3: SR=%04Xh DMA=%04X (%u,%u)',

ADC3->SR, ADC_DMA_STREAM->CR,

adc_buffer[0],adc_buffer[1]);*/

}

Regards

Pramod

1 ACCEPTED SOLUTION

Accepted Solutions
ra.pamod
Associate III
Posted on November 27, 2017 at 07:02

Hi, 

The issue is resolved, I reduced the sampling rate to ADC_SampleTime_56Cycles now it works.

Anything below this value gives me wrong reading on the second channel.

Regards

Pramod

View solution in original post

3 REPLIES 3
ra.pamod
Associate III
Posted on November 27, 2017 at 07:02

Hi, 

The issue is resolved, I reduced the sampling rate to ADC_SampleTime_56Cycles now it works.

Anything below this value gives me wrong reading on the second channel.

Regards

Pramod

AvaTar
Lead
Posted on November 27, 2017 at 14:28

ADC ref voltage is 3.0V.

...

But I get ADC count value 87 for ADC channel 12. which calculates to 1 V.

Incorrect.

For the 12 bit resolution, this translates to roughly 64mV.

Posted on November 30, 2017 at 13:32

Hi,

64mV is with reference to 3.0V but I am using voltage divider ratio of 16 to calculate the voltage.

(87*3*1000*16)/(4096*1000).

The external max is 32V.