CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

ex_use_capture.c - capture of a semi-cycle Pulse Width

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
AlbertCharles



Joined: 15 Sep 2023
Posts: 5

View user's profile Send private message Send e-mail

ex_use_capture.c - capture of a semi-cycle Pulse Width
PostPosted: Tue Aug 13, 2024 5:09 pm     Reply with quote

Hi Guys!

i'm using a ex_use_capture.c - PIC16F877A -Ccs PCM 5.115

Second: 4935.6
First: 4459.2
Second-First= Period: 476.4 us

Second: 7107.2
First: 6630.8
Second-First= Period: 476.4 us


Second: 10231.4
First: 9755.0
Second-First= Period: 476.4 us

I created fixed pulse train through scope's pulse generator, like this:

// sorry about figure...
_ _ _ _
| | |
| | |
| | |
| |_|

<-------> 476.4 us = perĂ­od

In the scope, i read the HIGH pulse at ~433us and LOW pulse at ~43us.
Boths add up ~476.4us. Its correct.
But the problem is that I need to know the exact value of each high and low pulse.
The variables that capture these values in the program receive variant values, as I published above. Why?

I appreciate and appreciate any help, as I've been at this for 15 days Thanks.

Below is the program:

---------------------------------------------------------------------------------

#include <16F877A.h>
#fuses HS, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(crystal=20MHz)

#define GENERATE_PWM_SIGNAL
#define RS232_XMIT PIN_C6
#define RS232_RCV PIN_C7
#define CAPTURE_PIN PIN_C2
#define CAPTURE_TIMER 1


#define PWM_PIN PIN_C1
#define PWM_TIMER 2
#define __CCS_USE_TIMER_PERIPH 0

#use rs232(xmit=RS232_XMIT, rcv=RS232_RCV, baud=9600) //Text through the UART
#use capture(input=CAPTURE_PIN,timer=CAPTURE_TIMER, CAPTURE_FALLING)

#ifdef GENERATE_PWM_SIGNAL
#use pwm(output=PWM_PIN, timer=PWM_TIMER, frequency=2kHz, duty=50)

#define TICK_IS_16BITS
#include <tick.c>

#define GetTickDifference(a,b) (a-b)
#endif

#if getenv("INSTRUCTION_CLOCK") >= 1000000
#define PERIOD_DIVISOR (getenv("INSTRUCTION_CLOCK") / 1000000)
#else
#define PERIOD_DIVISOR 1
#endif

unsigned int16 FirstCapture, SecondCapture;
int1 NewCapture = FALSE;

#INT_CCP1

void Capture_Interrupt(void)
{
static int1 First = TRUE;
unsigned int16 dummy;

if(!NewCapture)
{
if(First)
FirstCapture = get_capture_time(); //Read first capture event.
else
{
SecondCapture = get_capture_time(); //Read second capture event.
NewCapture = TRUE;
}

First++;
}
else
dummy = get_capture_time();
}

#define GetCaptureDifference(a,b) (b-a)

#ifdef GENERATE_PWM_SIGNAL
//The following are values used to generate 6 different PWM signals for
//the Capture to measure. The periods are 500us, 333.3us, 250us, 125us,
//62.5us, 31.2us.
//obs: i'm not using
unsigned int32 PwmFrequency[6] = {2000, 3000, 4000, 8000, 16000, 32000};

#endif

