What does ADCXX_INYY represent? Configuring ADC on certain pins from STM32F207ZG Board

adccmicrocontrollerstm32

I have a STM32F207ZG-SK board, and I want to configure pin B0 and A6 to read analog values from another board.

Did I do the setup for pin B0 and A6 correctly? I checked to see if it has ADC and it does, so I just changed certain areas of the code. The code was originally for Pin A0 and C5.

B0 –> ADC12_IN6 so does that mean that its for both ADC1 or ADC2 and that the channel is 6? Information on the ADCXX_INYY can be found here, but it doesn't say what it means.

So I changed

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; 
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; 
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 
GPIO_Init(GPIOA, &GPIO_InitStructure); --> changed to GPIO_Init(GPIOB, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; --> changed to GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; 
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 
GPIO_Init(GPIOC, &GPIO_InitStructure); --> changed to GPIO_Init(GPIOA, &GPIO_InitStructure);

and

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2| RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOE, ENABLE);

–> changed to

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2| RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOE, ENABLE);

Here is the code that I have so far, but for some strange reason its only reading 0's, when it is suppose to read 0.9V.

Information on the configuration of the ADC can be found here.

#define ADC_CCR_ADDRESS   ((uint32_t)0x40012308);

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2| RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOE, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2 |RCC_APB2Periph_ADC1 , ENABLE);
DMA_StructInit(&DMA_InitStructure); 

DMA_DeInit(DMA2_Stream0);  //Set DMA registers to default values
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_CCR_ADDRESS; //Source address*/
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&Adcdata; //Destination address*/
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 2; //Buffer size
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //source size - 16bit
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // destination size = 16b
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; 
DMA_Init(DMA2_Stream0, &DMA_InitStructure); //Initialize the DMA

DMA_Cmd(DMA2_Stream0, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_Init(GPIOB, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_Init(GPIOA, &GPIO_InitStructure);

/*ADC Init*/
// ADC_CommonStructInit(&ADC_CommonInitStruct);
// ADC_CommonInit(&ADC_CommonInitStruct);                         
/*ADC2 configuration*/
ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult;
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;

ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1;
// ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_6Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);

//ADC_CommonInit(&ADC_CommonInitStructure);

ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
// ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1; /* parallel so it is doing one conversion for one channel and one conversion for the other ADC channel*/
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_56Cycles);

ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult;
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
// ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1;
// ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
// ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);

ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
// ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1; //parallel ADC's for both channels. This is for each one

ADC_Init(ADC2, &ADC_InitStructure);

/*ADC2 regular TRIMER_CHANNEL configuration*/
ADC_RegularChannelConfig(ADC2, ADC_Channel_15, 1, ADC_SampleTime_56Cycles);

// ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_56Cycles);

ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
// ADC_DMARequestAfterLastTransferCmd(ADC2, ENABLE);

// ADC_ExternalTrigConvCmd(ADC2, ENABLE);

/* Enable ADC2 */
ADC_Cmd(ADC1, ENABLE);

ADC_Cmd(ADC2, ENABLE);
// ADC_ExternalTrigConvCmd(ADC2, ENABLE);
ADC_DMACmd(ADC1, ENABLE);
ADC_SoftwareStartConv(ADC1); 

Adc1=(((float)Adcdata[0]) * 3.3)/4096;  //voltage value
Adc2=(((float)Adcdata[1]) * 3.3)/4096;  //voltage

Best Answer

So it turns out that ADCXX_INYY, means that XX - the type of ADC's that you can configure to (i.e. 12 = can configure to ADC1 or ADC2). YY represents that GPIO channel where you can configure ADC.

Also, you need to do ADC_CommonInitStructure only once.

Here is the new and improved version of the code for further convenience.

static volatile Int32U TimingDelay;


int i;


__IO Int16U Adcdata[3];


__IO float Adc1=0;
float Adc1_avg=0;


__IO float Adc2=0;
float Adc2_avg=0;


__IO float Adc3=0;
float Adc3_avg=0;

/**************************************************************************************/

void RCC_Configuration(void)
{
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOE, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 | RCC_APB2Periph_ADC3, ENABLE);
}

/**************************************************************************************/


void DelayResolution100us(Int32U Dly)
{
  TimingDelay = Dly;


  while(TimingDelay != 0);
}


/**
  * @brief  Decrements the TimingDelay variable.
  * @param  None
  * @retval None
  */
void TimingDelay_Decrement(void)
{
  if (TimingDelay != 0x00)
  {
    TimingDelay--;
  }
}


void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  /* ADC Channel  8 -> PB0  ADC12_IN8
     ADC Channel  15 -> PC5 ADC12_IN15
     ADC Channel  0 -> PA0 ADC123_IN0
  */

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
}

/**************************************************************************************/

