2 Replies Latest reply on Jul 4, 2019 8:52 PM by MoTa_728816

    PSoC 5LP Duty Cycle

    CaDu_3933941

      Hi all,

      For my current project, I require to be able to read the pulse width of a PWM signal and store it in a variable using a PSoC 5LP. I would appreciate the help if anyone offered me any method on how to do this efficiently.

       

      Thanks

        • 1. Re: PSoC 5LP Duty Cycle
          Bob Marlowe

          Have a look into this thread.

           

          Bob

          • 2. Re: PSoC 5LP Duty Cycle
            MoTa_728816

            Hi,

             

            It took me a few days to implement this with CY8CKIT-059.

            There may (must) be better strategies, but this is the way I made it.

             

            At first I was trying to implement a state machine which advances state in each edge of the input signal,

            after all, I could not make it work well. (May be I'll try it again someday)

             

            Then I changed my strategy to use a couple of counters,

            one for counting "High" level and the other for "Low" level.

             

            With Rising Edge of the input signal,

            High Level counter gets reset and start counting,

            Low Level counter gets "capture" signal

             

            With Falling Edge of the input signal

            High Level counter gets "capture" signal

            Low Level counter gets reset and start counting.

             

            The schematic seems as

            001-schematic.JPG

            companion schematics

            Test PWM signal Generator

            002-PWM_GEN.JPG

            UART as usual

            003-UART.JPG

            Pin Assignment

            004-pin_assignment.JPG

             

            main.c

            ======================

            /**

            * Duty Cycle Count Test

            */

            #include "project.h"

            #include "stdio.h"

             

            volatile uint16_t h_count = 0 ;

            volatile uint16_t l_count = 0 ;

             

            char str[128] ; /* print buffer */

            void print(char *str)

            {

                UART_PutString(str) ;

            }

             

            void splash(void)

            {

                sprintf(str, "Duty Cycle Count Test (%s %s)\n", __DATE__, __TIME__) ;

                print(str) ;

            }

             

            CY_ISR(isr_H_callback)

            {

                h_count = H_Counter_ReadCapture() ;

                isr_H_ClearPending() ;

                H_Counter_Enable() ;

            }

             

            CY_ISR(isr_L_callback)

            {

                l_count = L_Counter_ReadCapture() ;

                isr_L_ClearPending() ;

                L_Counter_Enable() ;

            }

             

            void config_pwm(uint16_t period, uint16_t compare)

            {

                PWM_Stop() ;

                PWM_WriteCounter(0) ;

                PWM_WritePeriod(period) ;

                PWM_WriteCompare(compare) ;

                PWM_Start() ;   

            }

             

            void init_hardware(void)

            {

                Control_Reg_Write(1) ;

                CyDelayUs(10) ;

                Control_Reg_Write(0) ;

               

                UART_Start() ;

             

                H_Counter_Start() ;

                L_Counter_Start() ;

               

                H_Counter_Enable() ;

                L_Counter_Enable() ;

               

                isr_H_ClearPending() ;

                isr_L_ClearPending() ;

               

                isr_H_StartEx(isr_H_callback) ;

                isr_L_StartEx(isr_L_callback) ;

               

                CyGlobalIntEnable; /* Enable global interrupts. */   

            }

             

            void print_duty(uint16_t period, uint16_t compare)

            {

                uint16_t LW, HW ;

                float duty ;

                LW = l_count ;

                HW = h_count ;

                sprintf(str, "PWM %d/%d ", compare, period) ;

                print(str) ;

                sprintf(str, "Duty = %d:%d ", HW, LW) ;

                print(str) ;

                duty = (float)HW / (float)(HW + LW) ;

                sprintf(str, "%d.%02d %%\n", (int)(100 * duty), (int)(10000 * duty) % 100) ;

                print(str) ;

            }

             

            int main(void)

            {

                uint16_t period = 10000 ;

                uint16_t compare = 5000 ;

               

                init_hardware() ;   

                splash() ;

             

                config_pwm(period, compare) ;

                CyDelay(1000) ;

                   

                for(;;)

                {

                    print_duty(period, compare) ;

                   

                    compare += 100 ;

                    if (compare > period) {

                        compare = 0 ;

                    }

                   

                    config_pwm(period, compare) ;

                    CyDelay(1000) ;

                }

            }

            ======================

             

            Tera Term Log

            000-TeraTerm-log.JPG

             

            I'm glad that it's Friday!

             

            moto

            1 of 1 people found this helpful