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 support@ccsinfo.com

16F877 & measuring pulse width?

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







16F877 & measuring pulse width?
PostPosted: Wed Mar 26, 2003 7:36 am     Reply with quote

In the two weeks since I got my Warp13A and CCS 'C', I've managed to get much going, including an LCD output, an interrupt timer and doing A/D conversions. Much of this can can be directly attributed to the assistance of people on this board. Thanks.

There's just one step left in completing my Astronomy Sky Darkness Sensor, and that's to be able to measure a pulsewidth. I have made a couple of attempts at using the example called EX_CCPMP.c in the examples directory with a PIC16F877, but I've had no success so far.

My questions are the following...

1- Has anyone managed to get EX_CCPMP.c going on a 16F877?

2- Any ideas on how one could measure very long pulsewidths, say, as long as up to 10 seconds ( 0.1hz ), but also as fast as 1/1000th of a second ( 1000hz )?

Any working code snippets would, of course, be greatly welcomed. But any light at all you could cast on this topic would be appreciated.

Thanks,
Rollo
___________________________
This message was ported from CCS's old forum
Original Post ID: 13083
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

Re: 16F877 & measuring pulse width?
PostPosted: Wed Mar 26, 2003 9:01 am     Reply with quote

:=In the two weeks since I got my Warp13A and CCS 'C', I've managed to get much going, including an LCD output, an interrupt timer and doing A/D conversions. Much of this can can be directly attributed to the assistance of people on this board. Thanks.
:=
:=There's just one step left in completing my Astronomy Sky Darkness Sensor, and that's to be able to measure a pulsewidth. I have made a couple of attempts at using the example called EX_CCPMP.c in the examples directory with a PIC16F877, but I've had no success so far.
:=
:=My questions are the following...
:=
:=1- Has anyone managed to get EX_CCPMP.c going on a 16F877?
:=
:=2- Any ideas on how one could measure very long pulsewidths, say, as long as up to 10 seconds ( 0.1hz ), but also as fast as 1/1000th of a second ( 1000hz )?
:=
:=Any working code snippets would, of course, be greatly welcomed. But any light at all you could cast on this topic would be appreciated.
:=
:=Thanks,
:=Rollo

Read this
<a href="http://www.pic-c.com/forum/general/posts/12961.html" TARGET="_blank">http://www.pic-c.com/forum/general/posts/12961.html</a>
___________________________
This message was ported from CCS's old forum
Original Post ID: 13087
Sherpa Doug
Guest







Re: 16F877 & measuring pulse width?
PostPosted: Wed Mar 26, 2003 9:20 am     Reply with quote

:=In the two weeks since I got my Warp13A and CCS 'C', I've managed to get much going, including an LCD output, an interrupt timer and doing A/D conversions. Much of this can can be directly attributed to the assistance of people on this board. Thanks.
:=
:=There's just one step left in completing my Astronomy Sky Darkness Sensor, and that's to be able to measure a pulsewidth. I have made a couple of attempts at using the example called EX_CCPMP.c in the examples directory with a PIC16F877, but I've had no success so far.
:=
:=My questions are the following...
:=
:=1- Has anyone managed to get EX_CCPMP.c going on a 16F877?
:=
:=2- Any ideas on how one could measure very long pulsewidths, say, as long as up to 10 seconds ( 0.1hz ), but also as fast as 1/1000th of a second ( 1000hz )?

I would suggest you start measuring assuming a long (10 sec) pulse with a scaled 16 bit counter, or maybe 24 bits with the last byte done in software. If you find the pulse is too short to get good resolution you can repeat the measurement with a fast timer or by counting pulses in a known time. Since you now know it is a fast pulse you know it won't take long to repeat the measurement.

I once worked on tide gauges. We said we needed the measurement to be done before our coffee got cold ;-)

:=
:=Any working code snippets would, of course, be greatly welcomed. But any light at all you could cast on this topic would be appreciated.

Pun intended I assume...

:=
:=Thanks,
:=Rollo

___________________________
This message was ported from CCS's old forum
Original Post ID: 13088
Rollo
Guest







Re: 16F877 & measuring pulse width?
PostPosted: Wed Mar 26, 2003 10:54 am     Reply with quote

Thanks for the replies. I had read that thread in my attempt to understand. Based on your suggestion, I have tried that code, with a following modifications only:

1- 16F877 @ 4Mhz.
2- Added LCD and stdio includes and LCD output commands.

