PWM Clock Sharing | Cypress Semiconductor
PWM Clock Sharing
Did you finish your homework? Well, here's an answer anyway. A couple of days ago I used a pair of TCPWM blocks to toggle the brightness of an LED at 1Hz. In that project I used an 8-bit clock divider as the source for the LED-driving PWM and a 16-bit divider for the slower toggling Timer-Counter. It worked just fine but it felt a little decadent to use two clock dividers when I am using a PSoC, which has the on-chip flexibility to use one divider for both TCPWM blocks. How to do that?
Well, the easy part is changing the clock source selection in the Timer-Counter using the Device Configurator. Open the project in ModusToolbox IDE and open the Configurator. In the SWAP_CTR block change the Clock Signal to "8 bit Divider 2 clk", which is marked in the drop-down as "USED" as a reminder that another resource is using that source (obviously... this is why we are choosing it!).
Next, there is a little mathematics, which is the English word for math. The frequency of the TCPWM output is a function of the peripheral clock (CLK_PERI) frequency, the 8 but divider value, the TCPWM prescaler (which I hinted at last time) and the period of the TCPWM counter. In pseudo-math (note that it is OK to call it math when it's "pseudo" - just because I am a snob does not mean I am not really lazy as well) it looks like this.
LED frequency = ----------------------------
divider * prescaler * period
Some of these are known (or the pseudo-math becomes "guessing"). The LED toggling frequency needs to be 1Hz. The CLK_PERI is set to 72MHz in the Platform tab of the Device Configurator and let's leave that alone. For the others, the divider is a 8-bit value, the period is 16-bit, and the prescaler is 1, 2, 4, 8, 16, 32, 164 or 128. The trick we have to perform is to divide and prescale CLK_PERI such that the TCPWM period gives us 1Hz, preferably with a nice round number. Here is the rearranged formula.
divider * prescaler * period = 72000000
The 16-bit TCPWM has a maximum period of 65535, which means the clock must be divided by at least 1098.6, which cannot be done in a 8-bit divider. So we need to use a prescaler value of at least 8. Beyond that there are gabillions of combinations that satisfy the equation. After a little trial and error, well mostly error, I figured out that a divider of 225 works really nicely because it creates a frequency of 320kHz. Precaling that by 32 gives me a TCPWM frequency of 10kHz and a period of 10000 gives me a 1Hz output. Et voila!
Here is the set up for the Timer-Counter, with the prescaler and period set as above.
Note that the LED_PWM just has to toggle fast enough not to flicker so I set the period to 1000 and the compare values to 500 and 50 for the 50% and 5% intensity values.
I had quite a lot of fun doing this project. I think it nicely illustrates how flexible PSoC is and how wretched my mathematics skills are. I've attached a template that you can use to replicate the design - to use it, open the New Application dialog and "Import..." the modus.mk file to create a copy of the project.
Note: you must be logged into cypress.com to see the attachment (PWM_Swap.zip).