View previous topic :: View next topic |
Author |
Message |
soondin
Joined: 21 Apr 2011 Posts: 9
|
Generate Pulse used CCP1 Capture |
Posted: Mon May 16, 2011 8:25 am |
|
|
Hello All,
It's a code for pulse converter.
I used some code from this forum.
My target is get some pulse from sensor and send that pulse to other module.
When pulse reach to target, I hope to generate fixed pulse.
My code problem is can't make pulse what I want.
Following code works okay,
Code: |
output_low (PIN_A0);
delay_us (pulse_width);
|
But when PIN_A0 go high it's be delayed around 2*pulse_width
I think it's from interupt.
How can I solve this?
I'm newbie PIC programmer.
Please help me.
I'm used 4.084 compiler
Code: |
#include <18F2550.h>
//#include <errno.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=115200, xmit=PIN_C6, rcv=PIN_C7)
#zero_ram
int8 capture_falling_edge;
int8 got_pulse_width;
int16 ccp_delta;
int16 t1_falling_edge;
#int_ccp1
void ccp1_isr(void)
{
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;
int16 lim,set,kph;
int16 pul,offset,min,max;
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF);
setup_spi(SPI_SS_DISABLED);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_OFF);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_vref(FALSE);
output_high (PIN_A0);
lim = 1900;
set = lim * 0.95;
pul = 1400 * 500 / lim * 1.05;
offset = 280;
min = 50;
max = 2500;
got_pulse_width = FALSE;
capture_falling_edge = TRUE;
setup_ccp1(CCP_CAPTURE_FE);
setup_timer_1(T1_INTERNAL);
set_timer1(0);
clear_interrupt(INT_CCP1);
enable_interrupts(INT_CCP1);
enable_interrupts(GLOBAL);
while(TRUE)
{
if(got_pulse_width)
{
disable_interrupts(GLOBAL);
pulse_width = ccp_delta / 5;
enable_interrupts(GLOBAL);
kph = 1400 * 500 / pulse_width;
if( (kph < min) )
{
output_high(PIN_A0);
}
else if( (kph >= min) && (kph < set) )
{
output_low (PIN_A0);
delay_us (pulse_width);
output_high (PIN_A0);
delay_us (pulse_width);
}
else if( (kph >= set) && (kph < max) )
{
output_low (PIN_A0);
delay_us (pul);
output_high(PIN_A0);
delay_us (pul);
}
else if( (kph >= max) )
{
output_low (PIN_A0);
delay_us (275);
output_high(PIN_A0);
delay_us (275);
}
got_pulse_width = FALSE;
}
else
{
output_high (PIN_A0);
}
}
}
|
|
|
|
Geps
Joined: 05 Jul 2010 Posts: 129
|
|
Posted: Mon May 16, 2011 9:31 am |
|
|
If the delay is twice as long as to be expected, make sure your #use delay statement has the correct clock frequency in it. |
|
|
soondin
Joined: 21 Apr 2011 Posts: 9
|
|
Posted: Mon May 16, 2011 10:41 am |
|
|
Geps wrote: | If the delay is twice as long as to be expected, make sure your #use delay statement has the correct clock frequency in it. |
I think my delay and clock setting is correct
When work following else if.
Code: | else if( (kph >= min) && (kph < set) )
{
output_low (PIN_A0);
delay_us (pulse_width);
output_high (PIN_A0);
delay_us (pulse_width);
} |
output_low(PIN_A0) is okay with delay_us (pulse_width).
but output_high(PIN_A0) is work and happen 2 * delay_us (pulse_width).
What is wrong? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon May 16, 2011 3:07 pm |
|
|
Do an experiment. Take out the interrupt. "Fake up" the interrupt in
software. Put in some nominal values for the variables that are normally
set in the interrupt. Then look at the Pin A0 signal with a scope.
To do this, make the changes shown in bold below. I don't know the
repetition rate for your incoming pulses to the CCP1 pin, so I put in a
2ms period between pulses. Then I assumed a 1ms pulse arriving at
the CCP. So that's shown in the values that I entered below.
Run this code and see how it looks on the scope. This may give you
some information to debug the problem.
Quote: |
//enable_interrupts(GLOBAL);
while(TRUE)
{
delay_ms(2); // Loop delay
got_pulse_width = TRUE;
ccp_delta = 5000; // 1 ms pulse
if(got_pulse_width)
{
// disable_interrupts(GLOBAL);
pulse_width = ccp_delta / 5;
// enable_interrupts(GLOBAL);
kph = 1400 * 500 / pulse_width;
|
|
|
|
soondin
Joined: 21 Apr 2011 Posts: 9
|
|
Posted: Mon May 16, 2011 8:39 pm |
|
|
Thank you PCM programmer,
Quote: |
I don't know the repetition rate for your incoming pulses to the CCP1 pin, so I put in a 2ms period between pulses. |
My pulse(Square) range is from around 14ms to 300us.
When I do test with 1ms pulse, you can see scope capture under url.
http://twitpic.com/4yonuc |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon May 16, 2011 9:50 pm |
|
|
As a test, run your original code with a 1 ms pulse input. |
|
|
soondin
Joined: 21 Apr 2011 Posts: 9
|
|
Posted: Tue May 17, 2011 12:58 am |
|
|
PCM programmer wrote: | As a test, run your original code with a 1 ms pulse input. |
Please see link it's a input 1ms with my code
http://twitpic.com/4yr5cz
I can make some square pulse with remove some routine.
but Problems is can't detect no signal... |
|
|
soondin
Joined: 21 Apr 2011 Posts: 9
|
|
Posted: Tue May 17, 2011 1:18 am |
|
|
This is my new code.
I've remove following (inside while loop) and used offset value.
// got_pulse_width = FALSE;
Almost work fine. but some time can't detect no signal input or make strange pulse when just high CCP pins.
Code: |
main()
{
int16 pulse_width;
int16 lim,set,kph;
int16 pul,offset,min,max;
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF);
setup_spi(SPI_SS_DISABLED);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_OFF);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_vref(FALSE);
output_high (PIN_A0);
lim = 1900;
set = lim * 0.95;
pul = 1400 * 500 / lim * 1.05;
offset = 280;
min = 50;
max = 2500;
got_pulse_width = FALSE;
capture_falling_edge = TRUE;
setup_ccp1(CCP_CAPTURE_FE);
setup_timer_1(T1_INTERNAL);
set_timer1(0);
clear_interrupt(INT_CCP1);
enable_interrupts(INT_CCP1);
enable_interrupts(GLOBAL);
while(TRUE)
{
if(got_pulse_width)
{
disable_interrupts(GLOBAL);
pulse_width = ccp_delta / 5;
enable_interrupts(GLOBAL);
kph = 1400 * 500 / pulse_width;
if( (kph < min) )
{
output_high(PIN_A0);
}
else if( (kph >= min) && (kph < set) )
{
output_low (PIN_A0);
delay_us (pulse_width);
output_high (PIN_A0);
delay_us (pulse_width - offset);
}
else if( (kph >= set) && (kph < max) )
{
output_low (PIN_A0);
delay_us (pul);
output_high(PIN_A0);
delay_us (pul - offset);
}
else if( (kph >= max) )
{
output_low (PIN_A0);
delay_us (280);
output_high(PIN_A0);
// delay_us (275);
}
// got_pulse_width = FALSE;
}
else
{
output_high (PIN_A0);
}
}
}
|
|
|
|
|