Problems to refresh TCPWM Compare Value

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

cross mob
Anonymous
Not applicable

Hello,

   

I use a TCPWM to drive the Power Source of an LED. Period is 20Khz.

   

I only change the Compare (Duty) Value of the PWM to drive the LED power.

   

Every time I put a new Value in the Compare Register the LED flickers after write  one time.

   

Illustration Sample:

   

if  (power>100)  { duty--; TCPWM_WriteCompare(duty); }

   

else { duty++; TCPWM_WriteCompare(duty); }

   

Seems to be a restart of the PWM each Time when write Compare Register. I need the change only when Period restarts not inside the Period.

   

I see there are an WriteCompareBuf but if I write there nothing happent in PWM Signal (swap + SetCompareSwap enabled)

   

Regards,

   

Michael

0 Likes
9 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Can you please post your complete project, so that we all can have a look at all of your settings. To do so, use
Creator->File->Create Workspace Bundle (minimal)
and attach the resulting file.

   

 

   

Bob

0 Likes
Anonymous
Not applicable

Problem solved, thanks,  TCPWM_WriteCompare() dosen't restart PWM.

0 Likes
Anonymous
Not applicable

I still have problems to drive the LED's without flickers. So it seems that a TCPM_WriteCompare must be set directly after a TC Event (terminal count).

   

I take a look at the Cypress Sample Project "PWMExample01" and they use the TC Event before setting the Compare Register:

   

CY_ISR(InterruptHandler)
{
    /* Clear TC Inerrupt */
       PWM_ClearInterrupt(PWM_INTR_MASK_TC);
    
    /* Increment the Compare for LED brighrness decrease */ 
    PWM_WriteCompare(PWM_ReadCompare() + BRIGHTNESS_DECREASE);
}

   

int main()
{   
    /* Enable the global interrupt */
    CyGlobalIntEnable;
 
    /* Enable the Interrupt component connected to interrupt */
    TC_ISR_StartEx(InterruptHandler);
    
    /* Start the components */
    PWM_Start();
    PWM_WritePeriod(65300u);
    
    for(;;)
    {
        
    }
}

   

But in my case I have 12 PWM Sources (8 TCPWM + 4 UDB) and I have to set the Compare Register on different positions in  source code.

   

Question, can I directly access the TC Register of each PWM Unit without a Interrupt generation? Like this:

   

while (PWM1_TC_Register==0) ;

   

PWM1_WriteCompare(x);

   

 

   

Regards,

   

Michael

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Your while-loop is blocking. There is nothing bad about using interrupts for setting a new compare value.

   

 

   

Bob

0 Likes
Anonymous
Not applicable

Yes but then I have another 12 IRQ Routines and I need the compare change on different  positions in source...

   

 

   

When I  request the TC Flag with a while was the better solution for me, but I don't know how???

   

 

   

Michael

0 Likes
odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted
        info, I believe that TCPWM compare value is updated only when the counter rolls over (TC event is fired). For immediate update set the counter to zero immediately following Write compare operation. http://www.cypress.com/knowledge-base-article/best-practices-reload-compare-and-period-values-timerp... http://www.cypress.com/knowledge-base-article/dynamically-changing-period-value-timers-counters-and-... http://www.cypress.com/knowledge-base-article/changing-duty-cycle-pwm   
0 Likes
Anonymous
Not applicable

Unfortunately is the compare not update  automatically on TC event, see:

   

http://www.cypress.com/knowledge-base-article/changing-duty-cycle-pwm

   

>>>To prevent glitches on the PWM output, the compare value register should be updated only when the PWM is stopped or when the PWM has reached the zero count.

   

So I looking for a way to capture the TC event without using a Interrupt.

0 Likes

Hi,

You may reset the timer component after the writing the compare  value. That may work.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

"Yes but then I have another 12 IRQ Routines and I need the compare change on different  positions in source..."

   

So easiest (and cleanest) would be to define an array of a structure which contains a value for the new compare value and a pointer to a function that updates the PWM. so all your interrupt handlers look the same except for the index into the struct array. You can modify the value of any PWM anywhere in your program, when TC fires it will get updated. Care must be taken not to waste many MIPS, so when tested you should set the compiler optimization to "speed". This can be done on a file basis, so debugging the project can be performed in the non-optimized files.

   

 

   

Bob

0 Likes