cancel
Showing results for 
Search instead for 
Did you mean: 

Hi, I am using STM32F407ZGT6 with mikroe 1369 ( https://www.mikroe.com/mikromedia-4-stm32f4 ) I need to capture falling edge of external signal and read the time its took from starting the function till falling edge detected.

JPate.19
Associate II

Hi, I am using STM32F407ZGT6 with mikroe 1369 ( https://www.mikroe.com/mikromedia-4-stm32f4 )

I need to capture falling edge of external signal and read the time its took from starting the function till falling edge detected. 

I read maual but some how i am not getting right and its not working properly, i am getting 28 and 30 mS time regardless of signal present or not. Can some one guide me please and tell me what is wrong with this my code.

void InitTimer3(){

 // GPIO Input: TIME alternate function for CH1,PA6

 GPIO_Alternate_Function_Enable(&_GPIO_MODULE_TIM3_CH1_PA6);

 GPIO_Set_Pin_Mode(&GPIOA_BASE,_GPIO_PIN_6,_GPIO_CFG_MODE_INPUT);

//disableInterrupts(); // disable global interrupts

 RCC_APB1ENR.TIM3EN = 1;

 RCC_AHB1ENR |= 0x1 ; //clock enable to GPIOA

 TIM3_CR1.CEN = 0;

 TIM3_PSC = 1;

 TIM3_ARR = 37499;

 TIM3_CCER.CC1E=1;

 TIM3_CCER.CC1P = 0;

 TIM3_CCER.CC1NP = 1;   // Falling edage

  TIM3_CCMR1_Input =1; // INPUT CAPTURE CH1

 TIM3_CCR1 =1;    //page 641

 NVIC_IntEnable(IVT_INT_TIM3);

  TIM3_DIER.TIE = 1; // enable interupt

 TIM3_DIER.CC1IE = 1;

 TIM3_DIER.UIE = 1;

 TIM3_CR1.CEN = 1;

 TIM3_EGR.UG = 1;   // Reinit the counter

 TIM3_EGR = 1;

 enableInterrupts();

}

 int EdgeCounter = 0;

void Timer3_interrupt() iv IVT_INT_TIM3 {

   TIM3_SR.UIF = 0; // reset counter

    LED_B=1;

    LED_G=0;

    LED_R=0;

 // if falling edage detected

 if(TIM3_SR.CC1IF== 1)//falling edage detect

  {

    TIM3_CR1.CEN = 0;      // timer off

    Rly_D=0;

      disableInterrupts(); // disable global interrupts

   //TIM3_SRbits.CC1IF == 0;   // clear flag

    // Displya timer code here

     LED_B=0;

      LED_G=0;

      LED_R=1;

      }

 }

  void EL_TimeB() {

    InitTimer3();

    delay_ms(1000);

     EnableInterrupts();

    NVIC_IntEnable(IVT_INT_TIM3);

    delay_ms(1000);

    Rly_D=1;

  while(( TIM3_SRbits.CC1IF == 0 )  || (EdgeCounter< 5000 )) {

   NVIC_IntEnable(IVT_INT_TIM3);

   EdgeCounter++;

      }

      LED_B=1;

      LED_G=1;

      LED_R=0;

      j = TIM3_CNT;    // copy counter

    TIM3_CNT = 0;        // reset counter

    TIM3_EGR.UG = 1;       // update TIM3 registers

   TIM3_SRbits.CC1IF = 0 ;    // Clear flag

   strcpy(ELTIME_main.Caption,"  " );

  DrawLabel(&ELTIME_main);

  LongWordToStr(j, text3);

  strcpy(ELTIME_main.Caption,text3 );

  ELTIME_main.Font_Color = Cl_green;

  DrawLabel(&ELTIME_main);

  }

7 REPLIES 7

Clear the entire TIM3_SR before enabling interrupts.

---

Just a note, I don't use the mikroe compiler but check how does this

> TIM3_SR.UIF = 0; // reset counter

or this

>   TIM3_SRbits.CC1IF = 0 ;    // Clear flag

work. I suspect the former is a read-modify-write (RMW), and the latter is a bit-banding access, which from the point of view of the register is a RMW, too. Don't do RMW with TIMx_SR, always use a direct write to the whole register; otherwise you may clear flags which have just been set by hardware in the middle of the RMW process.

JW

Hi WJ,

Thanks for input,

I reset the counter but still i am getting fix 32mS as out put and this regardless of signal time.

I increase delay up to 1000mS but still showing 32mS.

Any thoughts?

What do you mean by "Don't do RMW with TIMx_SR, always use a direct write to the whole register"

> I reset the counter

I said, clear TIM3_SR.

> What do you mean by "Don't do RMW with TIMx_SR, always use a direct write to the whole register"

https://community.st.com/s/feed/0D50X00009bLSAZSA4

JW

JPate.19
Associate II

Hi WJ,

It is good info regarding TIMx_SR.

I have update and clear flag but still some how its not capturing properly and clearing hardware flag.

When i restart the hardware and run the program i get 0 mS which is perfect without any signal but in

second and onward attempt its shows 25mS.

I don't understand where part of this program is not working.

void InitTimer3(){

 // GPIO Input: TIME alternate function for CH1,PA6

 GPIO_Alternate_Function_Enable(&_GPIO_MODULE_TIM3_CH1_PA6);

 GPIO_Set_Pin_Mode(&GPIOA_BASE,_GPIO_PIN_6,_GPIO_CFG_MODE_INPUT);

//disableInterrupts(); // disable global interrupts

 RCC_APB1ENR.TIM3EN = 1;

 RCC_AHB1ENR |= 0x1 ; //clock enable to GPIOA

 TIM3_CR1.CEN = 0;

 TIM3_PSC = 1;

 TIM3_ARR = 37499;

 TIM3_CCER.CC1E=1;

 TIM3_CCER.CC1P = 0;

 TIM3_CCER.CC1NP = 1;   // Falling edage

   TIM3_CCMR1_Input =1; // INPUT CAPTURE CH1

   TIM3_CCR1 =1;    //page 641

   TIM3_SR = 0; // reset counter

   TIM3_SR.UIF = 0; // reset counter

   TIM3_SRbits.CC1IF = 0 ;  // Clear flag

   j=0;

 NVIC_IntEnable(IVT_INT_TIM3);

   TIM3_DIER.TIE = 1; // enable interupt

   TIM3_DIER.CC1IE = 1;

   TIM3_DIER.UIE = 1;

   TIM3_CR1.CEN = 1;

   TIM3_EGR.UG = 1;   // Reinit the counter

   TIM3_EGR = 1;

 enableInterrupts();

}

 int EdgeCounter = 0;

void Timer3_interrupt() iv IVT_INT_TIM3 {

  // TIM3_SR.UIF = 0; // reset counter

    LED_B=1;

    LED_G=0;

    LED_R=0;

 // if falling edage detected

 if(TIM3_SR.CC1IF== 1)//falling edage detect

  {

    TIM3_CR1.CEN = 0;      // timer off

    Rly_D=0;

      disableInterrupts(); // disable global interrupts

      TIM3_SR.UIF = 0; // reset counter

     LED_B=0;

      LED_G=0;

      LED_R=1;

      }

 }

 // PB1- TIM3CH4,pin 19 PA6 - TIM3CH1, pin 13 PB14 - TIM12Ch1  , pin 14 PB15 - TIM12Ch2

 //

 //4-PB0 TIM3CH3  //Phase A

 // 5 -PB1 TIM3CH4 // Phase B

 // 19 - PA6 - TIM3CH1  // Phase C

 //

 // PC0,PC2,PC3 // No timer available

  void EL_TimeB() {

    InitTimer3();

    delay_ms(1000);

     EnableInterrupts();

    NVIC_IntEnable(IVT_INT_TIM3);

    delay_ms(1000);

    Rly_D=1;

  while(( TIM3_SRbits.CC1IF == 0 )  || (EdgeCounter< 5000 )) {

   NVIC_IntEnable(IVT_INT_TIM3);

   EdgeCounter++;

      }

      LED_B=1;

      LED_G=1;

      LED_R=0;

      j = TIM3_CNT;    // copy counter

    TIM3_CNT = 0;        // reset counter

   // TIM3_EGR.UG = 1;       // update TIM3 registers

   TIM3_SRbits.CC1IF = 0 ;    // Clear flag

   strcpy(ELTIME_main.Caption,"  " );

  DrawLabel(&ELTIME_main);

  LongWordToStr(j, text3);

  strcpy(ELTIME_main.Caption,text3 );

  ELTIME_main.Font_Color = Cl_green;

  DrawLabel(&ELTIME_main);

  }

HI JW,

Is there any think you find in below code, which can help me to solve this puzzle.

I cant think of anything why this falling edge interrupt doent work.

JP

Try to read out the registers content and check whether they are set as you intended.

Also check (in disassembly) whether the interrupt service routine (ISR) address is in the vector table.

JW