AnsweredAssumed Answered

Reading ADC after exactly 1.56 us

Question asked by das.sanjib on Jan 9, 2014
Latest reply on Mar 11, 2016 by Clive One
I am reading ADC channels after every  1.56 us. I am not able to read on exactly 1.56 even after setting the interrupt for exact 1.56 us. For debugging I have put the toggling pin no 13 after adc read and checked in the CRO . It is showing  nearly 7 us as ADC reading is consuming 1.8 us as I checked the pin 13 toggling after keeping in the tight while loop. ADC read is happening exactly after 6.25 us if  I am setting the interrupt for 6.25 us (checked in the same way) . Is there any way to reduce the ADC read conversion time and read the channels exactly after 1.56 us. I have paste my code below . Any help will be really appreciated.I am new to STM32f4.


// STM32 ADC IQ Sample @ 200 KHz (PC.0, PC.1) STM32F4 Discovery

// Assumptions per system_stm32f4xx.c CPU @ 128 MHz, APB2 @ 64  MHz max is 84 (/2), APB1 @ 32 MHz max is 42 (/4)

#include "stm32f4_discovery.h"
 #include "stm32f4xx_tim.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx.h"
#include <misc.h>
#include "stm32f4xx_adc.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_dac.h"
#include "stm32f4xx_tim.h"

int ConvertedValue;
volatile int flag;

int main(void)
{
    LED_Config();
    adc_configure();
    DAC_configure();
     INTTIM_Config();
    EnableTimerInterrupt();
    TIM_Cmd(TIM2, ENABLE);
 while(1)
  {
      if (flag == 1)
      {


          flag = 0;
          //STM_EVAL_LEDOn(LED3);
          ConvertedValue = Get_ADC_Value(ADC_Channel_12);
         // GPIO_ToggleBits(GPIOD, GPIO_Pin_13);
          DAC_SetChannel1Data(DAC_Align_12b_R, ConvertedValue);
         // STM_EVAL_LEDOff(LED3);
          GPIO_ToggleBits(GPIOD, GPIO_Pin_13);
      }
 }
}
  DAC_configure()
        {
            RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
            GPIO_InitTypeDef  GPIO_InitStructure;

             GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
             GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
            GPIO_Init(GPIOA, &GPIO_InitStructure);

            TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
            RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);

            /* Time base configuration */
                  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
                  TIM_TimeBaseStructure.TIM_Period = 0xFF;
                  TIM_TimeBaseStructure.TIM_Prescaler = 0;
                  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
                  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
                  TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);

                  /* TIM6 TRGO selection */
                  TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update);

                  /* TIM6 enable counter */
                  TIM_Cmd(TIM6, ENABLE);

            /* DAC Config */
            DAC_InitTypeDef DAC_InitStructure;
                  RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);

                  DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO;
                  DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
                 // DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bits11_0;
                  DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
                  DAC_Init(DAC_Channel_1, &DAC_InitStructure);
            DAC_Cmd(DAC_Channel_1, ENABLE);
        //     unsigned int i;
            ////while(1){
            //DAC_SetChannel1Data(DAC_Align_12b_R, 3856);

        //    for(i= 65535; i > 0 ; i--);
           // DAC_SetChannel1Data(DAC_Align_12b_R, 4096/2);
            //for(i= 65535; i > 0 ; i--);



            }
void INTTIM_Config(void)
{
  /* TIM2 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  /* Time base configuration */
  TIM_InitStruct.TIM_Prescaler = 2 - 1;                // This will configure the clock to 2 kHz
  TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up;     // Count-up timer mode
  TIM_InitStruct.TIM_Period = 50 - 1;                    // 2 kHz down to 1 Hz = 1 second
  TIM_InitStruct.TIM_ClockDivision = TIM_CKD_DIV1;        // Divide clock by 1
  TIM_InitStruct.TIM_RepetitionCounter = 0;                // Set to 0, not used
  TIM_TimeBaseInit(TIM2, &TIM_InitStruct);
  TIM_Cmd(TIM2, ENABLE);
  /* TIM2 enable counter */

  TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
}
void EnableTimerInterrupt()
{
    NVIC_InitTypeDef nvicStructure;
    nvicStructure.NVIC_IRQChannel = TIM2_IRQn;
    nvicStructure.NVIC_IRQChannelPreemptionPriority = 0;
    nvicStructure.NVIC_IRQChannelSubPriority = 0;
    nvicStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&nvicStructure);
}