void main()
{
#ifdef GENERATE_PWM_SIGNAL
TICK CurrentTick, PreviousTick;
#endif
unsigned int16 Time,Time1;
unsigned int8 i = 0;

printf("\n\rex_use_captur.c - %s\n\n\r", getenv("DEVICE"));

//enable the Capture interrupt
enable_interrupts(INT_CCP1);
enable_interrupts(GLOBAL);

#ifdef GENERATE_PWM_SIGNAL
PreviousTick = CurrentTick = TickGet();
#endif

while (TRUE)
{
#ifdef GENERATE_PWM_SIGNAL
CurrentTick = TickGet();

// obs: i'm not using......
if(GetTickDifference(CurrentTick, PreviousTick) >= (5*TICKS_PER_SECOND)) //change PWM period every 5 seconds
{
if(++i >= 6)
i = 0;

pwm_set_frequency(PwmFrequency[i]);
pwm_set_duty_percent(500);

PreviousTick = CurrentTick;
}

#endif

if(NewCapture)
{
Time = GetCaptureDifference(FirstCapture, SecondCapture);

printf("Second: %8.1w us\n", ((unsigned int32)SecondCapture * 10) / PERIOD_DIVISOR);
printf("First: %8.1w us\n", ((unsigned int32)FirstCapture * 10) / PERIOD_DIVISOR);

printf("Period: %8.1w us", ((unsigned int32)Time * 10) / PERIOD_DIVISOR);

NewCapture = FALSE;
delay_ms(5000);
}
}
}
gaugeguy



Joined: 05 Apr 2011
Posts: 303

View user's profile Send private message

PostPosted: Wed Aug 14, 2024 6:15 am     Reply with quote

Your code is currently capturing every rising edge of the signal. If you want to measure the time high or time low you will need to capture both the rising edge and the falling edge.
You can either switch the CCP mode in each interrupt or set one CCP for rising capture and the other CCP for falling capture.
AlbertCharles



Joined: 15 Sep 2023
Posts: 5

View user's profile Send private message Send e-mail

PostPosted: Wed Aug 14, 2024 7:35 am     Reply with quote

Okay, thanks for your areply. I added the following lines after the line 120
if (v==0)
{
setup_ccp1(CCP_CAPTURE_RE);
v=1;
}
else
{
setup_ccp1(CCP_CAPTURE_FE);
v=0;
}
and the result was only the period reading changed, starting now with the rising edge and now with the falling edge. But the main thing is to obtain only the value of the high time, separate from the low time. I don't need the period, but each separate semicycle.
gaugeguy



Joined: 05 Apr 2011
Posts: 303

View user's profile Send private message

PostPosted: Wed Aug 14, 2024 8:29 am     Reply with quote

A full cycle has three time readings, not just two.
Rising edge, falling edge, & rising edge
or falling edge, rising edge, & falling edge.
AlbertCharles



Joined: 15 Sep 2023
Posts: 5

View user's profile Send private message Send e-mail

PostPosted: Wed Aug 14, 2024 9:25 am     Reply with quote

So, based on your answer, I say that I need to know the time (us) in which the high pulse was active, and then, the time (us) in which the low pulse was active. That's the real problem.Do you have any suggestions via code?
gaugeguy



Joined: 05 Apr 2011
Posts: 303

View user's profile Send private message

PostPosted: Wed Aug 14, 2024 9:37 am     Reply with quote

I am not giving you code, just some direction.

capture a rising edge, save as Rising1
capture a falling edge, save as Falling1
capture a rising edge, save as Rising2

time high = Falling1 - Rising1
time low = Rising2 - Falling1
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Aug 14, 2024 12:19 pm     Reply with quote

If CCS doesn't have an example, I KNOW there's a chapter devoted to 'how-to-do-it in the Microchip databook,though actual code will be in Assembler, converting to C is easy.
AlbertCharles



Joined: 15 Sep 2023
Posts: 5

View user's profile Send private message Send e-mail

PostPosted: Wed Aug 14, 2024 5:24 pm     Reply with quote

In the future I can try to convert, but today, in ccs, I would recover my time, as I have been in this fight for 15 days. If u have something in C, it would help me a lot.
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Aug 15, 2024 12:09 pm     Reply with quote

to add to gaugeguy's post..
if you reset( zero) the timer's 'count' register before the 1st rising edge detection.you'll see better numbers, providing you don't overflow( exceed the max count )
AlbertCharles



Joined: 15 Sep 2023
Posts: 5

View user's profile Send private message Send e-mail

PostPosted: Thu Aug 15, 2024 12:55 pm     Reply with quote

At lunch time I was meditating.. thinking about this hypothesis.. I will test it and report back here. Thanks
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group