Timer problem

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.
magic_3776931
Level 2
Level 2

Hi, I have a problem with Timer component.

My project is really simple, I would like to write in the compare register of the pwm the value read in the capture register of the timer.

The problem is that led's glow is not proportional to the time i press the mechanical switch.

How could i solve it?

0 Likes
1 Solution

If you right click the project and select "Update Components" it should put everything in order.  You are correct, I am a version behind on 4.1.  If you actually want to build and use the project I posted you will also probably need to change:

Target Device - Right Click Project > Device Selector

Pin Selection - Design Wide Resources > Pins

Clocks - Design Wide Resources > Clocks

VDD levels -  Design Wide Resources > System > Operating Conditions

as I'm using a different PSoC and setup to test with than you are.

Regarding your new project:

- Rather than pulsing the reset lines for the timer with a software delay, you actually already have the control register component set to "Pulse" which will do it automatically.    When you write a "1" to the control register it will generate a pulse, then return to the starting state (0).  The pulse will last for one clock cycle of attached clock signal, which will be enough for the timer to recognize it and reset the counter registers.

- You've got your Timer_1 component, the one set for 2S configured for trigger/capture, which you don't need.  It's job is to start and hit the Terminal Count once before you reset it in the ISR.  Set Trigger/Capture to NONE and remove the interrupt on capture.  We only want interrupt on TC.

View solution in original post

11 Replies
KyTr_1955226
Level 6
Level 6
250 sign-ins 10 likes given 50 solutions authored

One thing I noticed right away is you aren't clearing your timer interrupt, so it's basically gonna keep entering the ISR until you clear the flag.  You're reading the status register, which is good and should allow the Interrupt to be cleared, but you aren't actually clearing it.

Try:

TIMER_ISR_ClearPending();

at the end of your TIMER ISR.

Also, it's generally not a good idea to have a large delay in an ISR.  You want to spend as little time inside an ISR as reasonably possible.  You have a 2 second delay in there.  Might be worth having a second timer for 2 seconds, start the timer in your interrupt, and when the ISR fires, clear your PWM value.

I'm also seeing you're starting the PWM module almost fully ON at startup (CMP1 == 10000 == PERIOD VAL).  Is this intentional?  If not and you want to start the LED off, put 0 in for the CMP Value 1 in the component config.

Thank you for the advice, I added an other Timer that starts to count after reading the capture value of the "main" clock and on the terminal count it fires the second interrupt that clears the compare value and it works.

But I still have always the same problem, the glowing is not proportional to the time i press the mechanical switch, it's random.

Besides using the API function for clearing the interrupt after one time the project doesnt work anymore.

How can you say that reading the status register i don't clear the interrupt?

0 Likes

My mistake, looks like ReadStatusRegister should clear the interrupt flag.

I'm coming from PIC land where you have to clear the interrupt source, then clear the flag itself.  Looks like ReadStatusRegister for the Timer component should do both.

I'll give this a run on my test kit when I get a chance and see what I find.

Are you getting proper numbers from your timer when you release the button? I.E. 5000 for 4 seconds?

Are you able to confirm what numbers you are getting from your timer and feeding into the compare register?

0 Likes
lock attach
Attachments are accessible only for community members.

I think I might see it now.

The timer counts DOWN from the period value.  In this case 10000.

So if you hold the button for 2 seconds, you will have a capture of 8000.  In this case you want 2000 to the PWM Compare Register

PWM_WriteCompare(TIMER_INIT_PERIOD-counter);

EDIT:

Attached project that I ended up with.

I configured both the 10 Second timer and 2 Second timer for "one-shot" mode, and ran some control registers to the Reset inputs of the timers so that I could reset both timers counters with a control register write.

I also adjusted the 10 second timer to interrupt on TC (Terminal Count) so that if you hold the button for longer than 10 seconds, the interrupt will fire (rather than the timer rolling over with no notice).

FYI: I did this project on a CY8CKIT-50, so the device in the project and the pins used do not match your own.

magic_3776931
Level 2
Level 2

Thank you very much for these precious advices, I didnt check on datasheet Timer counts only down,I'm new to the world of mcu and psoc, at the beginning is quite hard.

Step by step the project is going better but these interrupts are diabolic, the first time  if I press just  for a while the button the led glows a little so its behaviour is right,but after this it blocked on a very bright state it seems the compare value alone is setted on the max value.

