|
|
View previous topic :: View next topic |
Author |
Message |
tienchuan
Joined: 25 Aug 2009 Posts: 175
|
|
Posted: Wed Nov 13, 2013 8:42 am |
|
|
Thanks Ttelmah.
Code: | (ccp_delta *( 1/(10MHz)*(4*8*1000) ) ) |
Yes, It it's a remark.
In my project change use crystal 10MHZ so that I must calcualtor this constant.
Oh,I thought failure,, I'm careless when using division to change the code, because I always think division math is slower than multiplication. You pls show me way to calculate time for math operation.
Added, when i test with this code, it has return value when i disconnect pulse clock in CCP1 pin, If true, it must no return value,so that I think need to clear int_ccp1 flag?
here is my full code I changed flow your idea:
Code: |
#include <16F877A.h>
#fuses HS, NOWDT, NOPROTECT, PUT, BROWNOUT, NOLVP
#use delay(clock=10000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
int8 capture_falling_edge;
int8 got_pulse_width;
int16 ccp_delta;
#int_ccp1
void ccp1_isr(void)
{
static int16 t1_falling_edge;
// If current interrupt is for falling edge.
if(capture_falling_edge)
{
setup_ccp1(CCP_CAPTURE_RE);
capture_falling_edge = FALSE;
t1_falling_edge = CCP_1;
}
else
{
setup_ccp1(CCP_CAPTURE_FE);
capture_falling_edge = TRUE;
ccp_delta = CCP_1 - t1_falling_edge;
got_pulse_width = TRUE;
}
}
//====================================
main()
{
int16 pulse_width_ms;
int16 local_ccp_delta;
got_pulse_width = FALSE;
capture_falling_edge = TRUE;
setup_ccp1(CCP_CAPTURE_FE);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8 );
enable_interrupts(INT_CCP1);
enable_interrupts(GLOBAL);
while(1)
{
if(got_pulse_width)
{
disable_interrupts(GLOBAL);
local_ccp_delta = ccp_delta;
enable_interrupts(GLOBAL);
pulse_width_ms = (local_ccp_delta * 32) /10000 ;
printf("%lu ms \n\r", pulse_width_ms);
}
delay_ms(500);
}
}
|
_________________ Begin Begin Begin !!! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Wed Nov 13, 2013 9:22 am |
|
|
It's not INT_CCP1 that is causing it to display with no input. You are not clearing the flag 'got_pulse_width' when you print.
Code: |
while(1)
{
if(got_pulse_width)
{
disable_interrupts(GLOBAL);
local_ccp_delta = ccp_delta;
enable_interrupts(GLOBAL);
got_pulse_width=FALSE; //need this or it'll keep printing....
pulse_width_ms = (local_ccp_delta * 32) /10000 ;
printf("%lu ms \n\r", pulse_width_ms);
}
delay_ms(500);
}
|
On times, CCS has a table in the manual 'how much time do maths operations take', which can be scaled for different clock rates, but the simplest solution is to just use a pulse output and time the actual duration, or use the stopwatch feature in MPLAB.
There is one problem with *32/10000. The result of *32, won't fit in an int16, so for longer times, the values out the top will be lost (65mSec max). If this matters you'll need to cast to an int32.
Best Wishes |
|
|
tienchuan
Joined: 25 Aug 2009 Posts: 175
|
|
Posted: Wed Nov 13, 2013 8:34 pm |
|
|
Thanks u, Ttelmah.
Well, It worked
But it seem has error when i disconnect pulse in CCP1, It has return value???
And is here my code edited follow your comment:
Code: |
#include <16F877A.h>
#fuses HS, NOWDT, NOPROTECT, PUT, BROWNOUT, NOLVP
#use delay(clock=10000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
int8 capture_falling_edge;
int8 got_pulse_width;
int32 ccp_delta;
#int_ccp1
void ccp1_isr(void)
{
static int16 t1_falling_edge;
// If current interrupt is for falling edge.
if(capture_falling_edge)
{
setup_ccp1(CCP_CAPTURE_RE);
capture_falling_edge = FALSE;
t1_falling_edge = CCP_1;
}
else
{
setup_ccp1(CCP_CAPTURE_FE);
capture_falling_edge = TRUE;
ccp_delta = CCP_1 - t1_falling_edge;
got_pulse_width = TRUE;
}
}
//====================================
main()
{
int32 pulse_width_ms;
int32 local_ccp_delta;
got_pulse_width = FALSE;
capture_falling_edge = TRUE;
setup_ccp1(CCP_CAPTURE_FE);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8 );
enable_interrupts(INT_CCP1);
enable_interrupts(GLOBAL);
while(1)
{
if(got_pulse_width)
{
disable_interrupts(GLOBAL);
local_ccp_delta = ccp_delta;
enable_interrupts(GLOBAL);
got_pulse_width= FALSE;
pulse_width_ms = (local_ccp_delta * 32) /10000;
printf("%lu ms \n\r", pulse_width_ms);
}
delay_ms(500);
}
}
|
Thanks u so much. _________________ Begin Begin Begin !!! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Thu Nov 14, 2013 1:28 am |
|
|
No pulse = line floating (unless you have arranged a pull-up resistor). May start picking up RF/mains interference....
Best Wishes |
|
|
tienchuan
Joined: 25 Aug 2009 Posts: 175
|
|
Posted: Sat Nov 16, 2013 8:05 pm |
|
|
Well, I worked exactly:)
I added config in main code:
Follow instructions in datasheet:
Quote: | If the RC2/CCP1 pin is configured as an output, a write to the port can cause a Capture condition |
Thanks u very much _________________ Begin Begin Begin !!! |
|
|
|
|
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
|