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

ccp Questions

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



Joined: 11 Jun 2005
Posts: 38

View user's profile Send private message

ccp Questions
PostPosted: Thu Jun 30, 2005 2:16 am     Reply with quote

i am doing rpm counter and i am using cpp metode

#INT_CCP1
ccp1_isr()
{

Value=CCP_1-oldValue;
oldValue=CCP_1;
gotCCP1 = TRUE;
}

void main()
{

float freq;
char i;
Value=0;
oldValue=0;
gotCCP1 = TRUE;

setup_ccp1(CCP_CAPTURE_RE); // CCP1 - rising edge
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);// Timer1 interrupt
enable_interrupts(INT_CCP1);
enable_interrupts(GLOBAL);

set_tris_C(0xAF); // All inputs except C4 and C6

while(TRUE) { // Start main program loop (endless)

while(!gotCCP1) // when is false stop and return 0.
{
Value=0;


}

freq=1.0/((float)Value*2e-6);
printf("Freq%f\r\n",freq);

gotCCP1 = FALSE;

}// while
}


but when i dont input signal the the output insn' t 0 but sametime the frequency sametime 0 !
there is sameone that can help me ?
how i can know when cpp interput is not used ?
thanks
Haplo



Joined: 06 Sep 2003
Posts: 659
Location: Sydney, Australia

View user's profile Send private message

PostPosted: Thu Jun 30, 2005 3:25 am     Reply with quote

How is the variable 'value' defined? If the timer overflows between two rising edges (which it will), the line 'Value=CCP_1-oldValue;' may result in an incorrect value.
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Jun 30, 2005 4:08 am     Reply with quote

You have forgotten to clear the CCP1 interrupt before you enabled it. The interrup flag may already be set which means you will have an interrupt event occur immediately the interrupt is enabled. In this case the first reading is rubbish..

Also you are fighting your own interrupt handler with value being set in the mainline and in the interrupt handler. This is why you are getting silly values. I suspect what you meant to do was:

Code:

while(TRUE) { // Start main program loop (endless)

     while(!gotCCP1) // when is false stop and return 0.
          ;

      disable_interrupt(INT_CCP1);
      freq=1.0/((float)Value*2e-6);
      gotCCP1 = FALSE;
      enable_interrupt(INT_CCP1);
      printf("Freq%f\r\n",freq);
      }// while
}

_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
ferrarilib



Joined: 11 Jun 2005
Posts: 38

View user's profile Send private message

PostPosted: Thu Jun 30, 2005 4:12 am     Reply with quote

int16 Value,oldValue ;

but i don't undestand .

can you do example how works ?
thanks
ferrarilib



Joined: 11 Jun 2005
Posts: 38

View user's profile Send private message

PostPosted: Thu Jun 30, 2005 4:26 am     Reply with quote

the problem is that when i dont have more interrupt the count stop

i have thy this too

while(TRUE) { // Start main program loop (endless)




disable_interrupts(INT_CCP1);
freq=1.0/((float)Value*2e-6);
gotCCP1 = FALSE;

enable_interrupts(INT_CCP1);
printf("Freq%f\r\n",freq);

}

but when the frequency is 0 reurrn always the last valure
Confused
Ttelmah
Guest







PostPosted: Thu Jun 30, 2005 4:35 am     Reply with quote

I'd say the key problem is here:
Code:

while(!gotCCP1) // when is false stop and return 0.
     {
     Value=0;
     }


The problem is that lines of code take _time_.
Now imagine that you are sitting in this loop. The entire loop probably takes about 6 instructions. Immediately after the instruction testing for gotCCP being false, gotCCP goes true. The code will still execute the section corresponding to 'false' (it was false when tested...), and will _clear_ the value. Then on the next test, gotCCP is seen as 'true', and the code passes to the 'print', with a zero value...
Change the logic.
Use something like:
Code:

if (gotCCP) {
   freq=1.0/((float)Value*2e-6);
   printf("Freq%f\r\n",freq);
   gotCCP1 = FALSE;
}

If you want to print something when gotCCP is not true, then simply add an 'else', and print a message. Don't clear value.

Best Wishes
ferrarilib



Joined: 11 Jun 2005
Posts: 38

View user's profile Send private message

PostPosted: Thu Jun 30, 2005 5:23 am     Reply with quote

Ttelmah wrote:
I'd say the key problem is here:
Code:

while(!gotCCP1) // when is false stop and return 0.
     {
     Value=0;
     }


The problem is that lines of code take _time_.
Now imagine that you are sitting in this loop. The entire loop probably takes about 6 instructions. Immediately after the instruction testing for gotCCP being false, gotCCP goes true. The code will still execute the section corresponding to 'false' (it was false when tested...), and will _clear_ the value. Then on the next test, gotCCP is seen as 'true', and the code passes to the 'print', with a zero value...
Change the logic.
Use something like:
Code:

if (gotCCP) {
   freq=1.0/((float)Value*2e-6);
   printf("Freq%f\r\n",freq);
   gotCCP1 = FALSE;
}

If you want to print something when gotCCP is not true, then simply add an 'else', and print a message. Don't clear value.

Best Wishes


thanks !

But i have tired this too:
while(TRUE) { // Start main program loop (endless)


//val=get_timer1()-old;
//old=get_timer1();

if(gotCCP1)
{


freq=1.0/((float)Value*2e-6);
printf("Freq%f\r\n",freq);
gotCCP1 = FALSE;
}
else
{

printf("Freq%f\r\n",mio);
}


}// while

where mio =0;

and return

Freq34.435260\0D

Freq.000000\0D (why is 0 ?)

Freq.000000\0D (why is 0 ?)
Freq34.435260\0D
when capture and when not capture is good !

Freq.000000\0D
Freq.000000\0D
Freq.000000\0D

Crying or Very sad
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Jun 30, 2005 5:39 am     Reply with quote

Do this and tell us the results

Code:

if(gotCCP1)
   {
   disable_interrupt(INT_CCP1) // MUST DO THIS 
   freq=1.0/((float)Value*2e-6);
   enable_interrupt(INT_CCP1) // MUST DO THIS 
   printf("Here at A - Freq%f\r\n",freq);
   gotCCP1 = FALSE;
   }
else
   {
   printf("Here at B Freq%f\r\n",mio);
   }

_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Ttelmah
Guest







PostPosted: Thu Jun 30, 2005 6:00 am     Reply with quote

I think I'd clear gotCCP, before re-anabling the interrupt. This woul allow it to again 'log' an edge that occured during the print time.

Best Wishes
ferrarilib



Joined: 11 Jun 2005
Posts: 38

View user's profile Send private message

PostPosted: Thu Jun 30, 2005 6:08 am     Reply with quote

asmallri wrote:
Do this and tell us the results

Code:

if(gotCCP1)
   {
   disable_interrupt(INT_CCP1) // MUST DO THIS 
   freq=1.0/((float)Value*2e-6);
   enable_interrupt(INT_CCP1) // MUST DO THIS 
   printf("Here at A - Freq%f\r\n",freq);
   gotCCP1 = FALSE;
   }
else
   {
   printf("Here at B Freq%f\r\n",mio);
   }


capture :
ere at B Freq .000000 ( ? )\0D
\0A
Here at B Freq .000000 ( ?)\0D
\0A
Here at A - Freq34.435260\0D
\0A
Here at B Freq .000000\0D (?)

i think that afther do last instruction go to while (TRUE) and restart another without take valure from interrupts !
i must insert a delay time because the frequency captured is low !
and the interrupt dont have time for set variable . Confused

so works fine :

while(TRUE) { // Start main program loop (endless)

delay_ms (100); this permit wait interrupt

if(gotCCP1)
{
//disable_interrupts(INT_CCP1); // MUST DO THIS don 't cange nothing in output
freq=1.0/((float)Value*2e-6);
// enable_interrupts(INT_CCP1); // MUST DO THIS
printf("Here at A - Freq%f\r\n",freq);
gotCCP1 = FALSE;
}
else
{
printf("Here at B Freq%f\r\n",mio);
}

}// while

now i must set 2e-6

i have 8000000 clock and do 2000000 of cicle so i think that is correct do

freq=1.0/((float)Value*2e-6); ? is good ?

Smile thanks
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Jun 30, 2005 6:46 am     Reply with quote

Ttelmah wrote:
I think I'd clear gotCCP, before re-anabling the interrupt. This woul allow it to again 'log' an edge that occured during the print time.

Best Wishes


Definately - my brain was out of gear :-)
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!


Last edited by asmallri on Thu Jun 30, 2005 7:11 am; edited 1 time in total
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Jun 30, 2005 6:59 am     Reply with quote