I'm very pleased to say that I am getting some output, but it seems both unpredictable in time and very variant in output, even under unchanging low light conditions.

It behaves like this:

a- Normal room lights give a reading of zero.
b- Very dim lights do give a reading, which apprears for the coded 2 seconds, and then the LCD text returns to zeroes.
c- Readings show up intermittantly, sometimes 2 seconds apart, sometimes 16 seconds apart, even tho light level is identical.
d- Here is an example of 10 readings from the Darkometer:

326
270
123
297
52
149
371
153
38
277

When I count pulses on a Basic Stamp 2, this light chip is dead steady within 2\% usually. I also have a laptop version going running off C, and it too is quite steady.

However, astro observers were asking for a standalone model, so I tried a PIC and CCS. I'm almost there, but no cigar.

I wonder what's wrong with the code? Here it is ( based closely on the code you pointed me to. )...

#include <16F877.H>
#device *=16
#fuses XT,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000) //using 4Mhz crystal you'll get 1 us increment
#include <lcd.c>
#INCLUDE <stdlib.h>

long int counter;
int end_counter_ready, enable_counter;


void main()
{
lcd_init();
delay_ms(1000);
printf(lcd_putc, "Pulses= ");
enable_interrupts(INT_EXT);
ext_int_edge(H_to_L);
enable_interrupts(GLOBAL);

while(TRUE)
{
if(end_counter_ready)
{
lcd_gotoxy(1,0);
printf(lcd_putc,"\%05lu", counter);
end_counter_ready = FALSE;
delay_ms(2000);
enable_interrupts(GLOBAL);
}

while(enable_counter)
{
counter++;
}

enable_counter = FALSE;
enable_interrupts(INT_EXT);
}
}


#int_EXT
edge_detect_isr()
{
if(!enable_counter)
{
enable_counter = TRUE;
ext_int_edge(H_to_L);
counter = 0;
}
else
{
enable_counter = FALSE;
end_counter_ready = TRUE;
ext_int_edge(H_to_L);
disable_interrupts(INT_EXT);
}
}


Thanks for your help,
Rol


:=:=In the two weeks since I got my Warp13A and CCS 'C', I've managed to get much going, including an LCD output, an interrupt timer and doing A/D conversions. Much of this can can be directly attributed to the assistance of people on this board. Thanks.
:=:=
:=:=There's just one step left in completing my Astronomy Sky Darkness Sensor, and that's to be able to measure a pulsewidth. I have made a couple of attempts at using the example called EX_CCPMP.c in the examples directory with a PIC16F877, but I've had no success so far.
:=:=
:=:=My questions are the following...
:=:=
:=:=1- Has anyone managed to get EX_CCPMP.c going on a 16F877?
:=:=
:=:=2- Any ideas on how one could measure very long pulsewidths, say, as long as up to 10 seconds ( 0.1hz ), but also as fast as 1/1000th of a second ( 1000hz )?
:=:=
:=:=Any working code snippets would, of course, be greatly welcomed. But any light at all you could cast on this topic would be appreciated.
:=:=
:=:=Thanks,
:=:=Rollo
:=
:=Read this
:= <a href="http://www.pic-c.com/forum/general/posts/12961.html" TARGET="_blank"> <a href="http://www.pic-c.com/forum/general/posts/12961.html" TARGET="_blank">http://www.pic-c.com/forum/general/posts/12961.html</a></a>
___________________________
This message was ported from CCS's old forum
Original Post ID: 13092
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

Re: 16F877 & measuring pulse width?
PostPosted: Wed Mar 26, 2003 12:41 pm     Reply with quote

<font face="Courier New" size=-1>I was thinking of something like this. For your application an interupt does not gain you any performance. The timer is free running and you only need to count overflow by checking the interupt flag. This should yeild measurement resolution of about 5-8 uS. The only errors in accuracy would be while incrementing the overflow counter. With a 16 bit timer the chance of that happening is around 1/16000 and the error is only about 5-8uS.


#include <16F877.H>
// #device *=16
#fuses XT,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000) //using 4Mhz crystal you'll get 1 us increment

int16 overflows_of_timer1;

void main()
{
lcd_init();
delay_ms(1000);
printf(lcd_putc, "Pulses= ");

while(TRUE)
{

While (PIN_B0);
set_timer1(0);
overflows_of_timer1=0;
While (!PIN_B0)
{if(bit_test(byte_address_for_timer1_interupt_flag,Flag_bit))
{bit_clear(byte_address_for_timer1_interupt_flag,Flag_bit);
++overflows_of_timer1;
}
}
Total_time = get_timer1() + (overflows_of_timer1 * (2^16));
Printf ...
delay ...
}
}
</font>
___________________________
This message was ported from CCS's old forum
Original Post ID: 13097
Rollo
Guest







