PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 14, 2011 3:19 pm |
|
|
I made it work, but I modified your program in several ways. Here's the
output for a 100 ms input pulse. I also tested it with 200, 201, etc., and it
works. I tested this with your compiler version, vs. 3.249.
Quote: |
100
100
100
100
100
|
See the revised test program below. I'm using a "low pin count" 16F690
board from Microchip, so I don't have an LCD on the board. Instead I
used a cheap software UART going to the PC and displayed the output
on Teraterm. Cheap means 2 wires, Tx and Gnd, and a DB-9 connector.
1. I got rid of all the array stuff. It's not needed for this test.
2. I initialized the pulse generation pin (Pin C0) to a low level.
3. I clear any existing CCP interrupt before starting.
4. I changed your pulse generation code to create a positive pulse at
the start of the loop. That way, your display code is not included in
the timing count.
5. I changed the generated pulse width to 100 ms, instead of your
proposed value of 1000 ms. That's because you have the Timer1
clock rate set at 125 KHz (4 MHz / 4 / 8 = 125 KHz). Timer1 can count
up to 65535, so the longest duration you can capture is about 524 ms.
I tested this, and it's a fact.
6. I reduced your loop delay at the end to 500 ms, just to speed up the
display update rate a little.
Code: |
#include <16F690.h>
#fuses INTRC_IO, NOWDT, NOPROTECT, PUT, BROWNOUT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C2, INVERT)
int8 capture_rising_edge;
int8 got_pulse_width;
int16 ccp_delta;
#int_ccp1
void ccp1_isr(void)
{
static int16 t1_rising_edge;
// If current interrupt is for rising edge.
if(capture_rising_edge)
{
setup_ccp1(CCP_CAPTURE_FE);
capture_rising_edge = FALSE;
t1_rising_edge = CCP_1;
}
else
{
setup_ccp1(CCP_CAPTURE_RE);
capture_rising_edge = TRUE;
ccp_delta = CCP_1 - t1_rising_edge;
got_pulse_width = TRUE;
}
}
//==================================
main()
{
int16 pulse_width_ms, local_ccp_delta;
got_pulse_width = FALSE;
capture_rising_edge = TRUE;
output_low(pin_C0);
setup_ccp1(CCP_CAPTURE_RE);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8 );
clear_interrupt(INT_CCP1);
enable_interrupts(INT_CCP1);
enable_interrupts(GLOBAL);
while(1)
{
output_high(pin_C0);
delay_ms(100);
output_low(pin_C0);
if(got_pulse_width)
{
disable_interrupts(GLOBAL);
local_ccp_delta = ccp_delta;
enable_interrupts(GLOBAL);
pulse_width_ms = local_ccp_delta / (125);
printf("%lu\n\r", pulse_width_ms);
got_pulse_width = FALSE;
}
delay_ms(500);
}
} |
|
|