![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
mitsaras
Joined: 24 Nov 2008 Posts: 9
|
Time period counter using PIC16F819 |
Posted: Tue Jan 06, 2009 6:01 am |
|
|
Hello,
first of all I would like to say many thanks to the people that helped me so far. It is really good to know that there is somebody to help you when you stuck and there is no way to continue, so once again many thanks
My task is to generate a c-code in order to calculate the input time period from a square wave signal. Based on that time period a square-wave in the output is then produced.
The code for that is given below:
Code:
Code: |
#include <16F819.H>
#fuses NOWDT, NOPROTECT, NOLVP,INTRC_IO, NOPUT, NOMCLR,NOBROWNOUT, NOCPD, NOWRT, NODEBUG
#use delay(clock=4000000)
// This global variable holds the time interval
// between two consecutive rising edges of the
// input signal.
int16 isr_ccp_delta;
// When a rising edge occurs on the input signal,
// the CCP1 will 'capture' the value of Timer1
// at that moment. Shortly after that, a CCP1
// interrupt is generated and the following isr
// is called. In the isr, we read the 'captured'
// value of Timer1. We then subtract from it the
// Timer1 value that we 'captured' in the previous
// interrupt. The result is the time interval
// between two rising edges of the input signal.
// This time interval is then converted to a frequency
// value by code in main().
#int_ccp1
void ccp1_isr(void)
{
int16 current_ccp;
static int16 old_ccp = 0;
// Read the 16-bit hardware CCP1 register
current_ccp = CCP_1; // From 16F819.H file
// Calculate the time interval between the
// previous rising edge of the input waveform
// and the current rising edge. Put the result
// in a global variable, which can be read by
// code in main().
isr_ccp_delta = current_ccp - old_ccp;
// Save the current ccp value for the next pass.
old_ccp = current_ccp;
}
//=======================
void main()
{
int16 current_ccp_delta;
setup_oscillator(OSC_4MHZ); //use internal 4MHz clock
// Setup Timer1 and CCP1 for Capture mode so that
// we can measure the input signal's frequency.
// The input signal comes from an external function
// generator, which is connected to the CCP1 pin with a wire.
set_timer1(0);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
setup_ccp1(CCP_CAPTURE_RE);
// Clear the CCP1 interrupt flag before we enable
// CCP1 interrupts, so that we don't get an unwanted
// immediate interrupt (which might happen).
clear_interrupt(INT_CCP1);
enable_interrupts(INT_CCP1);
enable_interrupts(GLOBAL);
while(1)
{
// Get a local copy of the latest ccp delta from the isr.
// We have to disable interrupts when we read a global
// isr variable that is larger than a single byte.
disable_interrupts(GLOBAL);
current_ccp_delta = isr_ccp_delta;
enable_interrupts(GLOBAL);
//The output pin is pin number 10, PIN_RB4
//Once we know the time (period) between two rising edges (current_ccp_delta)
//then in the output a square wave is produced.
//the square wave in the ouput has Ton and Toff time related to the period
//So if the period is e.g. 0.05s or in 16-bit -> 50000 then the
// Ton = Toff = 10000us
if (current_ccp_delta > 60975 && current_ccp_delta < 64516)
do {
output_high(PIN_B4);
delay_us(25000);
output_low(PIN_B4);
delay_us(25000);
}
while (TRUE);
else if (current_ccp_delta > 57142 && current_ccp_delta < 60975)
do {
output_high(PIN_B4);
delay_us(20000);
output_low(PIN_B4);
delay_us(20000);
}
while (TRUE);
else if (current_ccp_delta > 54347 && current_ccp_delta < 57142)
do {
output_high(PIN_B4);
delay_us(15000);
output_low(PIN_B4);
delay_us(15000);
}
while (TRUE);
else if (current_ccp_delta > 51282 && current_ccp_delta < 54347)
do {
output_high(PIN_B4);
delay_us(12000);
output_low(PIN_B4);
delay_us(12000);
}
while (TRUE);
else if (current_ccp_delta > 49019 && current_ccp_delta < 51282)
do {
output_high(PIN_B4);
delay_us(10000);
output_low(PIN_B4);
delay_us(10000);
}
while (TRUE);
else if (current_ccp_delta > 46511 && current_ccp_delta < 49019)
do {
output_high(PIN_B4);
delay_us(8000);
output_low(PIN_B4);
delay_us(8000);
}
while (TRUE);
else if (current_ccp_delta < 46511)
do {
output_high(PIN_B4);
delay_us(100);
output_low(PIN_B4);
delay_us(100);
}
while (TRUE);
}
} | The code calculates the time between the two rising edges of the input signal (period) and then on pin 10 or PIN_RB4 a square wave is produced.
The "Ton" and "Toff" time is the same and related to the period or the time between the two rising edges.
To test that code I used as an input a 20Hz square-wave signal produced from a function generator. Nevertheless, no matter what time period I use the output square wave have Ton and Toff fixed to 100us. Is it possible to have a look at that?
Also I am using PIC16F819. Could you please tell me if the input signal goes to pin 8 or pin 9 ?
Many thanks in advance. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jan 06, 2009 1:38 pm |
|
|
To debug the problem, get rid of all your if-else statements and replace
them with one printf statement. Print the value of current_ccp_delta so
that you know what it is. Use "%lu" in printf to display an unsigned
16-bit variable.
Also, you don't need to post a new thread on your project every day.
If you have other problems with capturing the frequency of an input
waveform, tomorrow or next week, post them in this same thread. |
|
![](templates/subSilver/images/spacer.gif) |
mitsaras
Joined: 24 Nov 2008 Posts: 9
|
Time period counter using PIC16F819 |
Posted: Tue Jan 06, 2009 4:28 pm |
|
|
Thank you, I will try that.
!!!!! |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|