Re: 16F877 & measuring pulse width?
PostPosted: Wed Mar 26, 2003 1:42 pm     Reply with quote

Thanks Neutone. Your code snippet was much appreciated. I looked into the 16F877 pdf file and found that the address of the timer one interrupt flag was 8c bit 0. So I added a #byte with a variable to contain that address. The rest of the code is pretty well what you were suggesting, but for some reason there is no output, except for the words "Pulses =".

I hope I didn't perpetrate a typo. Doesn't look like that approach will work, for this case. The program seems to lock up at the line...

while(PIN_B0);

I am using the same circuit that was generating pulses earlier today on pin B0, so it's not that the pin is not there.


Thanks very much for trying, tho!

Rol


Here's my code ( just in case ):

#include <16F877.H>
#fuses XT,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000) //using 4Mhz crystal you'll get 1 us increment
#include <lcd.c>
#INCLUDE <stdlib.h>
#byte tmr1IF = 0x8c

int16 overflows_of_timer1, total_time;
set_tris_b(1);


void main()
{
lcd_init();
delay_ms(1000);
printf(lcd_putc, "Pulses= ");

while(TRUE)
{

while(PIN_B0);
set_timer1(0);

while(!PIN_B0)
{
if( bit_test(tmr1IF, 0 ) )
{
bit_clear(tmr1IF, 0 );
++overflows_of_timer1;
}
}

total_time = get_timer1() + overflows_of_timer1;

lcd_gotoxy(1,0);
printf(lcd_putc, "\%05lu", total_time );
delay_ms(1000);
}
}


:=<font face="Courier New" size=-1>I was thinking of something like this. For your application an interupt does not gain you any performance. The timer is free running and you only need to count overflow by checking the interupt flag. This should yeild measurement resolution of about 5-8 uS. The only errors in accuracy would be while incrementing the overflow counter. With a 16 bit timer the chance of that happening is around 1/16000 and the error is only about 5-8uS.
:=
:=
:=#include <16F877.H>
:=// #device *=16
:=#fuses XT,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
:=#use delay(clock=4000000) //using 4Mhz crystal you'll get 1 us increment
:=
:=int16 overflows_of_timer1;
:=
:=void main()
:={
:=lcd_init();
:=delay_ms(1000);
:=printf(lcd_putc, "Pulses= ");
:=
:=while(TRUE)
:={
:=
:=While (PIN_B0);
:=set_timer1(0);
:=overflows_of_timer1=0;
:=While (!PIN_B0)
:={if(bit_test(byte_address_for_timer1_interupt_flag,Flag_bit))
:={bit_clear(byte_address_for_timer1_interupt_flag,Flag_bit);
:=++overflows_of_timer1;
:=}
:=}
:=Total_time = get_timer1() + (overflows_of_timer1 * (2^16));
:=Printf ...
:=delay ...
:=}
:=}
:=</font>
___________________________
This message was ported from CCS's old forum
Original Post ID: 13102
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

Re: 16F877 & measuring pulse width?
PostPosted: Wed Mar 26, 2003 2:11 pm     Reply with quote

