Electrical – stm32 f411re ADC + DMA

adcdmastm32f4

I would like to measure pin PC1 and compare it to Vref to get current voltage. This code below worked on L152re. I changed pin number, ADC1 address and DMA channel. It measures something but I am sure not correct. It oscillates between +/- 300 units. At least Vref should be stable. I am pretty sure that the problem will be with configuration of ADC or DMA. Can someone take a look? Thank you very much.

#include "init.h"
#include "stm32f4xx_rcc.h"

__IO uint16_t ADCConvertedValues[2];

void init_DMA(void){
    DMA_InitTypeDef DMA_initStructure;

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);

    DMA_DeInit(DMA2_Stream0);
    DMA_initStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
    DMA_initStructure.DMA_Memory0BaseAddr = (uint32_t)&ADCConvertedValues;
    DMA_initStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
    DMA_initStructure.DMA_BufferSize = 2;
    DMA_initStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_initStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_initStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_initStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_initStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_initStructure.DMA_Priority = DMA_Priority_High;
    DMA_initStructure.DMA_Channel = DMA_Channel_0;
    DMA_Init(DMA2_Stream0, &DMA_initStructure);

    DMA_Cmd(DMA2_Stream0, ENABLE);    
}

void init_ADC(void){
    GPIO_InitTypeDef GPIO_initStructure;
    ADC_InitTypeDef ADC_initStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

    RCC_HSICmd(ENABLE);
    while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);

    GPIO_initStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_initStructure.GPIO_Mode = GPIO_Mode_AN;
    GPIO_initStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOC, &GPIO_initStructure);

    ADC_DeInit();
    ADC_initStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_initStructure.ADC_Resolution = ADC_Resolution_12b;
    ADC_initStructure.ADC_ContinuousConvMode = ENABLE;
    ADC_initStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConvEdge_None;
    ADC_initStructure.ADC_NbrOfConversion = 2;
    ADC_initStructure.ADC_ScanConvMode = ENABLE;
    ADC_Init(ADC1, &ADC_initStructure);

    ADC_RegularChannelConfig(ADC1,ADC_Channel_11, 1, ADC_SampleTime_144Cycles);
    ADC_RegularChannelConfig(ADC1,ADC_Channel_Vrefint, 2, ADC_SampleTime_144Cycles);

    ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);

    ADC_DMACmd(ADC1, ENABLE);

    ADC_Cmd(ADC1, ENABLE);

    ADC_SoftwareStartConv(ADC1);
}

void init(void){
    init_DMA();
    init_ADC();
}

Best Answer

I have solved my problem. I didn't know I have to set TSVREFE bit in CCR register of ADC. It enables Vrefint channel. Thanks for your time.

ADC->CCR |= 0x00800000;