You are here

More PDL Examples - Pulse-Width Modulators | 赛普拉斯半导体

More PDL Examples - Pulse-Width Modulators

Last week I showed an example of using the PDL UART driver in a PSoC 6 application. Today I am going to show you a PWM and do more compare-and-contrast with the PDL-based code versus the generated API you might be used to with PSoC 4.

My project is going to use a PWM to blink an LED - because that has never been done before!!! If you have ever used PSoC Creator to make a design, you'll recognize what is going on here.

PSoC Creator PWM

The schematic looks just like it would for PSoC 4. I have a fairly slow (1kHz) clock feeding the PWM and a pair of pins connected to the inverting ("pwm_n") and non-inverting ("pwm") outputs. I chose recognizable names for the components because it will help me describe the API usage better. I also routed the two pins to P1.5 and P13.7 on the Pioneer kit because, step back in amazement folks, those are the physical pins that connect to LED8 and LED9.

PWM pin selections

Inside the PWM customizer I chose a period of 1000 for a 1Hz blink rate (OK, the PWM counter is actually zero-based so it is a 0.999Hz rate, but who wants to do the math?). I set the compare value to 100 so the pins will blink either mostly-on or mostly-off.

PWM customizer - setting period to 100, compare to 100

When I build this design PSoC Creator pulls in the PDL driver and generates some configuration code (BlinkyPWM.*) to make it easy to use.

PSoC Creator workspace with generated source

So, to write the firmware I have a couple of options. For the PWM component the authors include a thin "shim" that makes the PWM look identical to the PSoC 4 API. So the following code turns on the PWM and the pin blink away like troopers.


Now that is great, the whole application is almost indistinguishable from a PSoC 4 version. It is easy to write and it works perfectly. But this is a very simple application and that shim layer does not provide "instance-based API" for every PWM function. Eventually we are going to need to call the PDL directly. Let's start by replacing the _Start().

To do this you can look in two places - the PDL documentation or the generated code we are replacing! The PDL tells you how to write firmware that refers directly to the hardware. Here is the snippet of code it suggests you use to turn on a PWM.

/* Scenario: there is need to initialize
 * the first (index = 0) PWM of the TCPWM0 block
 * with the previously defined configuration settings
#define MY_TCPWM_PWM_NUM   (0UL)
   /* Handle possible errors */
/* Enable the initialized PWM */
/* Then start the PWM */

This example sets up counter 0 in block TCPWM0. Note that the documentation also tells you how to define the "config" struct in firmware. From here I can figure out that I need to call the following functions.

  • Cy_TCPWM_PWM_Init
  • Cy_TCPWM_PWM_Enable
  • Cy_TCPWM_TriggerStart

​That all seems pretty easy but with PSoC Creator it is even easier because it generates macros for all the arguments - so I do not need to figure out which physical TCPWM block is used. Instead of "TCPWM0" I can just use "BlinkyPWM_HW". For "MY_TCPWM_PWM_NUM" I use "BlinkyPWM_CNT_NUM". I do not have to write the configuration struct because "BlinkyPWM_config" is created for me from the choices I made in the customizer dialog. And, finally, the trigger mask is "BlinkyPWM_CNT_MASK". Here is the code, which turns on the PWM just like the _Start() function.

Cy_TCPWM_PWM_Init( BlinkyPWM_HW, BlinkyPWM_CNT_NUM, &BlinkyPWM_config );
Cy_TCPWM_PWM_Enable( BlinkyPWM_HW, BlinkyPWM_CNT_NUM );
Cy_TCPWM_TriggerStart( BlinkyPWM_HW, BlinkyPWM_CNT_MASK );

OK, that's simple enough but there is a way to cheat! I like that plan! Take a look in the generated BlinkyPWM.c file and find the _Start() function itself. It looks like this.

void BlinkyPWM_Start(void)
   if (0U == BlinkyPWM_initVar)
       (void) Cy_TCPWM_PWM_Init(BlinkyPWM_HW, BlinkyPWM_CNT_NUM, &BlinkyPWM_config);
       BlinkyPWM_initVar = 1U;
   Cy_TCPWM_Enable_Multiple(BlinkyPWM_HW, BlinkyPWM_CNT_MASK);
   #if (BlinkyPWM_INPUT_DISABLED == 7UL)
       Cy_TCPWM_TriggerStart(BlinkyPWM_HW, BlinkyPWM_CNT_MASK);
   #endif /* (BlinkyPWM_INPUT_DISABLED == 7UL) */   

Surprise, surprise! It's basically identical code. This is really useful because, even if your development flow is to use PSoC Creator only to draw the schematic and do all your firmware in another IDE, you still get a lot of generated reference code which will work perfectly in your application.

With PDL (and the generated shim layer) we are just adding to your available choices for firmware development. Using PDL is not really any harder than before, plus it saves a lot of code bloat and is easier to use with revision control systems (the drivers do not generated with the design). Next week I'll add some more examples... closing out the PWM application with an interrupt component and an ISR handler.




David Phillips's picture

Sharing such sort of article are truly helpful for individuals exceptionally undergrads to think about the most recent innovation. The photo gives a general thought regarding the procedure.

0234rihankhan_3298166's picture

Robux is very funny game and easy to get free robux this ,maximum played game many person can play it same on time enjoy it free robux its give many platform to play its and its simply to get on my website.

Chloe Norris's picture

The principle preferred standpoint of PWM is that power misfortune in the exchanging gadgets is low. At the point when a turn is off there is for all intents and purposes no present, and when it is on, there is no voltage drop over the switch. Power misfortune, being the result of voltage and current, is in this manner in the two cases near zero. PWM additionally functions admirably with computerized controls, which, on account of their on/off nature, can without much of a stretch set the required obligation cycle.


Regards: assignment help UK