cancel
Showing results for 
Search instead for 
Did you mean: 

TIM4 CCP1 Interrupt arrive too early (0.23ms instead of 500ms)

bluewaters213
Associate III
Posted on May 24, 2013 at 11:53

Hello,

I have configure Timer 4 in Compare mode with interrupt enable on STM32f103RB.I set the compare register to 500ms (72MHz System Clock).I have notice that TIM4 CCP1 Interrupt fire in 0.23ms (as measure with logic analyzer) instead of 500ms in the compare register.

I have work through my code a dozen times but could not find what is wrong with my code. 

=================================

&sharpinclude ''stm32f10x.h''

/*PROTOTYPE DECLERATION*/

void RCC_Init(void);

void GPIO_Init(void);

void Timer1PWM_Init(void);

void ADC_Init(void);

void Commutate (void);

void Align_Rotor(void);

const uint32_t COMM_INDEX[6] = {0x00001054,0x00001504,0x00001540,0x00001045,0x00001405,0x00001450}; /*Commutation 6 Step Pattern*/

const uint32_t  PWM_CCMR1[6] = {0x00006050,0x00006050,0x00005060,0x00005060,0x00006060,0x00006060}; /*Commutation 6 Step Pattern*/

const uint32_t  PWM_CCMR2[6] = {0x00006060,0x00006060,0x00006060,0x00006060,0x00006050,0x00006050}; /*Commutation 6 Step Pattern*/

volatile uint16_t commutationStep;

volatile uint16_t bemfsample[6];

volatile uint32_t zcthreshold;

volatile uint16_t Current;

int main(void)

{

RCC_Init();

  GPIO_Init();

// Timer1PWM_Init();

//   ADC_Init();

  Align_Rotor();

 while (1)

  {

  /*Do Nothing*/

  }

 }

==================================

&sharpinclude ''stm32f10x.h''

extern const uint32_t COMM_INDEX[6];

extern const uint32_t  PWM_CCMR1[6];

extern const uint32_t  PWM_CCMR2[6];

extern volatile uint16_t commutationStep;

volatile uint16_t DutyCycle;

void Align_Rotor(void)

  {

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

DutyCycle = 600;

commutationStep = 0;

TIM1->CCMR1 = PWM_CCMR1[commutationStep];       /*Change Commutation Pattern*/

TIM1->CCMR2 = PWM_CCMR2[commutationStep];       /*Change Commutation Pattern*/

TIM1->CCER = COMM_INDEX[commutationStep];       /*Change Commutation Pattern*/

TIM1->CCR1 = DutyCycle;                         /*Change CH1 PWM Duty Cycle by 6*/

TIM1->CCR2 = DutyCycle;                         /*Change CH2 PWM Duty Cycle by 6*/

TIM1->CCR3 = DutyCycle;                         /*Change CH3 PWM Duty Cycle by 6*/

TIM4->ARR = 16363;                              /*TIM4 Auto Reload Value Set to 500ms*/ 

TIM4->CCR1 = 16363;                             /*TIM4 CCP1 Value Set to 500ms*/ 

TIM4->PSC = 2199;                               /*TIM4 Set Prescaler to 2223*/

TIM4->DIER = TIM_DIER_CC1IE;                    /*Enable TIM4 CCP1 Interrupt*/

TIM4->CR1 = TIM_CR1_CEN | TIM_CR1_ARPE;         /*Start TIM4 (ALIGNMENT)*/

NVIC_EnableIRQ(TIM4_IRQn);                      /*Enable TIM4 CCP Interrupt in NVIC*/

  }

===================================

void TIM4_IRQHandler(void)

{

  if (TIM4->SR & TIM_SR_CC1IF) 

 {                                             /*ALIGNEMENT TIME EXPIRE, PROCEED TO RAMPUP */

      TIM4->SR &= ~TIM_SR_UIF;                      /*clear CC1IF flag */

      TIM4->DIER = 0x0000;                          /*Disable TIM4 CCP1 Interrupt*/

  if (commutationStep > 5) commutationStep = 0;   /*Automatic Rollover to 0 after 5 Step*/

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

}

}

=====================================

&sharpinclude ''stm32f10x.h''

&sharpdefine ENABLE_PWMCH1     0x0000000A

&sharpdefine ENABLE_PWMCH2     0x000000A0

&sharpdefine ENABLE_PWMCH3     0x00000A00

&sharpdefine ENABLE_PWMCH4     0x0000A000

&sharpdefine ENABLE_PWMCH1N    0x00A00000

&sharpdefine ENABLE_PWMCH2N    0x0A000000

