- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello, I have difficult to setup a simple Timer.
I use the Timer counter component with Clock + interrupt (isr_Timer1) on the interrupt connection.
I want simply be able to start the timer (one shot timer) and after the timer has finished, a interrupt function should be called and in this function I want switch off an LED.
follow Code does not works:
int main()
{
...
LED_Write(0u); // Switch On LED
ISR_Start(); Timer1_Start(); // start Timer + Interrupt isr_Timer1, ???
...
}
CY_ISR(Timer1)
{
LED_Write(1u); //Switch OFF LED after Timer has generate an Interrupt
}
what's wrong?
thank you.
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You are using "special" as "strange" or "odd", right?
> CY_ISR(timer_isr)
> {
> LED_Write(0u);
> Pin_8_Write(0u);
> CyDelay(1000);
> LED_Write(1u);
> Pin_8_Write(1u);
> }
You (actually we) are not supposed to stay in the ISR very long,
so it is not recommended to put "CyDelay(1000)" inside CY_ISR().
Probably it will cause WDT or some other interrupts.
How about modify the timer_isr as below?
CY_ISR(timer_isr)
{
LED_Write(!LED_Read()) ;
Timer_ClearInterrupt(Timer_TC_INTERRUPT_MASK) ; /* clear interrupt flag */
// Pin_8_Write(!Pin_8_Read()) ;
Timer_INT_StartEx(timer_isr) ; /* may be not necessary */
Timer_Start() ;
}
On the other hand, I noticed that the "EnterDeepSleepLowPowerMode();" in the for(;;) loop stops the timer,
so if this line is called before the timer generate interrupt, it will take very "LONG" time to generate interrupt.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You need to call
ISR_StartEx(Timer1); Timer1_Start(); // start Timer + Interrupt isr_Timer1,
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ISR_StartEx(Timer1); Timer1_Start(); // start Timer + Interrupt isr_Timer1,
that gives an error:
follow is the TopDesign:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your actual component name is isr_Timer1, so you need
isr_Timer1_StartEx(Timer1); Timer1_Start(); // start Timer + Interrupt isr_Timer1,
At this point Timer1() interrupt handler is unknown, so you need to declare
ISR_PROTO(Timer1);
at begin of main.c
I am not quite sure whether the handler name you used (Timer1) will conflict with the component name of the timer.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I changed design now as follow:
still have error:
main code:
int main()
{
ISR_PROTO(Tim);
...
...
if xy
{
LED_Write(0u); ISR_StartEx(Tim); Timer1_Start();
}
..
..
}
CY_ISR(Tim)
{
LED_Write(1u);
}
BTW: it doesn't matter if use isr_Tim or just Tim, always the same error?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Can you please post your complete project so that we all can have a look at all of your settings. Will make corrections of your errors easier. To do so, use
Creator->File->Create Workspace Bundle (minimal)
and attach the resulting file.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
user_1,
Attached below is a collection of various incarnations of the 1-Shot Timer:/odissey1
unfortunately I can not use the same component as you have used.
It still not works ... does anybody know why? (see my attached code in previous post)
thank you
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I wrote a simple test project similar to your ISR set up, and it worked fine for my CY8CKIT-044.
I'm wondering a couple of things.
(1) Is your program hit the line 354 in your main.c?
If the line does not get executed, probably it will not work.
(2) I can not remember exactly when, but one time I had an experience
that the "InterruptType" of Interrupt module needed to be "LEVEL" instead of "DERIVED".
In my sample trial both "DERIVED" and "LEVEL" worked though.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I wrote a simple test project similar to your ISR set up, and it worked fine for my CY8CKIT-044.
thank you.
I have now adapted and simplified all exactly according your code. Now with that code the compiler compiles without error - so that is good.
In the interrupt function I want just for testing switch On a LED, but unfortunately it looks that the function is never called because the LED goes not ON.
I'm confused now 😞 , see attached my project / code.
Addition: If I test just your code it works, but with the whole other code it does not works. There must be somewhere a bug conflict with a component or function??
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
if I add a delay of 6000ms after Timer_Start(); the interrupt function is called, if no delay the interrupt function is never called.
So there must be something in the main code that corrupts the timer / interrupt function... but what ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Your Timer interrupt occurs in 5.2sec (5200ms),
so if you give the timer 6000ms, surly the interrupt will be called.
In your project there are three interrupts, Timer, EZI2C and WDT.
And the priority of them are all 3 (same).
Although I can not test it as I can not compile your project in my environment,
off my head I would like to try..
(1) move Timer_INT_StartEx() and Timer_Start() after WDT_Start()
Either EZI2C_Start() or WDT_Start() may be disabling the Timer_INT_StartEx()/Timer_Start()
(2) set priority of Timer_INT higher than others
Setting an interrupt priority higher than WDT may not be a good idea though.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
(1) move Timer_INT_StartEx() and Timer_Start() after WDT_Start()
Either EZI2C_Start() or WDT_Start() may be disabling the Timer_INT_StartEx()/Timer_Start()
(2) set priority of Timer_INT higher than others
Setting an interrupt priority higher than WDT may not be a good idea though.
is very special, I changed Timer_INT priority to 2, the others are 3, still the same 😞
I'm not sure if it's really a interrupt conflict, because if I exclude CapSense_Start, WDT_Start and EZI2C_Start the issue is still the same.
So if have a delay of aprox 6000ms after Timer_Start and before the whole programm, means for(;;) it works properly, otherwise not.
very special... I will now try to move down the delay line for line to see which code-line makes the problem
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Thank you very much for your trying those.
It was a very nice trouble shooting, excluding those xxx_Start().
So interrupt conflict may not be the cause of this issue.
BTW,
> So if have a delay of aprox 6000ms after Timer_Start and before the whole programm,
> means for(;;) it works properly, otherwise not.
Are you talking about the inner loop timer also works or only the first shot works?
As I wrote in my previous response, providing 6000ms delay allows the timer to trigger the first shot.
But I wonder if the second and following shot(s) can be generated in the for(;;) loop or not.
Anyway, I'm sorry for not being a good help 😉
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
the delay must be after Timer_Start or somewhere in the for(;;) than it works.
regarding "one shot", I was thinking that if I select "one shot" the interrupt is only generated once.
So if I want that timer genarates a second time the interrupt I need to start the timer again, or not?
If I do follow see below, to see if interrupt is called a second time - the LEDs does not switch off.. again very special:
CY_ISR(timer_isr)
{
LED_Write(0u);
Pin_8_Write(0u);
CyDelay(1000);
LED_Write(1u);
Pin_8_Write(1u);
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I re-read main.c would you let me know
(1) If you put for (;;) ; before the original for (;;) { , will the timer work? (I'm hoping so)
(2) If (1) works, the cause is in the for (;;) loop, so please remove the added for (;;) ; and try
comment out each case xxx: ~ break one at a time,
so that you can identify the case which is causing the issue.
(I'm suspecting the "case SLEEP:", though)
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
see my reply above, the Delay must be somewhere after Timer_Start(), but it doesn't matter if in for(;;) or in a case etc.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So I supposed that something in the for(;;) { is stopping the timer interrupt, but to make it sure
I wanted to have empty for (;;) ; before the original for so that we can be sure that the cause is
in the for (;;) { loop and without it the delay is not required.
Then identify the cause I suggested to comment out one case at a time so that if you
comment out the case with the cause, the timer should work.
Then you can hunt down the cause of the issue in that particular case block.
BTW, I've started feeling that the "EnterDeepSleepLowPowerMode();" might be it.
Could you try just comment out that line and try without delay?
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
if I do without the main for(;;) it works without delay, but special is that the LEDs are not switching off?? see code:
CY_ISR(timer_isr)
{
LED_Write(0u);
Pin_8_Write(0u);
CyDelay(1000);
LED_Write(1u);
Pin_8_Write(1u);
}
int main()
{
EZI2C_Start();
...
CapSense_Start();
...
WDT_Start();
...
Timer_INT_StartEx(timer_isr);
Timer_Start();
//CyDelay(8000);
for(;;){ }
for(;;)
{
...
...
...
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You are using "special" as "strange" or "odd", right?
> CY_ISR(timer_isr)
> {
> LED_Write(0u);
> Pin_8_Write(0u);
> CyDelay(1000);
> LED_Write(1u);
> Pin_8_Write(1u);
> }
You (actually we) are not supposed to stay in the ISR very long,
so it is not recommended to put "CyDelay(1000)" inside CY_ISR().
Probably it will cause WDT or some other interrupts.
How about modify the timer_isr as below?
CY_ISR(timer_isr)
{
LED_Write(!LED_Read()) ;
Timer_ClearInterrupt(Timer_TC_INTERRUPT_MASK) ; /* clear interrupt flag */
// Pin_8_Write(!Pin_8_Read()) ;
Timer_INT_StartEx(timer_isr) ; /* may be not necessary */
Timer_Start() ;
}
On the other hand, I noticed that the "EnterDeepSleepLowPowerMode();" in the for(;;) loop stops the timer,
so if this line is called before the timer generate interrupt, it will take very "LONG" time to generate interrupt.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
if I exclude EnterDeepSleepLowPowerMode(); it is blinking now.... hmm.
So that and the correct routine in the isr function is the solution. thank you 🙂
but on the other hand, how can I use timer together with the EnterDeepSleepLowPowerMode();...
respectively how to go on with timer if it was interrupted by EnterDeepSleep ? Is it possible to go on with the latest timer count position which was interrupted by EnterDeepSleep?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'd appreciate if you mark my answer as "correct" if the original issue about interrupt is solved.
Meantime, handling low power mode is quite another story and not an easy one.
For the short answer, I'd recommend you to read the Architecture Technical Reference Manual (TRM)
If you are using 4200L
Chapter 6 Interrupts
Chapter 11 Power Modes
Chapter 19 Timer, Counter and PWM
etc.
As I skimmed chapters regarding to the low power mode (deep sleep),
I found that at least the good news is the count of the timer is preserved.
So you can continue the timer after deep sleep. (19-4 Power Modes in TCPWM Block)
Or may be creating another question discussion about deep sleep and timer might lead you to correct answers.
moto