Skip to main content
ra.pamod
Associate II
September 29, 2017
Solved

ADC value not correct for ADC_CHANNEL_12

  • September 29, 2017
  • 3 replies
  • 880 views
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

    This topic has been closed for replies.
    Best answer by ra.pamod
    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

    3 replies

    ra.pamod
    ra.pamodAuthorBest answer
    Associate II
    November 27, 2017
    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
    Senior III
    November 27, 2017
    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.

    ra.pamod
    ra.pamodAuthor
    Associate II
    November 30, 2017
    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.