Calculating Timer Interrupt Period

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
BeHi_4668916
Level 1
Level 1
First like received

I have some questions on setting up timer interrupts.  In reading the documentation and following some examples I am understanding that:

timer interrupt period = (1/clock freq) * period * scale

I am trying to set a timer to interrupt every millisecond but mine is interrupting at a much faster rate.  If i go off the reference manual and the examples I have looked at I would expect this to interrupt ever .001 seconds.  What am in not understanding correctly to set this up properly? 

my calculation and settings:
.001 = (12,000 * 2) / 24,000,000

I have it set up accordingly:
pastedImage_0.png

Clock:

pastedImage_1.png

Timer:

pastedImage_2.png

0 Likes
1 Solution
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

How about adding     Timer_SysTick_ClearInterrupt(Timer_SysTick_INTR_MASK_TC) ; before sysTickIncrement() ;

so that

From ISR:

CY_ISR(isr_SysTick_Interrupt)

{

    #ifdef isr_SysTick_INTERRUPT_INTERRUPT_CALLBACK

        isr_SysTick_Interrupt_InterruptCallback();

    #endif /* isr_SysTick_INTERRUPT_INTERRUPT_CALLBACK */

    /*  Place your Interrupt code here. */

    /* `#START isr_SysTick_Interrupt` */

    Timer_SysTick_ClearInterrupt(Timer_SysTick_INTR_MASK_TC) ;

    sysTickIncrement();

    /* `#END` */

}

moto

View solution in original post

0 Likes
6 Replies
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

I tried with CY8CKIT044

schematic

000-schematic.JPG

pwm setting

003-pwm.JPG

pins

001-pins.JPG

main.c

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

#include "project.h"

volatile int tick_flag = 0 ;

CY_ISR(tick_isr)

{

    Timer_SysTick_ClearInterrupt(Timer_SysTick_INTR_MASK_TC) ;

    tick_flag = 1 ;

}

int main(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */

   

    isr_SysTick_ClearPending() ;

    isr_SysTick_StartEx(tick_isr) ;

    Timer_SysTick_Start() ;

    for(;;)

    {

        if (tick_flag) {

            tick_flag = 0 ;

            if (Out1ms_Read()) {

                Out1ms_Write(0) ;

            } else {

                Out1ms_Write(1) ;

            }

        }

    }

}

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

Oscillo

IMG_4190.JPG

In my case, the interval was about 1ms.

moto

0 Likes

Thank you for taking time to address my question.  Your results are what I was expecting to get.  One difference is that I'm using the default interrupt handler from the generated file, but I wouldn't expect that to affect it.  From the ISR I call a function that just increments a 32 bit static variable.  I don't have an oscilloscope but after about 5 seconds I break on the interrupt and check the count of my variable and it is very very large.  I would expect it to only be about 5000.  Any ideas why I my interrupt is happening so much faster than .001 seconds?

Thanks.

From Main.c:

int main()

{

    /* Place your initialization/startup code here (e.g. MyInst_Start()) */

   

    /* Starts the timer */

    /* Enable interrupt component and set up handler */

    Timer_SysTick_Start();

    isr_SysTick_Start();

   

    /* Enable global interrupts. */

    CyGlobalIntEnable;

    for(;;)

    {

        /* Place your application code here. */     

        LED_Red_Write(~LED_Red_Read());

        CyDelay(2000);

        LED_Blue_Write(~LED_Blue_Read());

        CyDelay(2000);

        LED_Green_Write(~LED_Green_Read());

        CyDelay(2000);

    }

   

    return (1);

}

From ISR:

CY_ISR(isr_SysTick_Interrupt)

{

    #ifdef isr_SysTick_INTERRUPT_INTERRUPT_CALLBACK

        isr_SysTick_Interrupt_InterruptCallback();

    #endif /* isr_SysTick_INTERRUPT_INTERRUPT_CALLBACK */

    /*  Place your Interrupt code here. */

    /* `#START isr_SysTick_Interrupt` */

    sysTickIncrement();

    /* `#END` */

}

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

How about adding     Timer_SysTick_ClearInterrupt(Timer_SysTick_INTR_MASK_TC) ; before sysTickIncrement() ;

so that

From ISR:

CY_ISR(isr_SysTick_Interrupt)

{

    #ifdef isr_SysTick_INTERRUPT_INTERRUPT_CALLBACK

        isr_SysTick_Interrupt_InterruptCallback();

    #endif /* isr_SysTick_INTERRUPT_INTERRUPT_CALLBACK */

    /*  Place your Interrupt code here. */

    /* `#START isr_SysTick_Interrupt` */

    Timer_SysTick_ClearInterrupt(Timer_SysTick_INTR_MASK_TC) ;

    sysTickIncrement();

    /* `#END` */

}

moto

0 Likes

That was it! Thank you for your response.

Motoo,

Please let me add a comment regarding the Timer/Counter configuration.

Because the Period parameter is used to compare with the counter which initial value is ZERO, the period parameter must be set to N-1 when you want to get a N cycle period.  Please refer following description from the TCPWM component datasheet.

GS004706.png

Regards,

Noriaki

MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Noriaki-san,

Thank you very much for your information!

And your reply reminded me of the recent restriction of PSoC Creator.

To have 100% duty we need to set compare value >= period,

but the GUI configure tool does not allow us to enter such value.

So we need to set the compare value from the firmware API PWM_WriteCompare().

I wonder if it's still the case, though.

Best Regards,

13-Apr-2020

Motoo Tanaka

0 Likes