|
|
View previous topic :: View next topic |
Author |
Message |
AlbertCharles
Joined: 15 Sep 2023 Posts: 3
|
ex_use_capture.c - capture of a semi-cycle Pulse Width |
Posted: Tue Aug 13, 2024 5:09 pm |
|
|
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: 295
|
|
Posted: Wed Aug 14, 2024 6:15 am |
|
|
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: 3
|
|
Posted: Wed Aug 14, 2024 7:35 am |
|
|
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: 295
|
|
Posted: Wed Aug 14, 2024 8:29 am |
|
|
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: 3
|
|
Posted: Wed Aug 14, 2024 9:25 am |
|
|
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? |
|
|
|
|
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
|