Interrupts seemingly speeding up?

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

cross mob
lock attach
Attachments are accessible only for community members.
DaSh_4647611
Level 1
Level 1
First like received First like given

Hi all, I'm currently working on a class project, part of which involves flashing an LED periodically. I'm using an interrupt to trigger when the LED flashes and another interrupt to turn it off. The first interrupt seems to always execute on time (turning on the LED) but the second interrupt that turns the LED off seems to speed up such that the amount of time the LED is actually on decays to zero and then rolls over to being "normal". I'm having some trouble debugging why this might be happening or even understanding conceptually why this might be happening, since I'm making sure to reset my timer count back to zero every time I execute the first interrupt.

The first interrupt, which calls setLED to schedule the second interrupt:

pastedImage_1.png

pastedImage_2.png

pastedImage_0.png

0 Likes
1 Solution
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,

It would be appreciated if you post only one project, so that we don't have to hunt eggs.

So I read and touched some of your project

LEDDuration:

I changed Run Mode to "One Shot"

010-LEDDuration_config.JPG

LEDPWM CMP Value 1 to 254 so that the LED will not be too bright in the first 5s Timer cycle

012-LEDPWM_Config.JPG

main.c

NOTE: To the changed compare value take effect, the counter must be written 0.

So usually we do

PWM_Stop() ;

PWM_WriteCompare(new_value) ;

PWM_WriteCounter(0) ;

PWM_Enable() ;

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

/* ========================================

*

* Copyright YOUR COMPANY, THE YEAR

* All Rights Reserved

* UNPUBLISHED, LICENSED SOFTWARE.

*

* CONFIDENTIAL AND PROPRIETARY INFORMATION

* WHICH IS THE PROPERTY OF your company.

*

* ========================================

*/

#include "project.h"

uint8 switchPeriod = 0;

/** Set the LED to turn on for *time* seconds at *pwmMag*. */

void setLED(int pwmMag, int time) {

    LEDDuration_Stop() ;

    LEDPWM_Stop() ;

   

    LEDDuration_WritePeriod(time * 100);

    LEDDuration_WriteCounter(0);

       

    LEDPWM_WriteCompare1(pwmMag);

    LEDPWM_WriteCounter(0) ;

   

    LEDPWM_Enable() ;

    LEDDuration_Enable() ;

}

CY_ISR(TimerInterrupt)

{

    if (switchPeriod) {

        // Set LED to be on for 1 second and PWM to be half.

        switchPeriod = 0;

        setLED(130, 1);

    } else {

        // Set LED to be on for 2 seconds and PWM to be full

        switchPeriod = 1;

        setLED(255, 2);

    }

    Timer_1_ReadStatusRegister();

}

CY_ISR(LEDOffInterrupt) {

    LEDPWM_Stop() ;

    LEDPWM_WriteCompare1(0);

    LEDPWM_WriteCounter(0) ;

    LEDPWM_Enable() ;

   

    LEDDuration_Stop() ;

    LEDDuration_ReadStatusRegister();

}

int main(void)

{

    Timer_1_Init();

    LEDDuration_Init();

    LEDPWM_Init() ;

   

    TimerInterrupt_Start();

    TimerInterrupt_StartEx(TimerInterrupt);

   

    LEDOffInterrupt_Start();

    LEDOffInterrupt_StartEx(LEDOffInterrupt);

   

    // 5 second cycle.

    Timer_1_WritePeriod(500);

    Timer_1_WriteCounter(0) ;

    Timer_1_Enable() ;

   

    CyGlobalIntEnable; /* Enable global interrupts. */

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

    for(;;)

    {

        /* Place your application code here. */

    }

}

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

moto

View solution in original post

0 Likes
2 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,

It would be appreciated if you post only one project, so that we don't have to hunt eggs.

So I read and touched some of your project

LEDDuration:

I changed Run Mode to "One Shot"

010-LEDDuration_config.JPG

LEDPWM CMP Value 1 to 254 so that the LED will not be too bright in the first 5s Timer cycle

012-LEDPWM_Config.JPG

main.c

NOTE: To the changed compare value take effect, the counter must be written 0.

So usually we do

PWM_Stop() ;

PWM_WriteCompare(new_value) ;

PWM_WriteCounter(0) ;

PWM_Enable() ;

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

/* ========================================

*

* Copyright YOUR COMPANY, THE YEAR

* All Rights Reserved

* UNPUBLISHED, LICENSED SOFTWARE.

*

* CONFIDENTIAL AND PROPRIETARY INFORMATION

* WHICH IS THE PROPERTY OF your company.

*

* ========================================

*/

#include "project.h"

uint8 switchPeriod = 0;

/** Set the LED to turn on for *time* seconds at *pwmMag*. */

void setLED(int pwmMag, int time) {

    LEDDuration_Stop() ;

    LEDPWM_Stop() ;

   

    LEDDuration_WritePeriod(time * 100);

    LEDDuration_WriteCounter(0);

       

    LEDPWM_WriteCompare1(pwmMag);

    LEDPWM_WriteCounter(0) ;

   

    LEDPWM_Enable() ;

    LEDDuration_Enable() ;

}

CY_ISR(TimerInterrupt)

{

    if (switchPeriod) {

        // Set LED to be on for 1 second and PWM to be half.

        switchPeriod = 0;

        setLED(130, 1);

    } else {

        // Set LED to be on for 2 seconds and PWM to be full

        switchPeriod = 1;

        setLED(255, 2);

    }

    Timer_1_ReadStatusRegister();

}

CY_ISR(LEDOffInterrupt) {

    LEDPWM_Stop() ;

    LEDPWM_WriteCompare1(0);

    LEDPWM_WriteCounter(0) ;

    LEDPWM_Enable() ;

   

    LEDDuration_Stop() ;

    LEDDuration_ReadStatusRegister();

}

int main(void)

{

    Timer_1_Init();

    LEDDuration_Init();

    LEDPWM_Init() ;

   

    TimerInterrupt_Start();

    TimerInterrupt_StartEx(TimerInterrupt);

   

    LEDOffInterrupt_Start();

    LEDOffInterrupt_StartEx(LEDOffInterrupt);

   

    // 5 second cycle.

    Timer_1_WritePeriod(500);

    Timer_1_WriteCounter(0) ;

    Timer_1_Enable() ;

   

    CyGlobalIntEnable; /* Enable global interrupts. */

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

    for(;;)

    {

        /* Place your application code here. */

    }

}

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

moto

0 Likes

Ah thank you! Using a one-shot counter fixes the bug. I did not think about the fact that the off interrupt would loop around again after I cleared it and bleed into the next interval.