void ADC_Configuration(void)
{

  ADC_DeInit();

  ADC_CommonInitTypeDef ADC_CommonInitStructure;
  ADC_InitTypeDef ADC_InitStructure;

  /* ADC Common Init - COMMON - Do it once, do it first */
  ADC_CommonInitStructure.ADC_Mode = ADC_TripleMode_RegSimult;
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1; // 2 half-words one by one, 1 then 2 then 3
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_6Cycles; //6 or 5?
  ADC_CommonInit(&ADC_CommonInitStructure);

  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE; // 1 Channel - why is it DISABLE?
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // Continuous Conversions
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  //ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO; // Ignored - why include it if ignored?
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = 1;
  ADC_Init(ADC1, &ADC_InitStructure);
  ADC_Init(ADC2, &ADC_InitStructure); // Mirror on ADC2
  ADC_Init(ADC3, &ADC_InitStructure); // Mirror on ADC3

  /* ADC3 regular channel 8 configuration */
  ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_56Cycles); // PB0

  /* ADC2 regular channel 5 configuration */
  ADC_RegularChannelConfig(ADC2, ADC_Channel_15, 1, ADC_SampleTime_56Cycles); // PC5

  /* ADC3 regular channel 0 configuration */
  ADC_RegularChannelConfig(ADC3, ADC_Channel_0, 1, ADC_SampleTime_56Cycles); // PA0

  /* Enable DMA request after last transfer (Multi-ADC mode)  */
  ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);

  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);

  /* Enable ADC2 */
  ADC_Cmd(ADC2, ENABLE);

  /* Enable ADC3 */
  ADC_Cmd(ADC3, ENABLE);

  ADC_DMACmd(ADC1, ENABLE); //enable ADC1 DMA since ADC1 is the master
}

/**************************************************************************************/

static void DMA_Configuration(void)
{
  DMA_InitTypeDef DMA_InitStructure;

  DMA_DeInit(DMA2_Stream0);  //Set DMA registers to default values

  DMA_InitStructure.DMA_Channel = DMA_Channel_0;
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&Adcdata;
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)0x40012308; // CDR_ADDRESS; Packed ADC1, ADC2
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = 3; // Count of 16-bit words
  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_FIFOMode = DMA_FIFOMode_Enable;
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  DMA_Init(DMA2_Stream0, &DMA_InitStructure);

  /* DMA2_Stream0 enable */
  DMA_Cmd(DMA2_Stream0, ENABLE);
}

/**************************************************************************************/

int main(void)
{

  ENTR_CRT_SECTION();

  if(SysTick_Config(SystemCoreClock/10000))
 { 
    while (1);
  }

  EXT_CRT_SECTION();

  RCC_Configuration();

  GPIO_Configuration();

  ADC_Configuration();

  DMA_Configuration();

  /* Start ADC1 Software Conversion */
  ADC_SoftwareStartConv(ADC1);

  /*Turn on Backlight*/
  GLCD_Backlight(BACKLIGHT_ON);
  GLCD_SetFont(&Terminal_9_12_6,0x000F00,0x00FF0);
  GLCD_SetWindow(10,116,131,131);

  /*-------------------Display Readings-----------------------------------------*/


  GLCD_PowerUpInit((pInt8U)IAR_Logo.pPicStream);


  GLCD_Backlight(BACKLIGHT_ON);

  while(1){
    /***** Compute Gain and Phase ****/
        Adc3_avg = 0;
        Adc2_avg = 0;
        Adc1_avg = 0;

        DelayResolution100us(10000);

        for(i=1;i<=20;i++)
        {
          DelayResolution100us(10000);

          Adc1=(((float)Adcdata[0]) * 3.3)/4096;  //voltage value
          Adc1_avg = Adc1_avg + Adc1; //average gain

            //   Adc2con = (Adcdata[1] & 0x0FFF);
          Adc2=(((float)Adcdata[1]) * 3.3)/4096;  //voltage
          Adc2_avg = Adc2_avg + Adc2;//average phase

          //   Adc3con = (Adcdata[1] & 0x0FFF);
          Adc3=(((float)Adcdata[2]) * 3.3)/4096;  //voltage
          Adc3_avg = Adc3_avg + Adc3;//average phase
        }

        Adc1_avg = Adc1_avg/20;
        Adc2_avg = Adc2_avg/20;
        Adc3_avg = Adc3_avg/20;

        //Write to LCD
        GLCD_TextSetPos(0,0);
        GLCD_print("G:%.02f", Adc3_avg);
        GLCD_TextSetPos(7,0);
        GLCD_print("P1:%.02f", Adc2_avg);
        GLCD_TextSetPos(17,0);
        GLCD_print("P2:%.02f", Adc1_avg);
  }; // Don't want to exit
}