- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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:
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
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Timer Configuration
May be you don't need all the input, but since it is working, I don't try more here today.
PWM Configuration
Note: the Compare value + 1 is the exact pulse width.
Pins (for CY8CKIT-044)
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.
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Dan,
may be CE224594_PSoC4_Counter_Frequency_DutyCycle is useful to you.
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Timer Configuration
May be you don't need all the input, but since it is working, I don't try more here today.
PWM Configuration
Note: the Compare value + 1 is the exact pulse width.
Pins (for CY8CKIT-044)
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.
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