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

2 CCPs conflict

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
J.H.Sun



Joined: 27 Jun 2011
Posts: 4

View user's profile Send private message

2 CCPs conflict
PostPosted: Mon Jun 27, 2011 11:17 pm     Reply with quote

Dear all, I want to ask for help that the PIC18 used to receive and calculate the tachometer signal and also used to get the signal from remote controller (flight). So CCP1 is for remote controller(low:20ms, high:1ms), CCP2 is for tachometer. Here is the problem I am curious:
1. The code can not calculate the CCP1.
2. Even I once let CCP1 run, but it does not calculate properly.
3. How could I solve the conflict between multi-interrupts ?
Thank you!
Code:

#include <18F458.h>
#include <stdlib.h>
#fuses HS,WDT1//(18ms&4ms)
#use delay(clock=20000000)
#use rs232(baud=9600,rcv=PIN_C7,xmit=PIN_C6)
#priority CCP1,CCP2,RDA
#define bsize 128

#include <18F458.h>
#include <stdlib.h>
#fuses HS,WDT1//(18ms&4ms)
#use delay(clock=20000000)
#use rs232(baud=9600,rcv=PIN_C7,xmit=PIN_C6)
#priority CCP1,CCP2,RDA
#define bsize 128

int8  H_flg=0,A_flg=0,buffer[bsize],len=0,i,j,n,out[13];
int16 rpm=0,force=0,rate_ctrl=0;
int32 pwm=0;
float period=0;
char  data[4];


void rcv()
{
int8  buf[20], ii, jj ;
 
   for(ii = 0 ; ii < len ; ++ii)
   {
      for(jj = 0 ; jj < 15 ; jj++)
            buf[jj] = buf[jj+1]  ;
   
      buf[15] = buffer[ii] ;

      if(buf[1] == '4' && buf[2] == '1' &&
         buf[3] == '5' && buf[4] == '5' &&
         buf[6] == '2' && buf[7] == '0' &&
         buf[8] == '0' && buf[9] == '0' &&
         buf[10] == '0')
      {         
         data[0] = buf[11] ;
         data[1] = buf[12] ;
         data[2] = buf[13] ;
         data[3] = buf[14] ;
         
         if(buf[5] == '0')
            force = atof(data)  ;
         else if(buf[5] == '1')
            force = -atof(data) ;
           
            out[8]=force/256;
            out[9]=force%256;
         } 
   }
   for(ii = 0 ; ii < bsize ; ++ii )
       buffer[ii] = 0;

   len = 0;
}


#INT_CCP1 //(pwm, initial rising edge)
void CCP1_isr()
{
   if(H_flg ==0 && A_flg ==0)
   {
   set_timer1(0);
   setup_ccp1(CCP_CAPTURE_FE) ;
   H_flg = 1 ;
   }
   else if(H_flg ==1 && A_flg ==0)
   {
   pwm =get_timer1()*8; //10^-1 us
   setup_ccp1(CCP_CAPTURE_RE) ;
   H_flg = 0 ;
   out[3]= pwm/65536;
   out[4]=(pwm%65536)/256;
   out[5]=(pwm%65536)%256;
   }



#INT_CCP2 //(rpm)
void CCP2_isr()
{
   if(A_flg ==0 && H_flg ==0)
   {
   set_timer3(0) ;
   A_flg = 1;
   }
   else if(A_flg ==1 && H_flg ==0)
   {
   period  = (float)get_timer3()*0.0008 ;
   A_flg = 0;
   rpm   = (int16)(60000.0/period) ;
   out[6]=rpm/256 ;
   out[7]=rpm%256 ;
   }
}


#int_RDA
void RDA_isr(void)
{
 if(H_flg ==0)
 {
  buffer[len] = getc() ;
  ++len                ;
 
  if(len >= 16)
  rcv() ;
 }
}


void main ()
{
  for(n=0;n<13;n++)
  {
  out[n]=0;
  }
  setup_wdt(WDT_ON) ;
  setup_ccp1(CCP_CAPTURE_RE) ;
  setup_ccp2(CCP_CAPTURE_RE) ;
  setup_timer_1(T1_INTERNAL|T1_DIV_BY_4) ;
  setup_timer_3(T3_INTERNAL|T3_DIV_BY_4) ;
  enable_interrupts(INT_CCP1) ;
  enable_interrupts(INT_CCP2) ;
  enable_interrupts(INT_RDA) ;
  enable_interrupts(GLOBAL) ;
 

  while(TRUE)
   {
    restart_wdt();
    out[0]=252;
    out[1]=253;
    out[2]=0;
    out[10]=0;
    out[11]=254;
    out[12]=255;

   
    if(rate_ctrl ==15000)//20Hz(10750)
    {
       for(i=0;i<13;i++)
        { restart_wdt();
         printf("%c",out[i]);
        }
          rate_ctrl = 0 ;
    }
    rate_ctrl++ ;
  }
}


Last edited by J.H.Sun on Tue Jun 28, 2011 2:09 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19510

View user's profile Send private message

PostPosted: Tue Jun 28, 2011 2:00 am     Reply with quote

On thing 'leaping out', is your INT_RDA.
If H_FLG is non zero, characters won't be read. This _will_ result in the handler being repeatedly called, and the code effectively being hung.
If you want to throw characters away, read the character, then don't save it into the buffer. INT_RDA, says 'there is a character waiting to be read'. You _must_ read the character.

Then, remember that when the CCP triggers, it is the CCP registers that hold the timer value at the moment it triggered, not the timer registers. read the CCP, not the timer to get the moment when this occurred. Otherwise if another interrupt is being handled when the event occurs, there will be a significant error in the value you get.

Best Wishes
J.H.Sun



Joined: 27 Jun 2011
Posts: 4

View user's profile Send private message

PostPosted: Tue Jun 28, 2011 2:26 am     Reply with quote

thanks,Ttelmah !!
I just edit the code and still some problems.
The "H_flg" and "A_flg" is used to guarantee when CCP1 or CCP2 working
without being interrupt by other interruptions. Now, CCP2 can receive signal and calculate RPM from tachometer correctly, but CCP1 can not work. I tries to input signal (low:2ms, high:2ms ...), it can run. But if the signal like this (low:20ms, high:1.5ms), result from CCP1 is "0". I guess it is running, but some error causing it unable to detect, or the data being "reset" by watchdog timer.

Sincerely
Ttelmah



Joined: 11 Mar 2010
Posts: 19510

View user's profile Send private message

PostPosted: Tue Jun 28, 2011 9:25 am     Reply with quote

OK.
Your other big problem, is performing float maths in the ISR. Don't.

Just store the values from the CCP registers, and set a flag. Perform the maths in the main code, if the flag is set. Float maths take s huge amount of time. You are performing a multiplication, and a division in the ISR. General rule of thumb is "always keep ISR's short". You are talking about 2000 machine instructions to do these operations.....

Best Wishes
J.H.Sun



Joined: 27 Jun 2011
Posts: 4

View user's profile Send private message

PostPosted: Wed Jun 29, 2011 5:21 am     Reply with quote

Thanks,Ttelmah!
All the suggestions really help me a lot , by taking out some works especially "float" in the interruptions. The probelm has been solved.

Sincerely
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