cancel
Showing results for 
Search instead for 
Did you mean: 

Timer4 CCP2 Interrupt occur too early (about 70% of the time)

bluewaters213
Associate III
Posted on July 25, 2013 at 15:06

The original post was too long to process during our migration. Please click on the attachment to read the original post.
4 REPLIES 4
Posted on July 25, 2013 at 16:30

I know we've told you a couple of times this is NOT how to clear interrupts.

TIM4->SR &= ~TIM_SR_CC1IF;                   //Clear Timer3 CC1 Interrupt Flag

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
bluewaters213
Associate III
Posted on July 25, 2013 at 23:07

Hello,

Thanks for your response and I know I have been told on several occasion on the right way to clear timer interrupt flag. However, changing TIM3->SR  = ~TIM_SR_CC1IF to TIM3->SR &= ~TIM_SR_CC1IF was among the

https://www.google.com.ng/search?client=firefox-a&hs=Oz8&rls=org.mozilla:en-US:official&q=abracadabra&spell=1&sa=X&ei=hYrxUdSHOYSNOP6ugYAM&ved=0CCkQvwUoAA

I tried.

I have notice that the Timer4 Counter is not counting more than 34 before it is reset.I setup a little test to know if the Timer4 Counter is really counting.

The ADC interrupt occurs every 17KHz, so I setup a little test as shown below.

void ADC1_2_IRQHandler(void)

 {

    

    if (ADC1->SR & ADC_SR_EOC)                      

         {    

                ADC1->SR &= ~ADC_SR_EOC;                            //Clear ADC1 Interrupt Flag

                ADC2->SR &= ~ADC_SR_EOC;                            //Clear ADC2 Interrupt Flag

             GPIOB->ODR ^= (1 << 9);   //Toggle GPIOB Pin9

                Neutral_Voltage =  ADC1->DR;

                Phase_Voltage = ((ADC1->DR & 0xFFFF0000) >> 16);    //Read Motor OpenPhase Voltage on ADC2

                CommuationTime = TIM4->CNT;                         //Retrieve the Timer4 Counter value  

if (CommuationTime > 2150)

        {

          GPIOB->ODR ^= (1 << 8);  //Toggle GPIOB Pin8

     TIM4->CNT = 0;           

        }   

---------

GPIOB Pin9 toggle at 8.5KHz but GPIOB Pin8 never toggles indicating that Timer4 counter never exceed that value.What can cause the counter to keep resetting ?.

Regards

Posted on July 25, 2013 at 23:22

You know your testing for CC2 and clearing CC1 right? I'd try and follow the code but some of the comments don't match the timer being referenced. Can you advance CCR2 rather than clearing CNT? Setting CCR2 = CNT is apt to generate an interrupt, when the comparison fires.

    if (TIM4->SR & TIM_SR_CC2IF)

        {

       GPIOB->BRR = (1 << 9);                

         TIM4->SR &= ~TIM_SR_CC1IF;                   //Clear Timer3 CC1 Interrupt Flag

     FilterCommuationTime = TIM4->CNT;            

         TIM4->CNT = 0;                                 //Reset Timer4 Counter

 

The EOC can be cleared by reading the ADCx->DR. You should perhaps read the ADC1->DR just once as a 32-bit, then split into upper and lower 16-bit components.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
bluewaters213
Associate III
Posted on July 26, 2013 at 00:36

Hello,

Thanks once again for your response.I did some modification and used Timer3 instead of Timer4. and it work.I am sorry if my comment don't match.It was when I was trying some ''

https://www.google.com.ng/search?client=firefox-a&hs=Ht&rls=org.mozilla:en-US:official&q=abracadabra&spell=1&sa=X&ei=DKfxUeXUL8T2O7bzgHA&ved=0CCkQvwUoAA

'' that I tangle things up.

Code that start Timer3 counter

----------------

   // Switch to sensorless commutation

        Start_timer3();    

        TIM2_Configuration();

        TIM4->CR1 &= ~TIM_CR1_CEN;                    //Stop TIM4                

        TIM1->DIER |= TIM_DIER_CC4IE;                 // Enable Timer1 CC4 Interrupt which Software Trigger ADC   

void Start_timer3(void)

 {

      TIM3->PSC = (20 - 1);     

    TIM3->ARR = 0xFFFF;                          //TIM4 Auto Reload Value Set to 10us         

      TIM3->CNT = 0;                                    //Reload Prescaler and Other Registers

    TIM3->EGR = TIM_EGR_UG;                          //Reload Prescaler and Other Registers*/                

      TIM3->CR1 = TIM_CR1_CEN;                     //Start TIM3

    

 }

void ADC1_2_IRQHandler(void)

 {

    

    if (ADC1->SR & ADC_SR_EOC)                      

         {    

              temp = ADC1->DR;

                Neutral_Voltage =  temp;

                Phase_Voltage = ((temp & 0xFFFF0000) >> 16);    //Read Motor OpenPhase Voltage on ADC2

                CommuationTime = TIM3->CNT;                         //Retrieve the Zero Crossing Period    

            

 if (CommuationTime > 2150)

        {

          GPIOB->ODR ^= (1 << 8);

     TIM3->CNT = 0;            

        }    

     if (SampledPoint_ON == 1)                               //Zero Crossing Taken Place on PWM-ON DutyCycle?            

               {

             GPIOB->ODR ^= (1 << 9);

                    if (((ZC_Polarity == RISING_EDGE) && (Phase_Voltage > Neutral_Voltage)) ||

                         ((ZC_Polarity == FALLING_EDGE) && (Phase_Voltage < Neutral_Voltage)))

                            {

                             ZeroCrossing = Detected;                           //Zero Crossing Detected (Raised it flag)                    

                            }                

                }   

GPIOB Pin8 toggles as expected.I think I have to switch to timer3 though I will love to know the cause of timer4 counter resetting.

Regards