- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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:
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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"
LEDPWM CMP Value 1 to 254 so that the LED will not be too bright in the first 5s Timer cycle
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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"
LEDPWM CMP Value 1 to 254 so that the LED will not be too bright in the first 5s Timer cycle
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.