&sharpdefine ENABLE_PWMCH3N    0xA0000000

void GPIO_Init(void)

{

/*Enable Timer1 PWM Output Pins (CH1->PA8, CH2->PA9, CH3->PA10, CH4->PA11*/

GPIOA->CRH = ENABLE_PWMCH1 | ENABLE_PWMCH2 | 

            ENABLE_PWMCH3 | ENABLE_PWMCH4;

/*Enable Timer1 PWM Output Pins (CH1N->PB13, CH2N->PB14, CH3N->PB15)*/

GPIOB->CRH = ENABLE_PWMCH1N | ENABLE_PWMCH2N | ENABLE_PWMCH3N;

/*LED OutPut GPI0B*/

GPIOB->CRH |= GPIO_CRH_MODE8_1 | GPIO_CRH_MODE9_1;        /*PB8 - PB9-> 2MHz Output Mode, Push-Pull*/

/*ADC Analog Pin Configuration*/

GPIOC->CRL = 0x00000000;                                  /*PC0 - PC7 Configure as Analog Input*/

             

}

==============================

&sharpinclude ''stm32f10x.h''

void RCC_Init(void)

{

  RCC->APB2ENR |= RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPAEN |         /*Enable Alternate Function & GPIOA*/

               RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN |         /*Enable GPIOB & GPIOC*/

               RCC_APB2ENR_IOPDEN | RCC_APB2ENR_TIM1EN |         /*Enable GPIOD & TIMER1*/

                  RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN;          /*Enable ADC1 & ADC2*/

  RCC->APB1ENR |= RCC_APB1ENR_TIM2EN | RCC_APB1ENR_TIM3EN |         /*Enable TIMER2 & TIMER3*/  

               RCC_APB1ENR_TIM4EN | RCC_APB1ENR_I2C1EN |         /*Enable TIMER4, TIMER3 & I2C1 */

               RCC_APB1ENR_USART2EN;                             /*Enable USART2*/

  RCC->AHBENR = RCC_AHBENR_DMA1EN ;                                 /*Enable DMA1 clock*/

}

================================

Regards

Slim

#stm32-timer #stm32f103rb
5 REPLIES 5
Posted on May 24, 2013 at 12:21

I don't say this IS the cause of your problem, but

TIM4->SR &= ~TIM_SR_UIF;                      /*clear CC1IF flag */

is at suspicious (and it shouldn't be &= just =, too).

JW

Posted on May 24, 2013 at 12:50

[DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Problem%20in%20using%20TIM2%20Flag%20Polling&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=105]https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex_mx_stm32%2FProblem%20in%20using%20TIM2%20Flag%20Polling&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=105

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 May 24, 2013 at 14:36

Hello,

I have made the changes still no luck. The amazing thing is the interrupt fire at the right time (500ms) after the first misfiring(0.23ms).I just cant understand what is wrong.this problem have been hunting me for a long time with no solution at sight with about 2 similar post.I might try the newer stm32f but i will take 2 weeks to lay my hands on any.

void TIM4_IRQHandler(void)

{

  if (TIM4->SR & TIM_SR_CC1IF)

          {                                             /*ALIGNEMENT TIME EXPIRE, PROCEED TO RAMPUP */

      TIM4->SR = ~TIM_SR_CC1IF;                      /*clear CC1IF flag */    

//       TIM4->DIER = 0x0000;                          /*Disable TIM4 CCP1 Interrupt*/    

            ++commutationStep;

            if (commutationStep > 5) commutationStep = 0;   /*Automatic Rollover to 0 after 5 Step*/

                

         TIM1->CCMR1 = PWM_CCMR1[commutationStep];       /*Apply Commutation Pattern to the Correct MOSFET Switch*/

        TIM1->CCMR2 = PWM_CCMR2[commutationStep];       /*Apply Commutation Pattern to the Correct MOSFET Switch*/

            TIM1->CCER = COMM_INDEX[commutationStep];       /*Apply Commutation Pattern to the Correct MOSFET Switch*/

                

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

            }    

}

zzdz2
Associate II
Posted on May 24, 2013 at 16:04

You can try to reload prescaler after setting PSC register.

It can be done with UG bit inTIMx_EGR. I do it like this:

TIM2->PSC = 10000 - 1;
TIM2->ARR = (g_clkmhz * 100) - 1;
TIM2->CNT = 0;
// reload prescaler:
TIM2->EGR = TIM_EGR_UG;

bluewaters213
Associate III
Posted on May 24, 2013 at 17:59

Hello,

Thanks alot..your suggestion solved the problem.

Slim