Pulse Width Measurement code

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

cross mob
DaRa_4676996
Level 1
Level 1

Hi Cypress community,

Please I would like to get help for getting a C code as a CY_ISR function or a piece of code in the for(;;) loop that  implements the counter capture method
for pulse width  measurement  with a PSoC 4 counter as illustrated in the  following  pictures:

pastedImage_142.png

pastedImage_145.png

Please Cypress tutorial examples for PSoC 4 devices - 4200L on my kit - or an expert who could show how to use
the counter API functions for switching the type of interrupts in this application.

Thank you for your help,
Dan Radut

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

I think that I've tried this before, but as I can not remember where it was,

I created a new sample with CY8CKIT-044.

I hope that the same method should work for PSOC 4200L.

Schematic

PWM is used for a test signal generator.

So please connect PWM_Out to PWM_In externally using jumper wire,

or you can provide your target pulse to PWM_IN

Note: I use 10kHz clock for PWM and 20kHz for Timer.

You need to adjust Clock_1 and the period of the Timer depending on your target pulse.

001-schematic.JPG

Timer Configuration

May be you don't need all the input, but since it is working, I don't try more here today.

002-Timer_config.JPG

PWM Configuration

Note: the Compare value + 1 is the exact pulse width.

002-PWM_config.JPG

Pins (for CY8CKIT-044)

003-pins.JPG

Tera Term Log

From the program PWM Compare was changed 10, 100, 1000, 9000...

And since Timer Clock is 2x of PWM clock if the read value is about twice of PWM Compare

it means the measurement was successful.

000-TeraTerm_log.JPG

main.c

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

#include "project.h"

#include "stdio.h"

#define STR_LEN 64

char    str[STR_LEN+1] ;

void    print(char *str)

{

UART_UartPutString(str) ; /* PSoC 4 */

// UART_PutString(str) ;     /* PSoC 5 */

}

void cls(void)

{

    print("\033c") ; /* reset */

    CyDelay(20) ;

    print("\033[2J") ; /* clear screen */

    CyDelay(20) ;

}

void splash(char *prog_name)

{

    cls() ;

    if (prog_name && *prog_name) {

        print(prog_name) ;

    }

    print(" (") ;

    print(__DATE__) ;

    print(" ") ;

    print(__TIME__) ;

    print(")\n") ;

}

volatile int capture_flag = 0 ;

volatile int overflow_flag = 0 ;

volatile uint16_t timer_value = 0 ;

#define MEASURE_CYCLE 5

int num_measured = 0 ;

uint16_t compares[] = { 10, 100, 1000, 9000 } ;

int num_compares = sizeof(compares) / sizeof(uint16_t) ;

int compare_index = 0 ;

CY_ISR(timer_isr)

{

    uint32_t source ;

    timer_interrupt_Disable() ;

    source = Timer_GetInterruptSource() ;

    if (source & Timer_INTR_MASK_TC) {

        overflow_flag = 1 ;

    } else if (source & Timer_INTR_MASK_CC_MATCH) {

        capture_flag = 1 ;

        timer_value = Timer_ReadCounter() ;

    }

    Timer_ClearInterrupt(source) ;

}

void set_pwm_compare(uint16_t value)

{

    snprintf(str, STR_LEN, "PWM Compare: %d\n\r", value) ;

    print(str) ;   

    PWM_Stop() ;

    PWM_WriteCompare(value) ;

    PWM_WriteCounter(0) ;

    PWM_Enable() ;

}

  

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */   

    UART_Start() ;

   

    PWM_Start() ;

       

    timer_interrupt_ClearPending() ;

    timer_interrupt_StartEx(timer_isr) ;

    Timer_Start() ;

}

int main(void)

{

    init_hardware() ;

   

    splash("Pulse Counter Test") ;

   

    set_pwm_compare(compares[compare_index]) ;

   

    for(;;)

    {

        if (overflow_flag) {

            overflow_flag = 0 ;

            print("Timer Over flow!\n") ;

            Timer_WriteCounter(0) ;

            timer_interrupt_ClearPending() ;

            timer_interrupt_Enable() ;

        }

        if (capture_flag) {

            capture_flag = 0 ;

            snprintf(str, STR_LEN, "Measured: %d\n\r", timer_value) ;

            print(str) ;

           

            num_measured++ ;

            if (num_measured >= MEASURE_CYCLE) {

                num_measured = 0 ;

                compare_index = (compare_index + 1) % num_compares ;

                set_pwm_compare(compares[compare_index]) ;

            }

            Timer_WriteCounter(0) ;

            timer_interrupt_Enable() ;

        }

    }

}

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