:=Thanks Neutone. Your code snippet was much appreciated. I looked into the 16F877 pdf file and found that the address of the timer one interrupt flag was 8c bit 0. So I added a #byte with a variable to contain that address. The rest of the code is pretty well what you were suggesting, but for some reason there is no output, except for the words "Pulses =".
:=
:=I hope I didn't perpetrate a typo. Doesn't look like that approach will work, for this case. The program seems to lock up at the line...
:=
:=while(PIN_B0);
:=
:=I am using the same circuit that was generating pulses earlier today on pin B0, so it's not that the pin is not there.
:=
:=
:=Thanks very much for trying, tho!
:=
:=Rol
:=
:=
:=Here's my code ( just in case ):
:=
:=#include <16F877.H>
:=#fuses XT,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
:=#use delay(clock=4000000) //using 4Mhz crystal you'll get 1 us increment
:=#include <lcd.c>
:=#INCLUDE <stdlib.h>
:=#byte tmr1IF = 0x8c
:=
:=int16 overflows_of_timer1, total_time;
:=set_tris_b(1);
:=
:=
:=void main()
:={
:= lcd_init();
:= delay_ms(1000);
:= printf(lcd_putc, "Pulses= ");
:=
:= while(TRUE)
:= {
:=
:= while(PIN_B0);
:= set_timer1(0);
:=
:= while(!PIN_B0)
:= {
:= if( bit_test(tmr1IF, 0 ) )
:= {
:= bit_clear(tmr1IF, 0 );
:= ++overflows_of_timer1;
:= }
:= }
:=
:= total_time = get_timer1() + overflows_of_timer1;
:=
:= lcd_gotoxy(1,0);
:= printf(lcd_putc, "\%05lu", total_time );
:= delay_ms(1000);
:= }
:=}
:=
:=
:=:=<font face="Courier New" size=-1>I was thinking of something like this. For your application an interupt does not gain you any performance. The timer is free running and you only need to count overflow by checking the interupt flag. This should yeild measurement resolution of about 5-8 uS. The only errors in accuracy would be while incrementing the overflow counter. With a 16 bit timer the chance of that happening is around 1/16000 and the error is only about 5-8uS.
:=:=
:=:=
:=:=#include <16F877.H>
:=:=// #device *=16
:=:=#fuses XT,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
:=:=#use delay(clock=4000000) //using 4Mhz crystal you'll get 1 us increment
:=:=
:=:=int16 overflows_of_timer1;
:=:=
:=:=void main()
:=:={
:=:=lcd_init();
:=:=delay_ms(1000);
:=:=printf(lcd_putc, "Pulses= ");
:=:=
:=:=while(TRUE)
:=:={
:=:=
:=:=While (PIN_B0);
:=:=set_timer1(0);
:=:=overflows_of_timer1=0;
:=:=While (!PIN_B0)
:=:={if(bit_test(byte_address_for_timer1_interupt_flag,Flag_bit))
:=:={bit_clear(byte_address_for_timer1_interupt_flag,Flag_bit);
:=:=++overflows_of_timer1;
:=:=}
:=:=}
:=:=Total_time = get_timer1() + (overflows_of_timer1 * (2^16));
:=:=Printf ...
:=:=delay ...
:=:=}
:=:=}
:=:=</font>

My mistake its

while ( !input(PIN_B1) );

not

while ( !PIN_B1 );
___________________________
This message was ported from CCS's old forum
Original Post ID: 13105
Rollo
Guest







Re: 16F877 & measuring pulse width?
PostPosted: Wed Mar 26, 2003 5:37 pm     Reply with quote

while ( !input(PIN_B1) );

That's what I thought. Unfortunately, even when I make the changes to use the input command, there are no pulses getting red. Something else seems awry. I'll keep plugging at it and will post a solution if I come across one.

Thanks again,
Rol


