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 CCS Technical Support

CCP1 and Time1 Interrupt : calculate RPM

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



Joined: 22 Dec 2004
Posts: 78

View user's profile Send private message

CCP1 and Time1 Interrupt : calculate RPM
PostPosted: Thu Jul 13, 2006 8:39 pm     Reply with quote

Hi...After having passed through very bad time I have solved this problem. As I got clue from this forum but that code was not working perfect for me. I think to post it so it can be useful for other like me.

I am calculating RPM using CCP1 and Timer1 interrupt. In the case when timer1 and CCP1 occur almost same time then it was calculating wrong RPM.

As this calculations are little bit different than http://www.ccsinfo.com/forum/viewtopic.php?t=22403 and http://www.ccsinfo.com/forum/viewtopic.php?t=906

I am posting my code here:

Code:




#CASE
#include <18F452>
#fuses H4, NOWDT, NOLVP, BROWNOUT, BORV42, PUT, PROTECT, NOCPD, STVREN, NOWRT, NOWRTD, NOWRTC, NOWRTB, EBTR, NOCPB, EBTRB, NODEBUG
#use delay(clock=40000000)

#include <stdlib>
 

#byte PIR1 = 0x0F9E

//#bit TMR1IF = 0x0F9E.0
//#bit CCP1IF = 0x0F9E.2

unsigned int16 NewRPM=0;
unsigned int16  temptimer1=0,tempcount1=0;
int1 isCCP1=0;
unsigned int16 counttimer1=0;
unsigned int16  temptimer1_1=0,tempcount1_1=0;
unsigned int32 TimerCycle=0;




#int_ccp1
void CCP1_isr()
{      

//When ever CCP1 interrupt occur it will copy the timer1 value to CCP_1 register.
//But in the situation when timer1 overflow happen at almost same time when CCP1
//interrupt occur.

 if(bit_test(PIR1,0)) //TMR1IF
   {

//Here there are two possibilities for CCP_1 value. One is CCP_1 value is
//achieved before timer1 overflow(example: CCP_1=65530 and get_timer1() = 5).
//Second is CCP_1 value achieved after timer1 overflow.(example: CCP_1 = 2 and
//get_timer1= 5)


//If we want high accuracy then use this code.
/*
        if(get_timer1() < CCP_1)
      {
          temptimer1 = CCP_1;
      }
      else
      {
          temptimer1 = 0;
            counttimer1++;
      }
*/

//If we don't want high accuracy then use this code....Here we ignore some count of
//CCP_1. example: if CCP_1=65530 or CCP_1=4 in both the cases we are increamenting
//counttimer1 and take temptimer1=0;

         temptimer1 = 0;
         counttimer1++;




         tempcount1 = counttimer1; 

   }
   else
   {
      //If timer1 interrupt does not occur when CCP1 occur.
      temptimer1 = CCP_1;

         tempcount1 = counttimer1;

   }

      
      set_timer1(0);
         
    counttimer1=0;


   if(isCCP1==0)
   {
         temptimer1_1 = temptimer1;
         tempcount1_1 = tempcount1;       
   }



    isCCP1=1;

//This is because in the case when timer1 overflow occur after executing code from above
//else loop then clear TIMER1IF interrupt. We can do this because we are setting timer1 zero
//every time. i.e. set_timer1(0).

    bit_clear(PIR1,0);
   
}//#int_ccp1   
 
#INT_TIMER1                       
void timer1_isr() {               

//Here again same like above:
//Here there are two possibilities for CCP_1 value.

//CCP1IF

   if(bit_test(PIR1 ,2) && (get_timer1() < CCP_1)) 

   {
/*
One is CCP_1 value is achieved before timer1 overflow(example: CCP_1=65530 and get_timer1() = 5).   
Then we will use CCP_1 and counttimer1 will not be increamented.
*/
   
   }   
   else
   {
/*
There are two situations here:
(1) Second is CCP_1 value achieved after timer1 overflow.(example: CCP_1 = 2 and get_timer1= 5)
(2) Normal or regular timer1 overflow interrupt when no ccp1 interrupt occur.
*/
      counttimer1++;
   }

 
}//#INT_TIMER1



As my code does not displaying proper, I have slpit in two parts.
prayami



Joined: 22 Dec 2004
Posts: 78

View user's profile Send private message

PostPosted: Fri Jul 14, 2006 4:04 pm     Reply with quote

Code:





void main() {

   set_tris_a(0x01);
   set_tris_b(0x00);
   set_tris_d(0x00);
   set_tris_c(0x9F);
   set_tris_e(0x00);      

   output_high(PIN_E0);
   output_high(PIN_E1);
       
     //setup_ccp1(CCP_CAPTURE_RE);   

    setup_ccp1(CCP_CAPTURE_DIV_4);
     
     setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);   
     set_timer1(0);
            
 
     enable_interrupts(INT_TIMER1);
     enable_interrupts(INT_CCP1);   

     enable_interrupts(GLOBAL);
 
                      
      output_low(PIN_A1);
       output_low(PIN_A2);
       output_low(PIN_A3);
       output_low(PIN_A4);
       output_low(PIN_A5);   
      
       output_low(PIN_D0);      
       output_low(PIN_D1);
       output_low(PIN_D2);
       output_low(PIN_D3);
       output_low(PIN_D5);


   NewRPM=0;

            
  while(TRUE) {


//-----------Start CCP1---------------------------
   if(isCCP1==1)
   {


        TimerCycle = make32(tempcount1_1,temptimer1_1);


     //Devide by 4 because : CCP_CAPTURE_DIV_4
        TimerCycle = TimerCycle/4;
               
         if(TimerCycle > 0)
         {
               NewRPM = (unsigned int16)(600000000.0/((float)TimerCycle) );           
         }
         else
         {
               NewRPM = 0;           
         }



   isCCP1=0;

   /*
   RPM = 60/(TimerCycle*Time for One Intruction Cycle*Timer Prescaler)
   RPM = 60/(TimerCycle*0.2us)
   */


   }//if(isCCP1==1)

//-----------End CCP1---------------------------


     
  }
 
}

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