Hope this can be another hint for you.

moto

View solution in original post

0 Likes
2 Replies
LiDo_2439176
Level 5
Level 5
First question asked 50 replies posted 50 sign-ins

Hi Dan,

may be CE224594_PSoC4_Counter_Frequency_DutyCycle is useful to you.

psoc 4 L freq.png

Timer 1 counts high part of waveform and Timer 2 counts low part of waveform. By adding the two values we can calculate the period of the waveform and so on.

Best regards,

Liviu

0 Likes
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

I think that I've tried this before, but as I can not remember where it was,

I created a new sample with CY8CKIT-044.

I hope that the same method should work for PSOC 4200L.

Schematic

PWM is used for a test signal generator.

So please connect PWM_Out to PWM_In externally using jumper wire,

or you can provide your target pulse to PWM_IN

Note: I use 10kHz clock for PWM and 20kHz for Timer.

You need to adjust Clock_1 and the period of the Timer depending on your target pulse.

001-schematic.JPG

Timer Configuration

May be you don't need all the input, but since it is working, I don't try more here today.

002-Timer_config.JPG

PWM Configuration

Note: the Compare value + 1 is the exact pulse width.

002-PWM_config.JPG

Pins (for CY8CKIT-044)

003-pins.JPG

Tera Term Log

From the program PWM Compare was changed 10, 100, 1000, 9000...

And since Timer Clock is 2x of PWM clock if the read value is about twice of PWM Compare

it means the measurement was successful.

000-TeraTerm_log.JPG

main.c

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

#include "project.h"

#include "stdio.h"

#define STR_LEN 64

char    str[STR_LEN+1] ;

void    print(char *str)

{

UART_UartPutString(str) ; /* PSoC 4 */

// UART_PutString(str) ;     /* PSoC 5 */

}

void cls(void)

{

    print("\033c") ; /* reset */

    CyDelay(20) ;

    print("\033[2J") ; /* clear screen */

    CyDelay(20) ;

}

void splash(char *prog_name)

{

    cls() ;

    if (prog_name && *prog_name) {

        print(prog_name) ;

    }

    print(" (") ;

    print(__DATE__) ;

    print(" ") ;

    print(__TIME__) ;

    print(")\n") ;

}

volatile int capture_flag = 0 ;

volatile int overflow_flag = 0 ;

volatile uint16_t timer_value = 0 ;

#define MEASURE_CYCLE 5

int num_measured = 0 ;

uint16_t compares[] = { 10, 100, 1000, 9000 } ;

int num_compares = sizeof(compares) / sizeof(uint16_t) ;

int compare_index = 0 ;

CY_ISR(timer_isr)

{

    uint32_t source ;

    timer_interrupt_Disable() ;

    source = Timer_GetInterruptSource() ;

    if (source & Timer_INTR_MASK_TC) {

        overflow_flag = 1 ;

    } else if (source & Timer_INTR_MASK_CC_MATCH) {

        capture_flag = 1 ;

        timer_value = Timer_ReadCounter() ;

    }

    Timer_ClearInterrupt(source) ;

}

void set_pwm_compare(uint16_t value)

{

    snprintf(str, STR_LEN, "PWM Compare: %d\n\r", value) ;

    print(str) ;   

    PWM_Stop() ;

    PWM_WriteCompare(value) ;

    PWM_WriteCounter(0) ;

    PWM_Enable() ;

}

  

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */   

    UART_Start() ;

   

    PWM_Start() ;

       

    timer_interrupt_ClearPending() ;

    timer_interrupt_StartEx(timer_isr) ;

    Timer_Start() ;

}

int main(void)

{

    init_hardware() ;

   

    splash("Pulse Counter Test") ;

   

    set_pwm_compare(compares[compare_index]) ;

   

    for(;;)

    {

        if (overflow_flag) {

            overflow_flag = 0 ;

            print("Timer Over flow!\n") ;

            Timer_WriteCounter(0) ;

            timer_interrupt_ClearPending() ;

            timer_interrupt_Enable() ;

        }

        if (capture_flag) {

            capture_flag = 0 ;

            snprintf(str, STR_LEN, "Measured: %d\n\r", timer_value) ;

            print(str) ;

           

            num_measured++ ;

            if (num_measured >= MEASURE_CYCLE) {

                num_measured = 0 ;

                compare_index = (compare_index + 1) % num_compares ;

                set_pwm_compare(compares[compare_index]) ;

            }

            Timer_WriteCounter(0) ;

            timer_interrupt_Enable() ;

        }

    }

}

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

Hope this can be another hint for you.

moto

0 Likes