:=:=Thanks Neutone. Your code snippet was much appreciated. I looked into the 16F877 pdf file and found that the address of the timer one interrupt flag was 8c bit 0. So I added a #byte with a variable to contain that address. The rest of the code is pretty well what you were suggesting, but for some reason there is no output, except for the words "Pulses =".
:=:=
:=:=I hope I didn't perpetrate a typo. Doesn't look like that approach will work, for this case. The program seems to lock up at the line...
:=:=
:=:=while(PIN_B0);
:=:=
:=:=I am using the same circuit that was generating pulses earlier today on pin B0, so it's not that the pin is not there.
:=:=
:=:=
:=:=Thanks very much for trying, tho!
:=:=
:=:=Rol
:=:=
:=:=
:=:=Here's my code ( just in case ):
:=:=
:=:=#include <16F877.H>
:=:=#fuses XT,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
:=:=#use delay(clock=4000000) //using 4Mhz crystal you'll get 1 us increment
:=:=#include <lcd.c>
:=:=#INCLUDE <stdlib.h>
:=:=#byte tmr1IF = 0x8c
:=:=
:=:=int16 overflows_of_timer1, total_time;
:=:=set_tris_b(1);
:=:=
:=:=
:=:=void main()
:=:={
:=:= lcd_init();
:=:= delay_ms(1000);
:=:= printf(lcd_putc, "Pulses= ");
:=:=
:=:= while(TRUE)
:=:= {
:=:=
:=:= while(PIN_B0);
:=:= set_timer1(0);
:=:=
:=:= while(!PIN_B0)
:=:= {
:=:= if( bit_test(tmr1IF, 0 ) )
:=:= {
:=:= bit_clear(tmr1IF, 0 );
:=:= ++overflows_of_timer1;
:=:= }
:=:= }
:=:=
:=:= total_time = get_timer1() + overflows_of_timer1;
:=:=
:=:= lcd_gotoxy(1,0);
:=:= printf(lcd_putc, "\%05lu", total_time );
:=:= delay_ms(1000);
:=:= }
:=:=}
:=:=
:=:=
:=:=:=<font face="Courier New" size=-1>I was thinking of something like this. For your application an interupt does not gain you any performance. The timer is free running and you only need to count overflow by checking the interupt flag. This should yeild measurement resolution of about 5-8 uS. The only errors in accuracy would be while incrementing the overflow counter. With a 16 bit timer the chance of that happening is around 1/16000 and the error is only about 5-8uS.
:=:=:=
:=:=:=
:=:=:=#include <16F877.H>
:=:=:=// #device *=16
:=:=:=#fuses XT,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
:=:=:=#use delay(clock=4000000) //using 4Mhz crystal you'll get 1 us increment
:=:=:=
:=:=:=int16 overflows_of_timer1;
:=:=:=
:=:=:=void main()
:=:=:={
:=:=:=lcd_init();
:=:=:=delay_ms(1000);
:=:=:=printf(lcd_putc, "Pulses= ");
:=:=:=
:=:=:=while(TRUE)
:=:=:={
:=:=:=
:=:=:=While (PIN_B0);
:=:=:=set_timer1(0);
:=:=:=overflows_of_timer1=0;
:=:=:=While (!PIN_B0)
:=:=:={if(bit_test(byte_address_for_timer1_interupt_flag,Flag_bit))
:=:=:={bit_clear(byte_address_for_timer1_interupt_flag,Flag_bit);
:=:=:=++overflows_of_timer1;
:=:=:=}
:=:=:=}
:=:=:=Total_time = get_timer1() + (overflows_of_timer1 * (2^16));
:=:=:=Printf ...
:=:=:=delay ...
:=:=:=}
:=:=:=}
:=:=:=</font>
:=
:=My mistake its
:=
:=while ( !input(PIN_B1) );
:=
:=not
:=
:=while ( !PIN_B1 );
___________________________
This message was ported from CCS's old forum
Original Post ID: 13112
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

Re: 16F877 & measuring pulse width?
PostPosted: Thu Mar 27, 2003 10:54 am     Reply with quote

I was was looking at the code and thinking that use of fast IO was an assumption I had made but not said. With fast IO the TRIS regester must be set for each port pin.
___________________________
This message was ported from CCS's old forum
Original Post ID: 13146
Rollo
Guest







Re: 16F877 & measuring pulse width?
PostPosted: Thu Mar 27, 2003 11:13 am     Reply with quote

Thanks for your continuing good suggestions. I played with the CCPMP.c code in the examples directory, and changed it so as to measure timer1 clicks elapsed from one L_to_H to the next L_to_H. On a 4Mhz clock, I figure each tick is therefore 1 usec --(clock/4). To get hertz from pulse period, I figure I have to go... 1/ pulse_width in seconds. So, for example, with 500 usec, I would need to calculate: 1/0.0005 = 2000hz

I'm still testing quite a bit. Something isn't quite right, but at least I'm getting readings that seem to flow in the correct direction.

I'm really having trouble outputting any floats with printf -- is there some kind of bug? That's why I'm having to do the weird approximative math in there, before outputting hz. Will repost this interrupt solution once it get it going more accurately.

Thanks again,
Rol


#include <16F877.h>
#FUSES XT,NOWDT,NOPROTECT,NOLVP,PUT,NOBROWNOUT
#use delay(clock=4000000)
#include <lcd.c>
#INCLUDE <stdlib.h>

long rise,rise2,pulse_width, hertz;

int1 flag=1;

#int_ccp2
void isr() {

if(flag)
{
rise = CCP_1;// CCP_1 is the time the pulse went high
flag=0;
}

else
{
rise2=CCP_2;// CCP_2 is the next time the pulse went high again
flag=1;
}

// pulse_width/(clock/4) is the time elapsed


}


set_tris_D(0);

