Turn on PWM for specific number of pulses, then turn off.

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

cross mob
MiKi_3184011
Level 1
Level 1
First question asked First reply posted First like given

I have a PWM component on a cy8cproto-0624343w board thats driving a stepper motor.  It works fine as an always on or off but i would like to be able to start it with a specific amount of pulses required and have it turn off automatically when those pulses are complete.  I'm very new to Cypress and having a hard time finding relevant examples for the PSoC 6 platform, any help would be greatly appreciated.

0 Likes
1 Solution
AchimE_41
Employee
Employee
10 sign-ins 5 sign-ins First comment on KBA

Hi Mike,

I think there are 3 ways to do this, probably more.

1. As Lingling said you can count the periods by adding an interrupt to the PWM, that is triggered every time an overflow happens. If the interrupt happened the desired time, stop the pwm.

2. Cascade two TCPWM, one is your PWM, the other one is a Counter.

Note: the clock used to drive the TCPWM should no be faster than 1/4 peri_clock in this case.

- The Counter is in single-shot Compare mode. The PWM obvious in continuous PWM mode. Kill Mode is "Stop on Kill".

- The Counter is configured to have a count input (trigger on rising edge) connected to the PWM overflow signal.

- The PWM is configured to have its Kill/Stop input (trigger on rising edge) connected to the Counter capture_out signal.

- The counters period is the number of pulse you want to see minus one (I think).

Each period of the PWM will increase the Counters value, when the counter reaches its Period, it will stop the PWM.

3. Use the Smart-IOs, but this one is quite restricted.

- a) Only available if the PWM is on port 8 or 9

- a) You will lose a Pin on that port because it is disabled due to internal routing. (It is used to route the Stop trigger back to the PWM)

- b) You can use any PWM and will lose 2 GPIOs on the port for internal routing. (One is used to route the Stop trigger back to the PWM, one to route the PWM overflow trigger to start the SmartIO counter (DU or DataUnit))

- You are only allowed to have one PWM on each of these two ports, where you want to do the pulse counting.

Smart-IO is some logic added to the IO-Port, that also contains a 8bit counter, that could be used for this.

[4. On other PSoC6 devices use the UDBs to generate a counter. Your device does not have UDBs and Modus does not support own components yet.]

regards,

Achim

View solution in original post

4 Replies
LinglingG_46
Moderator
Moderator
Moderator
500 solutions authored 1000 replies posted 10 questions asked

You can use one Variable to record how many periods has run. And stop the PWM depending on your demand.

It needs to be designed by your project logic.

0 Likes
AchimE_41
Employee
Employee
10 sign-ins 5 sign-ins First comment on KBA

Hi Mike,

I think there are 3 ways to do this, probably more.

1. As Lingling said you can count the periods by adding an interrupt to the PWM, that is triggered every time an overflow happens. If the interrupt happened the desired time, stop the pwm.

2. Cascade two TCPWM, one is your PWM, the other one is a Counter.

Note: the clock used to drive the TCPWM should no be faster than 1/4 peri_clock in this case.

- The Counter is in single-shot Compare mode. The PWM obvious in continuous PWM mode. Kill Mode is "Stop on Kill".

- The Counter is configured to have a count input (trigger on rising edge) connected to the PWM overflow signal.

- The PWM is configured to have its Kill/Stop input (trigger on rising edge) connected to the Counter capture_out signal.

- The counters period is the number of pulse you want to see minus one (I think).

Each period of the PWM will increase the Counters value, when the counter reaches its Period, it will stop the PWM.

3. Use the Smart-IOs, but this one is quite restricted.

- a) Only available if the PWM is on port 8 or 9

- a) You will lose a Pin on that port because it is disabled due to internal routing. (It is used to route the Stop trigger back to the PWM)

- b) You can use any PWM and will lose 2 GPIOs on the port for internal routing. (One is used to route the Stop trigger back to the PWM, one to route the PWM overflow trigger to start the SmartIO counter (DU or DataUnit))

- You are only allowed to have one PWM on each of these two ports, where you want to do the pulse counting.

Smart-IO is some logic added to the IO-Port, that also contains a 8bit counter, that could be used for this.

[4. On other PSoC6 devices use the UDBs to generate a counter. Your device does not have UDBs and Modus does not support own components yet.]

regards,

Achim

Thank you sir, your second example worked perfectly.  Because it's specific to this example i would like to ask a further question. I want to fire an interrupt when the PWM receives the kill signal from the counter so i can clean up some stuff?

0 Likes

Hi,

I dont think there is a way to trigger that on the tcpwm that is generating the PWM, but you can generate an interrupt on the COUNTER that fires the kill signal. In the Config of the COUNTER set the interrupt to "Overflow & Underflow"

Code would look like this:

void COUNTER_IRQHandler(void)

{

Cy_TCPWM_ClearInterrupt(COUNTER_HW, COUNTER_NUM, CY_TCPWM_INT_ON_TC);

/* your code */

}

cy_stc_sysint_t intrCfg =

{

   /*.intrSrc =*/ COUNTER_IRQ, /* Interrupt source TCPWM for COUNTER */

   /*.intrPriority =*/ 2UL     /* Interrupt priority is 2 */

};

int main(void)

{

    /* Set up the device based on configurator selections */

    init_cycfg_all();

    /* Init the TCPWM */

    Cy_TCPWM_PWM_Init(COUNTER_HW, COUNTER_NUM, &COUNTER_config);

    Cy_TCPWM_PWM_Enable(COUNTER_HW, COUNTER_NUM);

    Cy_TCPWM_TriggerStart(COUNTER_HW, COUNTER_MASK);

    /* Initialize the interrupt with vector at COUNTER_IRQHandler() */

Cy_SysInt_Init(&intrCfg, &COUNTER_IRQHandler);

/* Enable the interrupt */

Cy_TCPWM_ClearInterrupt(COUNTER_HW, COUNTER_NUM, CY_TCPWM_INT_ON_TC);

NVIC_EnableIRQ(intrCfg.intrSrc);

    __enable_irq();

    for(;;)

    {

    }

}

0 Likes