cancel
Showing results for 
Search instead for 
Did you mean: 

ADC Conversion

ezrab
Associate II
Posted on October 12, 2010 at 13:22

hi.

i am trying to activate the adc module with the following program :

__IO uint16_t ADCConvertedValue;

int main(void)

{

int temp=0;

    setsystemclock(); //set system clock to 24Mhz3

    //rcc CONFIGURATION

   RCC->AHBENR=RCC_AHBENR_DMA1EN; //dma clock enable

   RCC->APB2ENR=RCC_APB2ENR_IOPCEN | RCC_APB2ENR_ADC1EN; //portc and ADC clock enable.

    //GPIO CONFIGURATION

   GPIOC->CRL=0x0;// ADC1_IN14

   // DMA configuration:

   DMA1_Channel1->CCR= DMA_CCR1_CIRC |  DMA_CCR1_PSIZE_0 | DMA_CCR1_MSIZE_0 | DMA_CCR1_PL_1; //Circular mode,Read from peripheral,Peripheral size 16-bits,  Memory size 16-bits, Channel priority level High.

   DMA1_Channel1->CNDTR=1; //bytes to be transmitted. Check only 1 channel

   DMA1_Channel1->CPAR = 0x4001244C; //adc address

   DMA1_Channel1->CMAR=(uint32_t)&ADCConvertedValue;

   DMA1_Channel1->CCR |= CCR_ENABLE_Set;

   //ADC configuration

   ADC1->CR1=ADC_CR1_SCAN;

   ADC1->CR2=ADC_CR2_ALIGN | ADC_CR2_EXTSEL ; //data align right , software start

   ADC1->SMPR1=0;// 1.5 cycles conversion time

   ADC1->SQR3=0;

   ADC1->SQR1|=ADC_SQR1_SQ14_0;

   ADC1->CR2 |=ADC_CR1_SCAN  ;  /* Enable ADC1 DMA */

   ADC1->CR2 |=ADC_CR2_ADON; /* Enable ADC1 */

   ADC1->CR2 |=ADC_CR2_RSTCAL ;//reset calibration

   while ((ADC1->CR2 & ADC_CR2_RSTCAL) != 0x00); //wait for   end of ADC1 reset calibration register

   ADC1->CR2 |=ADC_CR2_CAL;/* Start ADC1 calibaration */

   while((ADC1->CR2 & ADC_CR2_CAL) != 0x00);/* Check the end of ADC1 calibration */

   ADC1->CR2 |=ADC_CR2_SWSTART |ADC_CR2_EXTTRIG; /* Start ADC1 Software Conversion */

    while(1)

    {

  if((ADC1->SR&ADC_SR_EOC)>0)

  {

    temp=ADC1->DR;

    ADC1->CR2 |=ADC_CR2_SWSTART |ADC_CR2_EXTTRIG; /* Start ADC1 Software Conversion */

    temp=temp+1;

  }

    }

}

but if i put GND in PC4 which is channel 14 i dont get zero in  ADC1->DR.

why what am i doing wrong?

thanks.
12 REPLIES 12
Posted on October 12, 2010 at 14:44

So, are you using DMA or Polled IO?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
ezrab
Associate II
Posted on October 12, 2010 at 15:24

basicly i am just trying to activate the adc module in diffrent modes.

in this emaple i used the dma for polling the adc but i dont realy need it.

as i understand using the dma for polling makes it faster right?

any way if i could activate it even with out the DMA it would be great.

so what am i doing worg?

thanks.

ezrab
Associate II
Posted on October 12, 2010 at 16:46

i found what was wrong the channel selection was wrog as i figure it out the line:

ADC1->SQR3=0xe;//channel number first conversion

determines that the first sequnce of conversion will be channel 14 right?

Posted on October 12, 2010 at 19:14

This also works..

int main(void)

{

  int led, adc;

  GPIO_InitTypeDef GPIO_InitStructure;

    ADC_InitTypeDef  ADC_InitStructure;

  /* Initialise LEDs LD3&LD4, both off */

  STM32vldiscovery_LEDInit(LED3);

  STM32vldiscovery_LEDInit(LED4);

  led = 0;

  STM32vldiscovery_LEDOff(LED3);

  STM32vldiscovery_LEDOff(LED4);

  /* Enable ADC1 and GPIOC clock */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);

  /* Configure PC.04 (ADC Channel14) as analog input -------------------------*/

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

  GPIO_Init(GPIOC, &GPIO_InitStructure);

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

  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;

  ADC_InitStructure.ADC_ScanConvMode = ENABLE;

  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;

  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

  ADC_InitStructure.ADC_NbrOfChannel = 1;

  ADC_Init(ADC1, &ADC_InitStructure);

  /* ADC1 regular channel14 configuration */

  ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_55Cycles5);

//  ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_1Cycles5);

  /* Enable ADC1 */

  ADC_Cmd(ADC1, ENABLE);

  /* Enable ADC1 reset calibaration register */

  ADC_ResetCalibration(ADC1);

  /* Check the end of ADC1 reset calibration register */

  while(ADC_GetResetCalibrationStatus(ADC1));

  /* Start ADC1 calibaration */

  ADC_StartCalibration(ADC1);

  /* Check the end of ADC1 calibration */

  while(ADC_GetCalibrationStatus(ADC1));

  /* Start ADC1 Software Conversion */

  ADC_SoftwareStartConvCmd(ADC1, ENABLE);

    while(1)

    {

        if (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == SET)

        {

            adc = ADC_GetConversionValue(ADC1);

            /* Probably overkill */

            ADC_ClearFlag(ADC1, ADC_FLAG_EOC);

          /* Start ADC1 Software Conversion */

          ADC_SoftwareStartConvCmd(ADC1, ENABLE);

      led ^= 1;

      if (led)

        STM32vldiscovery_LEDOff(LED3);

      else

        STM32vldiscovery_LEDOn(LED3);

        }

    }

  /* does not exit - kind of important */

  return(adc);

}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
ezrab
Associate II
Posted on October 14, 2010 at 08:35

hi

thanks for your replay.

i noticed that you changed the conversion to 5 cycle why?

why would i like to make the adc slower?

whats the down side of using the DMA?

doesnt it makes it faster?

joa
Associate II
Posted on October 14, 2010 at 09:47

> why would i like to make the adc slower?

That depends on the output impedance of what you connect to the ADC.

If you meet the requirements from table 42 in the stm32f100x[468B] manual for 1.5 cycles, then go for it.

ezrab
Associate II
Posted on October 14, 2010 at 10:46

sorry i dont realy understand whats the limition in using the 1.5 cycles.

joa
Associate II
Posted on October 14, 2010 at 11:26

RAin (the output impedance of the thing you connect to the ADC) must be at most 400 ohms to get correct readings with 1.5 cycles sample time. You can, for example, not connect a 10 kOhm pot directly, but the output from an OP-amp in a buffer configuration is probably OK.

I guess (someone correct me if I'm wrong) it is because the current needed for the conversion have to be delivered very fast for a short sample time.
ezrab
Associate II
Posted on October 14, 2010 at 12:47

hi.

i have aquestion:

if i want the measure sevrel channels it the fastest way what are my options and how?

thanks.