Skip to main content
gdiez
Associate III
August 31, 2010
Question

EOC ADC INTERRUPT

  • August 31, 2010
  • 15 replies
  • 3390 views
Posted on August 31, 2010 at 09:51

EOC ADC INTERRUPT

    This topic has been closed for replies.

    15 replies

    gdiez
    gdiezAuthor
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 14:04

    I´ve found my error. I´d not configure the nested Interrupt vector hehehe

    void NVIC_configuration(void)

    {

       NVIC_InitTypeDef NVIC_InitStructure;

    /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */  

    #ifndef  EMB_FLASH

      NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);      /* Set the Vector Table base location at 0x20000000 */

    #else   

      NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);    /* Set the Vector Table base location at 0x08000000 */

    #endif

    /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

     /* Configure and enable ADC interrupt */

      NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQChannel;

      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

      NVIC_Init(&NVIC_InitStructure); 

    }

    gdiez
    gdiezAuthor
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 14:04

    I suffocate in a water glass.

    My program enters in the ADC Interrupt but I can´t reset EOC flag. What is the matter with my code?

    void ADC_IRQHandler(void)

    {

       IT_tick=1;

       ADC1ConvertedValue = ADC1->DR;   /* Dato convertido */

       ADC1->SR &=~ 0x0000001F;                                       /* DOESN´T WRITES SR */

       /* ADC_ClearITPendingBit(ADC1, ADC_IT_EOC); */ /* DOESN´T WRITES SR EITHER*/

     

    }

    gdiez
    gdiezAuthor
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 14:04

    Does anyone know why I cant clear EOC flag?

    Have i clear another bit, SCAN, CONT or something?

    lipin
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 14:04

    Did you check if you really entered ISR? 

    You maybe using default isr implementation which is loop. In my vector table ADC handler is called:

    ADC1_2_IRQHandler or ADC1_IRQHandler depends on target device.

    not

    ADC_IRQHandler

    Regards

    Thomas

    gdiez
    gdiezAuthor
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 14:04

    Thks for replying. I´d read that but it doesn´t works. My code is the following one:

    void ADC_IRQHandler(void)

    {

    IT_tick=1;

    ADC1ConvertedValue = ADC1->DR; /*

    READ. IT DOESN´T CLEAR EOC Flag*/

    ADC1->SR &=~ 0x00000002; /*

    DOESN´T WRITES SR, SO DOESN´T CLEAR EOC Flag */

    ADC_ClearITPendingBit(ADC1, ADC_IT_EOC); /*

    LIBRARY FUNCTION. DOESN´T WRITES SR EITHER */

    }

    Must i do anything else to clear this bit?

    My programm stays in the ISR ever.

    0690X0000060MlNQAU.gif

    John F.
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 14:04

    Hi,

    You need to read the Manual RM0008.

    EOC: End of conversion: This bit is set by hardware at the end of a group channel conversion (regular or injected). It is cleared by software or by reading the ADC_DR.

    The EOC bit is of type ''read/clear (rc_w0)''

    Software can read as well as clear this bit by writing 0. Writing ‘1’ has no effect on

    the bit value.

    So you must write a zero directly to the register to clear the bit.

    John F.

    lipin
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 14:04

    Your code works on my uc and ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);  quits intterupt or by reading DR value as John F. mentioned.

    Dunno about your naming aliases but only changes I made are:

    NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;

    ADC1_2_IRQHandler

    and adding GPIO init.

    Remeber that you have

    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

    so it reenters interrupt as soon as next conversion is done. 

    Regards

    John F.
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 14:04

    ADC status register (ADC_SR) Bits 31:5 Reserved, must be kept cleared.

    ADC1->SR &=~ 0x00000002;

    isn't the same as

    ADC1->SR = 0x0000001D

    ... and you should clear the ADC pending bit using ADC_ClearITPendingBit() function in your ADC routine too of course!

    John F.

    gdiez
    gdiezAuthor
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 14:04

    My only requeriments are the follow:

    - ADC Conversion time =1uS

    - 20KHz conversion frecuency

    0690X00000602dZQAQ.jpg

    I have the configuration:

    XTAL=8MHz

    HCLK=56MHZ

    RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_7);

    APB2= 56MHz

    RCC_PCLK2Config(RCC_HCLK_Div1);

    ADCCLK=14MHz

    RCC_ADCCLKConfig(RCC_PCLK2_Div4);

    1 Regular channel 1.5 cycles

     ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 1, ADC_SampleTime_1Cycles5); 

    totalconversion time = 14 * 1/14Mhz = 1us

    My sysclk is 56MHz so i think that one clock cycle is 17,85nS more or less, so I think that have enough time to leave the ISR

    lipin
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 14:04

    Continuousmode off means there is one sampling & conversion. So it enters ISR andthen stops u need to trigger ADC once again by usingADC_SoftwareStartConvCmd(ADC1, ENABLE); .

    Continuousmode on it triggers interrupt on each (group) conversion done. Conversions are made in infinite row.Going more deeply according that you are using 72Mhz clock your ADC clock is:

    RCC_ADCCLKConfig(RCC_PCLK2_Div8);

    72Mhz / 8 =9Mhz

    totalconversion cycles = 1,5 (ADC_SampleTime_1Cycles5) + 12,5 cycles

    totalconversion time = 14 * 1/9Mhz = 1,(5) us

    So each1,5us you have new value and EOC flag is set. More or less its very short timeand you need to do all your math in this time otherwise next eoc flag is setand may not enter main loop at all. Let’s mention that interrupt latency is 12cycles.

    Do youreally need that frequent short time sampling? I bet you want short timesampling but not that frequent than use that continuous mode for sake of simplicityand additional timer to read values. Don’t use EOC flag.

    That is theway I see it i might be wrong just starting with stm32.