void LED_Config(void)
{
  /* GPIOD Periph clock enable */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

  /* Configure PD12, PD13, PD14 and PD15 in output pushpull mode */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOD, &GPIO_InitStructure);

}
void adc_configure(){
 ADC_InitTypeDef ADC_init_structure; //Structure for adc confguration
 GPIO_InitTypeDef GPIO_initStructre; //Structure for analog input pin
 ADC_CommonInitTypeDef ADC_CommonInitStructure;
 //Clock configuration
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//The ADC1 is connected the APB2 peripheral bus thus we will use its clock source
 RCC_AHB1PeriphClockCmd(RCC_AHB1ENR_GPIOCEN,ENABLE);//Clock for the ADC port!! Do not forget about this one ;)
 //Analog pin configuration
//GPIO_initStructre.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;//The channel 10 is connected to PC0
 GPIO_initStructre.GPIO_Pin = GPIO_Pin_2;
 GPIO_initStructre.GPIO_Mode = GPIO_Mode_AN; //The PC0 pin is configured in analog mode
 GPIO_initStructre.GPIO_PuPd = GPIO_PuPd_NOPULL; //We don't need any pull up or pull down
 GPIO_Init(GPIOC,&GPIO_initStructre);//Affecting the port with the initialization structure configuration
 //ADC structure configuration

 ADC_DeInit();
// ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
 //  ADC_CommonInit(&ADC_CommonInitStructure);
 ADC_init_structure.ADC_DataAlign = ADC_DataAlign_Right;//data converted will be shifted to right
 ADC_init_structure.ADC_Resolution = ADC_Resolution_12b;//Input voltage is converted into a 12bit number giving a maximum value of 4096
 ADC_init_structure.ADC_ContinuousConvMode = DISABLE; //the conversion is continuous, the input data is converted more than once
 ADC_init_structure.ADC_ExternalTrigConv =  ADC_ExternalTrigConvEdge_None;// conversion is synchronous with TIM1 and CC1 (actually I'm not sure about this one :/)
 ADC_init_structure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//no trigger for conversion
 ADC_init_structure.ADC_NbrOfConversion = 1;//I think this one is clear :p
 ADC_init_structure.ADC_ScanConvMode = DISABLE;//The scan is configured in one channel
 ADC_Init(ADC1,&ADC_init_structure);//Initialize ADC with the previous configuration
 //Enable ADC conversion
 ADC_Cmd(ADC1,ENABLE);
 //Select the channel to be read from
 //ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_3Cycles);
 //ADC_RegularChannelConfig(ADC1,ADC_Channel_11,1,ADC_SampleTime_3Cycles);
 ADC_RegularChannelConfig(ADC1,ADC_Channel_12,1,ADC_SampleTime_3Cycles);
// NVIC_SetPriority(ADC_IRQn, 10);
//  NVIC_EnableIRQ(ADC_IRQn);
 //ADC_RegularChannelConfig(ADC1,ADC_Channel_13,1,ADC_SampleTime_3Cycles);
 }

int Get_ADC_Value(int Channel)
{
    int ADC_Val = 0;
    switch(Channel)
    {

        case 11:
            ADC_SoftwareStartConv(ADC1);
            while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));//Processing the conversion
            ADC_Val = ADC_GetConversionValue(ADC1);
            break;
        case 12:
            ADC_SoftwareStartConv(ADC1);
            while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
            ADC_Val = ADC_GetConversionValue(ADC1);
            break;
        case 13:
            ADC_SoftwareStartConv(ADC1);
              while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
                        ADC_Val = ADC_GetConversionValue(ADC1);
                        break;
        case 14:
                   ADC_SoftwareStartConv(ADC1);
                   while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
                   ADC_Val = ADC_GetConversionValue(ADC1);
                   break;
       // default:
        //    ADC_Val = 0;
         //   break;
    }
   // return ADC_GetConversionValue(ADC1);
    return ADC_Val;
}
void TIM2_IRQHandler()

{


    // unsigned long long int digit = 0;
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
    //{
    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
        //  USART1_puts(USART1, "\nchannel");
        //  digit = itoa(channel_i);
    flag = 1;
}

















Outcomes