I can't see your attached project and I would like to attach my improved project but it seems I can't.

0 Likes

Hmm, I don't know why you wouldn't be able to download the project or upload your current one.  I'm able to download the one I attached to the previous post.

Anyway, you may want to consider running your timers in One-Shot mode.  Currently, your 10 second timer is running in Continuous mode.  This means that while it is enabled, it counts down from 10000 all the way to 0, it will roll over back to 10000 and do it again, for as long as the timer remains enabled.  This point where it hits 0 is called the Terminal Count (TC).  You can configure the module to interrupt when this occurs (Interrupt on TC).  Continuous timers I use mostly for events that need to occur regularly (every 20mS, for example).

Think about what this does when you press the button though.  The timer starts, you release the button after an amount of time, and the interrupt occurs for the capture.  The timer stops, but the value in the counter register hasn't been reset to 10000!  Next time a trigger occurs, it will resume counting from this value.  This is why you might be seeing "random" brightnesses on the LED.

One-Shot mode is different, and might be more suited for what you're trying to do.

When you configure as One-Shot and use the Capture/Trigger, you enable the timer in software (Timer_Start()), but the timer will not begin counting until your falling edge trigger occurs, and stops when the rising edge occurs.  You then reload the 10000 value into the counter register by giving a pulse on the RESET pin of the component (you can do this using a Control Register component).  At that point it is ready for the next trigger event.

What you then have to consider is what do you want to do when the button is pressed for longer than 10 seconds?  In the project I attached to the last post, I set to interrupt on the Terminal Count and write the full value to the PWM component.

Hope this wasn't too confusing.  Someone please correct me if I'm super wrong anywhere above.

lock attach
Attachments are accessible only for community members.
magic_3776931
Level 2
Level 2

Thank you for the advices, could you check for the last time the improved project? I hope not to bother you too much.

I set the control reg bit to 1 and again to 0 after 2msec in order to be sure that both timers recognize the rising edge of the reset pulse .(clock period 1msec)

This causes some problems to the second timer (Timer_1) count because sometimes the led stops to glow before 2msec.

I dont know if the problem is the project itself, how i route the component, or it's in the firmware.

I would ask you how could I can see your project attached on the last post? I can download it and see the code but i cant see how you route the component it seems you use an old version of psoc creator.

0 Likes

Maybe I solved the problem disabling capture event on Timer_1 and enabling only trigger mode rising edge detect.

In the C code i started the Timer_1 in the main and I deleted the API Timer_1_Stop.

Anyway could you check if i set the control registers in the right way? thank you.

0 Likes

You should not even need the Trigger on Timer_1.

Timer_1_Start();

will start the counting.  You could use the Trigger though if you wanted to control the timer starting via signal rather than in software.

The way you have it (minus the manual pulse of the reset signals) should work fine for software control:

CY_ISR(TIMER_ISR_Handler){ 

    uint16 counter = TIMER_ReadCapture();

    PWM_WriteCompare(10000-counter);

    Timer_1_Start();

    TIMER_ReadStatusRegister();

    Control_Reg_1_Write(1);        

}

CY_ISR(isr_1_handler){

    Timer_1_ReadStatusRegister();

    PWM_WriteCompare(0);

    Control_Reg_2_Write(1);

    Timer_1_Stop();

}

Thank you for your patience and kindness you have me precious advices!!

Actually it works good!!!

0 Likes

If you right click the project and select "Update Components" it should put everything in order.  You are correct, I am a version behind on 4.1.  If you actually want to build and use the project I posted you will also probably need to change:

Target Device - Right Click Project > Device Selector

Pin Selection - Design Wide Resources > Pins

Clocks - Design Wide Resources > Clocks

VDD levels -  Design Wide Resources > System > Operating Conditions

as I'm using a different PSoC and setup to test with than you are.

Regarding your new project:

- Rather than pulsing the reset lines for the timer with a software delay, you actually already have the control register component set to "Pulse" which will do it automatically.    When you write a "1" to the control register it will generate a pulse, then return to the starting state (0).  The pulse will last for one clock cycle of attached clock signal, which will be enough for the timer to recognize it and reset the counter registers.

- You've got your Timer_1 component, the one set for 2S configured for trigger/capture, which you don't need.  It's job is to start and hit the Terminal Count once before you reset it in the ISR.  Set Trigger/Capture to NONE and remove the interrupt on capture.  We only want interrupt on TC.