4 Replies Latest reply on May 1, 2019 1:31 PM by AchimE_41

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

    MiKi_3184011

      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.

        • 1. Re: Turn on PWM for specific number of pulses, then turn off.
          LinglingG_46

          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.

          • 2. Re: Turn on PWM for specific number of pulses, then turn off.
            AchimE_41

            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

            1 of 1 people found this helpful
            • 3. Re: Turn on PWM for specific number of pulses, then turn off.
              MiKi_3184011

              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?

              • 4. Re: Turn on PWM for specific number of pulses, then turn off.
                AchimE_41

                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(;;)
                    {
                
                    }
                }