If you are going to use interrupts then you MUST leave the enable and disable statements in place. Interrupts WILL corrupt the results, maybe not now, maybe not tomorrow, but it is as sure as night follows day.

Code:

while(TRUE) { // Start main program loop (endless)

// the following line is not required unless for some reason you want multiple interrupts to occur
// delay_ms (100);       this permit wait interrupt

if(gotCCP1)
   {
   disable_interrupts(INT_CCP1); // MUST DO THIS   don 't cange nothing in output
   freq=1.0/((float)Value*2e-6);
   gotCCP1 = FALSE; 
   enable_interrupts(INT_CCP1); // MUST DO THIS 
   printf("Here at A - Freq%f\r\n",freq);

   }
else
   {
   // I don't know why the following line is here as no interrupt
   // will have occurred to change anything from last reading
   // printf("Here at B Freq%f\r\n",mio);
   }

}// while



Quote:

now i must set 2e-6

i have 8000000 clock and do 2000000 of cicle so i think that is correct do

freq=1.0/((float)Value*2e-6); ? is good ?

Smile thanks


I don't understand the question.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
ferrarilib



Joined: 11 Jun 2005
Posts: 38

View user's profile Send private message

PostPosted: Thu Jun 30, 2005 7:16 am     Reply with quote

asmallri wrote:
If you are going to use interrupts then you MUST leave the enable and disable statements in place. Interrupts WILL corrupt the results, maybe not now, maybe not tomorrow, but it is as sure as night follows day.

Code:

while(TRUE) { // Start main program loop (endless)

// the following line is not required unless for some reason you want multiple interrupts to occur
// delay_ms (100);       this permit wait interrupt

if(gotCCP1)
   {
   disable_interrupts(INT_CCP1); // MUST DO THIS   don 't cange nothing in output
   freq=1.0/((float)Value*2e-6);
   gotCCP1 = FALSE; 
   enable_interrupts(INT_CCP1); // MUST DO THIS 
   printf("Here at A - Freq%f\r\n",freq);

   }
else
   {
   // I don't know why the following line is here as no interrupt
   // will have occurred to change anything from last reading
   // printf("Here at B Freq%f\r\n",mio);
   }

}// while



Quote:

now i must set 2e-6

i have 8000000 clock and do 2000000 of cicle so i think that is correct do

freq=1.0/((float)Value*2e-6); ? is good ?

Smile thanks


I don't understand the question.

?
you tell to me that if i am mesure the frequency with period is not stable ?
Confused

my question is now i have clock pic to 8Mhz
and i must know frequency in hz
f=1/T ---> T= period

freq=1.0/((float)Value*2e-6);

2e-6 is the factor for have frequency in hz Rolling Eyes
Ttelmah
Guest







PostPosted: Thu Jun 30, 2005 3:17 pm     Reply with quote

What is the likely range of input frequencies involved?.
Remember that Timer1, is only a 16bit counter, so the maximum interval between clock edges that can be handled by the approach you are using here, corresponds to just over 30Hz (at 8MHz). If your frequency drops below this, you really need to add a timer1 interrupt, and increment a 'carry' bit, and use 32bit values for the count.
Conversely, if the frequency is relatively high, there will be significant 'jitter' in the measurement. If (for example), the time is about 0.1mSec/cycle, unless the clock is synchronous to the internal processor clock, values will jump between perhaps 199,and 201 counts, and the frequency measure will show about 1% fluctuation, even if the clock is perfectly stable.
Something seems to be 'screwy' about your maths.
As shown, a frequency of 10000Hz, will give counts around 200, and should be converted, by using:
freq=2E6/Value;
For the same count value, your conversion would give:
1/(200*2E-6) = 2500...
The single division will also need less maths time.

Best Wishes
ferrarilib



Joined: 11 Jun 2005
Posts: 38

View user's profile Send private message

PostPosted: Fri Jul 01, 2005 12:36 pm     Reply with quote

thanks now i undastand and my project start go on .. Razz
yes i have implement with timer1 (#INT_TIMER1) so i have carry bite. and i have used union variable for do it to 32 bit.



I have resolve the problem whitout delay but with

if(period>2000000)
{
period=0;

}
in the CCP1 function (interrupts) so dont give to me error

and all is good now. So when the cicle is down 2000000 (1hz) the counter give to me 0.
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