Skip to main content
Visitor II
May 16, 2014
Question

Problem in ADC1 (Scan Mode, Buffered reading) Triggered by TIM1

  • May 16, 2014
  • 2 replies
  • 867 views
Posted on May 16, 2014 at 16:19

Hi everyone

I am using STM8S003F3 in my board. for reading 5 analog inputs in regular interval I have used single conversion - scan mode - buffered ADC triggered by TIM1 by the following code

//ADC1_DeInit ();

ADC1_Init ( ADC1_CONVERSIONMODE_SINGLE, ADC1_CHANNEL_6,   ADC1_PRESSEL_FCPU_D18, 

            ADC1_EXTTRIG_TIM , ENABLE,  ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_ALL, DISABLE );

ADC1->CR2 |= ADC1_CR2_SCAN;//ADC1_ScanModeCmd ( ENABLE );

ADC1->CSR |= (uint8_t)ADC1_IT_EOCIE;//ADC1_ITConfig ( ADC1_IT_EOCIE, ENABLE );

ADC1->CR3 |= ADC1_CR3_DBUF;//ADC1_DataBufferCmd ( ENABLE );

ADC1->CR1 |= ADC1_CR1_ADON;//ADC1_Cmd ( ENABLE );

and I configured TIM1 to trigger ADC1 in regular times with the following code

//TIM1_DeInit ();

TIM1_TimeBaseInit (TIM1_PRESCALER, TIM1_COUNTERMODE_UP, TIM1_PERIOD, 0);

// TIM1_ITConfig (TIM1_IT_UPDATE, ENABLE);

TIM1->CR1 |= TIM1_CR1_ARPE;//TIM1_ARRPreloadConfig (ENABLE);

TIM1_SelectOutputTrigger (TIM1_TRGOSOURCE_UPDATE);

TIM1->CR1 |= TIM1_CR1_CEN;//TIM1_Cmd (ENABLE);

when I run my program, it works normal for at least 30 seconds, after that the ADC buffer values get zero!!! it seems that all interrupts are working correct. A new clue that I found is that, ADC overrun flag is always SET from the start and as I checked, ADC triggering by TIM1 is slow enough to avoid over running! ( I even make triggering 10 times slower )

Even if I clear the over run flag, it gets SET again.

I think buffer over running stops ADC from conversion input channels but I don't know how I can deal with this

I appreciate if you give me your comments

#stm8s-adc1-scan-mode #adc-stm8 #stm8-adc-problem
    This topic has been closed for replies.

    2 replies

    abbasAuthor
    Visitor II
    May 23, 2014
    Posted on May 23, 2014 at 13:22

    I caught the problem!!!

    It seems to be a hardware exception, because ADC EOC ( end of conversion )

    interrupt works but ADC content is zero.

    I replace TIM1 external trigger ( which was hardware act ) with TIM1

    interrupt, in which I do ADC1 start conversion ( a software act ), and the

    problem disappeared!

    I think the following failure had been taking place:

    in my code, the whole operations are performed in interrupt routines, but the

    TIM1 external trigger was triggering ADC1 by hardware without seeing if the

    other interrupt routines had been done and released CPU resource before

    ADC1 EOC ( end of conversion ) handler can read the results. so in particular

    intervals ADC1 was being triggered by TIM1 before ADC data buffers had

    been read. I thought this would just raise an overrun flag but in practice, the

    repetition of this phenomena took ADC1 hardware to a permanent state in

    which it was returning zero for nonzero analog inputs.

    I would be thankful if anyone, specifically a ST company expert, say his/her

    opinion about this 
    Visitor II
    December 19, 2015
    Posted on December 19, 2015 at 12:24

    Hi abbas,

    I am working on sensing of my AC waveform (of 50 Hz) with ADC1 of STM8S003k3 MCU.I want to trigger my ADC with TRGO event from TIM1.

    The TRGO signal is my OC1REF signal.When i observed my Timer Ouput(TRGO) on PC.1 pin,i am getting correct sampling freq set by me(10 Khz).But i am not able to get correct sampled waveform.So i am in doubt that my TRGO event is triggering my ADC correctly or not.

    Following is my TIM1 setup:

      TIM1->CR1 &= ~0x10;           // upcount counter

      TIM1->ARRH= (u8)(AUTORELOAD >> 8); // init sampling period and pulse wide

      TIM1->ARRL= (u8)(AL); // auto reload register

      TIM1->CCR1H= (u8)((AUTORELOAD) >> 8);// compare register

      TIM1->CCR1L= (u8)(AL-AD_STAB);

      TIM1->CR1|= TIM1_CR1_ARPE; // auto reload register is buferred

      TIM1->CR2 |= 0x40; // CC1REF is used as TRGO

      TIM1->CCMR1= (6<<4) & TIM1_CCMR_OCM; // CC1REF in PWM 1 mode

      TIM1->IER  |= TIM1_IER_CC1IE; // CC1 interrupt enable

      TIM1->CCER1|= TIM1_CCER1_CC1P; // OC1 negative polarity

      TIM1->CCER1|= TIM1_CCER1_CC1E; // OC1 output enable

      TIM1->BKR|= TIM1_BKR_MOE;

      

      TIM1->SMCR|=  TIM1_SMCR_MSM; // synchronization of TRGO with ADC

      TIM1->CR1|= TIM1_CR1_CEN; // timer 1 enable

    TIM1 Interrupt:-

    INTERRUPT_HANDLER(TIM1_CAP_COM_IRQHandler, 12)

    {

          

           GPIOD->ODR &= ~PIN_0;

           TIM1->SR1&=~TIM1_SR1_CC1IF;

            ADC1->CR1 |= ADC1_CR1_ADON; 

    }

    I am reading my ADC conversion on EOC IE interrupt.

    Please help me regarding this.It is very important for me.