main() {

lcd_init();

setup_ccp1(CCP_CAPTURE_RE); // Configure CCP1 to capture rise
setup_ccp2(CCP_CAPTURE_RE); // Configure CCP2 to capture fall
setup_timer_1(T1_INTERNAL); // Start timer 1

enable_interrupts(INT_CCP2); // Setup interrupt on falling edge
enable_interrupts(GLOBAL);


while(TRUE) {

delay_ms(500);

disable_interrupts(INT_CCP2);
if ( rise > rise2 ) {
pulse_width = rise - rise2;
}
else {
pulse_width = rise2 - rise;
}

printf(lcd_putc, "\%05lu us ", pulse_width ); // @ 4Mhz clock, 1 TMR1 tik = 1usec ?
delay_ms(1000);
hertz = 10000 / ( pulse_width/100); // hertz = 1/time for one pulse. approx int16 range?
printf(lcd_putc, "\%05lu Hz ", hertz );
delay_ms(1000);
enable_interrupts(INT_CCP2);


}
}


:=I was was looking at the code and thinking that use of fast IO was an assumption I had made but not said. With fast IO the TRIS regester must be set for each port pin.
___________________________
This message was ported from CCS's old forum
Original Post ID: 13148
Rollo
Guest







Re: 16F877 & measuring pulse width?
PostPosted: Thu Mar 27, 2003 11:18 am     Reply with quote

Strange, the include directives in my code did not show up in the copy/paste. They are <lcd.c> and <stdio.c> In case anyone cares... ;-)

Thanks,
Rol



:=Thanks for your continuing good suggestions. I played with the CCPMP.c code in the examples directory, and changed it so as to measure timer1 clicks elapsed from one L_to_H to the next L_to_H. On a 4Mhz clock, I figure each tick is therefore 1 usec --(clock/4). To get hertz from pulse period, I figure I have to go... 1/ pulse_width in seconds. So, for example, with 500 usec, I would need to calculate: 1/0.0005 = 2000hz
:=
:=I'm still testing quite a bit. Something isn't quite right, but at least I'm getting readings that seem to flow in the correct direction.
:=
:=I'm really having trouble outputting any floats with printf -- is there some kind of bug? That's why I'm having to do the weird approximative math in there, before outputting hz. Will repost this interrupt solution once it get it going more accurately.
:=
:=Thanks again,
:=Rol
:=
:=
:=#include <16F877.h>
:=#FUSES XT,NOWDT,NOPROTECT,NOLVP,PUT,NOBROWNOUT
:=#use delay(clock=4000000)
:=#include <lcd.c>
:=#INCLUDE <stdlib.h>
:=
:=long rise,rise2,pulse_width, hertz;
:=
:=int1 flag=1;
:=
:=#int_ccp2
:=void isr() {
:=
:= if(flag)
:= {
:= rise = CCP_1;// CCP_1 is the time the pulse went high
:= flag=0;
:= }
:=
:= else
:= {
:= rise2=CCP_2;// CCP_2 is the next time the pulse went high again
:= flag=1;
:= }
:=
:= // pulse_width/(clock/4) is the time elapsed
:=
:=
:=}
:=
:=
:=set_tris_D(0);
:=
:=main() {
:=
:= lcd_init();
:=
:= setup_ccp1(CCP_CAPTURE_RE); // Configure CCP1 to capture rise
:= setup_ccp2(CCP_CAPTURE_RE); // Configure CCP2 to capture fall
:= setup_timer_1(T1_INTERNAL); // Start timer 1
:=
:= enable_interrupts(INT_CCP2); // Setup interrupt on falling edge
:= enable_interrupts(GLOBAL);
:=
:=
:= while(TRUE) {
:=
:= delay_ms(500);
:=
:= disable_interrupts(INT_CCP2);
:= if ( rise > rise2 ) {
:= pulse_width = rise - rise2;
:= }
:= else {
:= pulse_width = rise2 - rise;
:= }
:=
:= printf(lcd_putc, "\%05lu us ", pulse_width ); // @ 4Mhz clock, 1 TMR1 tik = 1usec ?
:= delay_ms(1000);
:= hertz = 10000 / ( pulse_width/100); // hertz = 1/time for one pulse. approx int16 range?
:= printf(lcd_putc, "\%05lu Hz ", hertz );
:= delay_ms(1000);
:= enable_interrupts(INT_CCP2);
:=
:=
:= }
:=}
:=
:=
:=:=I was was looking at the code and thinking that use of fast IO was an assumption I had made but not said. With fast IO the TRIS regester must be set for each port pin.
___________________________
This message was ported from CCS's old forum
Original Post ID: 13149
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

Re: 16F877 & measuring pulse width?
PostPosted: Thu Mar 27, 2003 11:51 am     Reply with quote

1=in
0=out

This sets all port d pins to input.

#use fast_io (D)
set_tris_D(0xFF);
___________________________
This message was ported from CCS's old forum
Original Post ID: 13152
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