cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 ADC/DMA always returns same value.

John Hite
Associate III
Posted on April 19, 2017 at 19:16

STM32F437

I want to use ADC3 with DMA to capture values and have them available when needed but I don't need an ISR. Regardless of changing the input the value never changes. Below is the code I am using. Please give a shout if you see something amiss.

Thanks,

JH

#define ADC_NUM_READINGS 1  

static uint16_t adc3_result;

static const DMA_InitTypeDef dma2 =

{

    DMA_Channel_2,

    ADC3_BASE + 0x4C,                 

    (uint32_t)&adc3_result,               

    DMA_DIR_PeripheralToMemory,

    ADC_NUM_READINGS,

    DMA_PeripheralInc_Disable,

    DMA_MemoryInc_Disable,

    DMA_PeripheralDataSize_HalfWord,

    DMA_MemoryDataSize_HalfWord,

    DMA_Mode_Circular,

    DMA_Priority_High,

    DMA_FIFOMode_Enable,

    DMA_FIFOThreshold_HalfFull,

    DMA_MemoryBurst_Single,

    DMA_PeripheralBurst_Single

};

void adcInit(void)

{

    GPIO_InitTypeDef GPIO_InitStruct;

    ADC_CommonInitTypeDef cInit;

    ADC_InitTypeDef init;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);

    GPIO_StructInit(&GPIO_InitStruct);

    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;

    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;

    GPIO_Init(GPIOA, &GPIO_InitStruct);

    DMA_DeInit(DMA2_Stream0);

    DMA_Init(DMA2_Stream0, (DMA_InitTypeDef*)&dma2);

    DMA_Cmd(DMA2_Stream0, ENABLE);

    cInit.ADC_Mode = ADC_Mode_Independent;

    cInit.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;

    cInit.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;

    cInit.ADC_Prescaler = ADC_Prescaler_Div2;

    ADC_CommonInit(&cInit);

    init.ADC_Resolution = ADC_Resolution_12b;

    init.ADC_ScanConvMode = DISABLE;

    init.ADC_ContinuousConvMode = ENABLE;

    init.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;

    init.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO;

    init.ADC_DataAlign = ADC_DataAlign_Right;

    init.ADC_NbrOfConversion = 1;

    ADC_Init(ADC3, &init);

    ADC_RegularChannelConfig(ADC3, ADC_Channel_6, 1, ADC_SampleTime_15Cycles);

    ADC_DMARequestAfterLastTransferCmd(ADC3, ENABLE);

    ADC_DMACmd(ADC3, ENABLE);

    ADC_Cmd(ADC3, ENABLE);

    ADC_SoftwareStartConv(ADC3);

}

uint16_t readVoltage(void)

{

    return adc3_result;

}
6 REPLIES 6
S.Ma
Principal
Posted on April 19, 2017 at 19:59

Try without dma fifo and use an array of 3.elements with incremental memory

By the way for scalability, better write

static uint16_t adc3_result[

ADC_NUM_READINGS];

Adc3_result becomes a pointer... Adjust the code for it.

Otherwise even if the sw is debugged, it would break from 2 samples onward.

pguiet
Associate
Posted on April 19, 2017 at 21:50

Unless you did it elsewhere, turn on DMA clock - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);?

Posted on April 19, 2017 at 20:25

Thanks for posting. I tried these changes but the problem persists.

I changed DMA_FIFOMode to DMA_FIFOMode_Disable and

changed DMA_MemoryInc to DMA_MemoryInc_Enable.

I changed

ADC_NUM_READINGS

back to array and set

ADC_NUM_READINGS

to 3. I had changed it to a scalar as I was trying to follow the example in the SPL.

JH

Posted on April 19, 2017 at 22:15

Thanks for posting.

Good eye, but my mistake for not showing it. It is done elsewhere, but I just just trying to show the essentials of a much larger project and failed to show that step was accounted for.

JH

John F.
Senior
Posted on April 20, 2017 at 08:42

Do you use ADC3_IN6?

On STM32F437xx it is on pin PF8.

Do you use the right pin?

Posted on April 20, 2017 at 17:44

Thanks John, great catch!

I used the right pin but used the wrong ADC, should have been ADC2_6. This is an update of an old board and all of these type readings were mux'ed into ADC3. So John Boy here gets no points for attention to detail.

ADC2->DR has the right info now but the DMA is not doing what I want. I will start a new whine, um, thread about that.