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

CCP1 Capture Interrupt Latency (18F452)
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Scott Anderson
Guest







CCP1 Capture Interrupt Latency (18F452)
PostPosted: Mon Jan 20, 2003 2:58 pm     Reply with quote

I s'pose y'all know about this already, but I just found out and thought I'd share.
Background:
I am using the PIC to measure speed and use the TIMER1 overflow interrupt to extend the range of TIMER1. I divide the clock by 8 and capture the timer value when there is a tachometer transition on the CCP1 pin.

The effect:
If the catured timer value is within 12 counts but still less than 0xFFFF, the timer overflow interrupt has already been serviced. This happens whether I set the priority for the TIMER1 overflow interrupt higher or lower than the CCP1 interrupt.

The solution:
You can't count on this behaving in a consistent manner, so you have to mistrust the extended count any time you are near the beginning or end of the timer. I can afford to ignore some measurements, so that is how I deal with any sudden drop in speed due to an extra count in the overflow count variable.
___________________________
This message was ported from CCS's old forum
Original Post ID: 10831
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

Re: CCP1 Capture Interrupt Latency (18F452)
PostPosted: Mon Jan 20, 2003 3:20 pm     Reply with quote

:=I s'pose y'all know about this already, but I just found out and thought I'd share.
:=Background:
:=I am using the PIC to measure speed and use the TIMER1 overflow interrupt to extend the range of TIMER1. I divide the clock by 8 and capture the timer value when there is a tachometer transition on the CCP1 pin.
:=
:=The effect:
:=If the catured timer value is within 12 counts but still less than 0xFFFF, the timer overflow interrupt has already been serviced. This happens whether I set the priority for the TIMER1 overflow interrupt higher or lower than the CCP1 interrupt.
------------------------------------------------------------

I recently went through this problem. Here is the solution
I came up with. There may be a better way, but this is what I
came up with in the allotted time. I did this for a 16F628.

//------------------------------------------------------------
// MACROS
// This macro allows us to insert a byte into the specified
// offset of a 16 or 32 bit variable. Example:
// *BytePtr(temp_long, 2) = 0x55;
// If temp_long is 0, the above line will make it become:
// 0x00550000
#define BytePtr(var, offset) (char *)(&var + offset)

// The Timer1 interrupt increments an 8-bit variable which
// extends the timer to 24 bits. We need this so we can
// avoid having to switch the Timer pre-scaler between "low"
// and "high" rpm ranges.

#int_timer1
void timer1_isr(void)
{
gc_timer1_extension++;
}

//------------------------------------------------------
// When we get a CCP interrupt, read the CCP register and
// save it in a global variable.

#int_ccp1
void ccp1_isr(void)
{
char timer_ext_copy;
int32 current_ccp;
static int32 old_ccp = 0;

// Set flag to indicate that we did a capture.
gc_capture_flag = TRUE;

current_ccp = (int32)CCPR1_REG; // Read the current CCP

// Get local copy of the timer ext.
timer_ext_copy = gc_timer1_extension;

// Check if a Timer1 interrupt is pending. If so, check if
// the CCP capture occurred before or after the Timer rolled
// over. We can tell if it occurred after it rolled over, if
// the CCP's MSB is zero. ie., if the CCP is somewhere between
// 0x0000 and 0x00FF.
// We know that we can just check if the MSB = 0x00, because
// it takes about 30 us to get into this ISR. (Using a 4 Mhz
// crystal on a 16F628). The timer increments at 1 us per
// count, so 0xFF = 255 us.
// Actually, to be safer, I'll give it 2 MSB counts, which is
// 511 us. That way, if I lengthen any of the other ISR's,
// we'll still be able to detect the roll-over OK.
// If the timer did roll over after we got a CCP interrupt,
// then we need to increment the timer extension byte, that we
// save. We have to do that because the CCP interrupt has
// priority, and so it executes before the Timer isr can
// execute and increment the extension.
// (Designing the code with the priority switched doesn't help.
// You still have the same type of problem. With CCP first,
// the fix is easier).
//

// Was CCP captured after Timer1 wrapped ?
// If so, increment the copy of the timer ext.
if(TMR1IF_BIT)
{
if(*BytePtr(current_ccp, 1) < 2)
timer_ext_copy++;

// Since we know a timer interrupt is pending, let's just
// handle it here and now. That saves a little load off
// the processor.
gc_timer1_extension++; // Increment the real timer extension
TMR1IF_BIT = 0; // Then clear the Timer1 interrupt
}

// Insert the timer extension into the proper place in the
// 32-bit CCP value.
// ie., Insert it into location "EE" as follows: 0x00EEnnnn
// (nnnn = the CCP).
*BytePtr(current_ccp, 2) = timer_ext_copy;

// Because we're using unsigned math, we don't have to worry
// if the current value is less than the old. The result is
// always the absolute value of the difference. The only way
// there could be a problem is if the new CCP value had rolled
// over twice. But with a 24-bit value, and a Timer
// pre-scalar of 1, that's 16.7 seconds. That's way beyond any
// practical value.

// Edited on Jan. 2, 2004: There was a bug in this routine,
// because I was promoting a 24-bit value to a 32-bit data type,
// but the upper byte was always left = 0. This caused a problem
// with the 32-bit subtraction when the 24-bit value rolled over past 0.
// Kenny spotted this error and provided a fix in a PM to me.
// I have commented out the original line, and inserted his fix, below.
//g32_ccp_delta = current_ccp - old_ccp;
g32_ccp_delta = (current_ccp > old_ccp) ? current_ccp - old_ccp : current_ccp + (0x1000000 - old_ccp);

// Save the current ccp value for next time.
old_ccp = current_ccp;

}

___________________________
This message was ported from CCS's old forum
Original Post ID: 10833


Last edited by PCM programmer on Fri Jan 02, 2004 1:56 pm; edited 1 time in total
Hans Wedemeyer
Guest







Re: CCP1 Capture Interrupt Latency (18F452)
PostPosted: Mon Jan 20, 2003 4:03 pm     Reply with quote

If your TIMER does an interrupt BEFORE 0XFFFF there has to be something wrong with hardware(PIC18F452)!

What you are saying is that the interrupt happens before the register overflows ?

The Interrupt can't(should not)happen before TIMER1 counter overflows.

Is there an errata sheet about this at MicroChip ?
___________________________
This message was ported from CCS's old forum
Original Post ID: 10836
Scott Anderson
Guest







Re: CCP1 Capture Interrupt Latency (18F452)
PostPosted: Tue Jan 21, 2003 11:29 am     Reply with quote

The timer does not interrupt before it reaches 0xffff. The capture happens before the overflow, but the overflow interrupt sometimes happens before the capture interrupt can be processed. This is just an architectural characteristic of the chip.
:=If your TIMER does an interrupt BEFORE 0XFFFF there has to be something wrong with hardware(PIC18F452)!
:=
:=What you are saying is that the interrupt happens before the register overflows ?
:=
:=The Interrupt can't(should not)happen before TIMER1 counter overflows.
:=
:=Is there an errata sheet about this at MicroChip ?
:=
:=
___________________________
This message was ported from CCS's old forum
Original Post ID: 10856
Hans Wedemeyer
Guest







Re: CCP1 Capture Interrupt Latency (18F452)
PostPosted: Thu Jan 23, 2003 9:00 am     Reply with quote

I don't know the overall design of your application and this may not be a good solution for you.

There is another solution that comes to mind, that of using a rolling Counter and don't use TIMER1 interrupts to extend the Timer1 counter.
If you need the Timer1 interrupts for something else this still works becasue we never need to bother about incrementing Timer1 count (i.e. Extending it) in the Timer1 ISR.

I've used this for years and it has never failed me.
BTW reading timers with PIC18 is a LOT faster than with PIC16.

// some unions for convenient access
struct HighLow32
{
int16 h;
int16 l;
};
union HL32
{
INT32 L;
struct HighLow32 hl;
};

int16 OldCount;
union HL32 Count;
int Update;

CCP1_isr()
{
Count.hl.l = Get_Timer1();
Update++; // just a convenient update flag
}


Somewhere else :-)

if ( Update > 0 )
{
if( OldCount > Count.hl.l ) // then Timer1 rolled over
{
Count.hl.h++;
}
OldCount = Count.hl.l;

// now do something with the Full 32 bit count value
Count.L;

Update=0; // allow another reading or whatever
}
___________________________
This message was ported from CCS's old forum
Original Post ID: 10931
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

Re: CCP1 Capture Interrupt Latency (18F452)
PostPosted: Thu Jan 23, 2003 1:16 pm     Reply with quote

:=CCP1_isr()
:={
:= Count.hl.l = Get_Timer1();
:= Update++; // just a convenient update flag
:=}
:=
---------------------------------------------------

What if the timer rolls over several times between CCP
interrupts ?
___________________________
This message was ported from CCS's old forum
Original Post ID: 10946
Hans Wedemeyer
Guest







Re: CCP1 Capture Interrupt Latency (18F452)
PostPosted: Thu Jan 23, 2003 4:41 pm     Reply with quote

:=What if the timer rolls over several times between CCP
:=interrupts ?

Sure as I said I did not know the application and it may not suitable for his application:-

The limitation is obvious and in practice with a Div 1 setting for Timer1 and the 4mHz clock it will roll over every 65mS, so the slowest rate on "CCP"1 should not exceed that. In practice
if there is enough time to process the comparsion in some other loop ( typically main()) the slowest CCP1 can begin to approach 2*65mS (1.99 * is better )

Use a Div8 setting for Timer1 and 4mHz clock and the roll over time is that much longer...

This will avoid Timer1 rolling over twice, which will ensure the assumption is still true when the comparison is made elsewhere.

Of course the comparison can be done in the CCP1 ISR in which case the high frequency will suffer because if the extended handling time in the ISR is too long.

All in all this does work, and avoiding any ISR is a bonus !
___________________________
This message was ported from CCS's old forum
Original Post ID: 10952
asseel



Joined: 13 Jun 2009
Posts: 6

View user's profile Send private message

PostPosted: Sun Jun 14, 2009 2:26 pm     Reply with quote

hi
i try to use your code in my program
could you take look here pleases

http://www.ccsinfo.com/forum/viewtopic.php?p=117019#117019

thank you
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jun 14, 2009 2:31 pm     Reply with quote

You chose a really old thread to reply to. There are several newer
threads about the same topic. Read all of these threads (each one
is 2 or 3 pages long). You also need to be at least an intermediate
level C programmer to understand all of this. I can't make you be
a that level. You have to work with the C language for some time
to get to the intermediate level of skill.
http://www.ccsinfo.com/forum/viewtopic.php?t=29963
http://www.ccsinfo.com/forum/viewtopic.php?t=38013
http://www.ccsinfo.com/forum/viewtopic.php?t=36852
asseel



Joined: 13 Jun 2009
Posts: 6

View user's profile Send private message

PostPosted: Sun Jun 14, 2009 2:53 pm     Reply with quote

thank you
i will read them
gurdeepsembi



Joined: 22 Dec 2010
Posts: 14
Location: UK

View user's profile Send private message

PostPosted: Wed Dec 22, 2010 6:11 am     Reply with quote

Hi PCM programmer,

I am trying to read the frequency of a square wave signal generated by a gear tooth sensor. The freq range I need to measure is 0-20 Hz. I am using a PIC18F2520 running at 8MHz.

I have used your code which extends timer1 to 24 bits, but I am getting errors when I try to compile the code. Errors are:

Undefined identifier CCPR1_REG
Undefined identifier TMR1IF_BIT

We are using the PCH compiler version 4.114

Any idea why I am getting these errors? Do I have to declare these variables somewhere? I thought that the header file would contain these variables but when I looked in 18F2520.h that is supplied with the compiler, there is no reference to these variables. Is there another header file I need to include?

My code is:

Code:


#include <18F2520.h>
#device ICD=TRUE      //disable this for production as it removes code protection
//#device adc=8

#FUSES WDT         //Use Watch Dog Timer
#FUSES WDT4096              //Watch Dog Timer uses 1:4096 Postscale - 1 WD cycle is 4ms - With postscale, timeout is 16.38 secs
#FUSES INTRC_IO      //Internal RC Osc, no CLKOUT
#FUSES FCMEN               //Fail-safe clock monitor enabled
#FUSES BROWNOUT           //Enable brownout reset
#FUSES BORV27                  //Brownout reset at 2.7V
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOCPD                 //No EE protection
#FUSES STVREN                  //Stack full/underflow will cause reset
#FUSES DEBUG                   //Debug mode for use with ICD
#FUSES NOLVP                  //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT                //Program memory not write protected
#FUSES NOWRTD               //Data EEPROM not write protected
#FUSES NOWRTC               //configuration not registers write protected
#FUSES IESO                      //Internal External Switch Over mode enabled
#FUSES NOEBTR                  //Memory not protected from table reads
#FUSES NOEBTRB           //Boot block not protected from table reads
#FUSES MCLR                     //Master Clear pin enabled

#FUSES NOPROTECT          //Code not protected from reading
#FUSES NOCPB                  //No Boot Block code protection
#FUSES NOWRTB               //Boot block not write protected

#use delay(clock=8000000,RESTART_WDT)

#define OP_BUZZER_OB PIN_A4    //   On Board Buzzer

// This global variable holds the time interval
// between two consecutive rising edges of the
// input signal.
int32 isr_ccp_delta;
int32 current_ccp_delta;
int16 frequency;

int gc_capture_flag = 0;
int32 g32_ccp_delta;
int32 gc_timer1_extension;


// 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(). 

// code from http://www.ccsinfo.com/forum/viewtopic.php?t=906

//------------------------------------------------------------
// MACROS
// This macro allows us to insert a byte into the specified
// offset of a 16 or 32 bit variable. Example:
// *BytePtr(temp_long, 2) = 0x55;
// If temp_long is 0, the above line will make it become:
// 0x00550000
#define BytePtr(var, offset) (char *)(&var + offset)

// The Timer1 interrupt increments an 8-bit variable which
// extends the timer to 24 bits. We need this so we can
// avoid having to switch the Timer pre-scaler between "low"
// and "high" rpm ranges.

#int_timer1
void timer1_isr(void)
{
   gc_timer1_extension++;
}

//------------------------------------------------------
// When we get a CCP interrupt, read the CCP register and
// save it in a global variable.

#int_ccp1
void ccp1_isr(void)
{
   char timer_ext_copy;
   int32 current_ccp;
   static int32 old_ccp = 0;
   
   // Set flag to indicate that we did a capture.
   gc_capture_flag = TRUE;
   
   current_ccp = (int32)CCPR1_REG; // Read the current CCP
   
   // Get local copy of the timer ext.
   timer_ext_copy = gc_timer1_extension;
   
   // Check if a Timer1 interrupt is pending. If so, check if
   // the CCP capture occurred before or after the Timer rolled
   // over. We can tell if it occurred after it rolled over, if
   // the CCP's MSB is zero. ie., if the CCP is somewhere between
   // 0x0000 and 0x00FF.
   // We know that we can just check if the MSB = 0x00, because
   // it takes about 30 us to get into this ISR. (Using a 4 Mhz
   // crystal on a 16F628). The timer increments at 1 us per
   // count, so 0xFF = 255 us.
   // Actually, to be safer, I'll give it 2 MSB counts, which is
   // 511 us. That way, if I lengthen any of the other ISR's,
   // we'll still be able to detect the roll-over OK.
   // If the timer did roll over after we got a CCP interrupt,
   // then we need to increment the timer extension byte, that we
   // save. We have to do that because the CCP interrupt has
   // priority, and so it executes before the Timer isr can
   // execute and increment the extension.
   // (Designing the code with the priority switched doesn't help.
   // You still have the same type of problem. With CCP first,
   // the fix is easier).
   //
   
   // Was CCP captured after Timer1 wrapped ?
   // If so, increment the copy of the timer ext.
   if(TMR1IF_BIT)
   {
      if(*BytePtr(current_ccp, 1) < 2)
      timer_ext_copy++;
      
      // Since we know a timer interrupt is pending, let's just
      // handle it here and now. That saves a little load off
      // the processor.
      gc_timer1_extension++; // Increment the real timer extension
      TMR1IF_BIT = 0; // Then clear the Timer1 interrupt
   }
   
   // Insert the timer extension into the proper place in the
   // 32-bit CCP value.
   // ie., Insert it into location "EE" as follows: 0x00EEnnnn
   // (nnnn = the CCP).
   *BytePtr(current_ccp, 2) = timer_ext_copy;
   
   // Because we're using unsigned math, we don't have to worry
   // if the current value is less than the old. The result is
   // always the absolute value of the difference. The only way
   // there could be a problem is if the new CCP value had rolled
   // over twice. But with a 24-bit value, and a Timer
   // pre-scalar of 1, that's 16.7 seconds. That's way beyond any
   // practical value.
   
   // Edited on Jan. 2, 2004: There was a bug in this routine,
   // because I was promoting a 24-bit value to a 32-bit data type,
   // but the upper byte was always left = 0. This caused a problem
   // with the 32-bit subtraction when the 24-bit value rolled over past 0.
   // Kenny spotted this error and provided a fix in a PM to me.
   // I have commented out the original line, and inserted his fix, below.
   //g32_ccp_delta = current_ccp - old_ccp;
   g32_ccp_delta = (current_ccp > old_ccp) ? current_ccp - old_ccp : current_ccp + (0x1000000 - old_ccp);
   
   // Save the current ccp value for next time.
   old_ccp = current_ccp;

}

//--------------------------------------------------------------------------------
//   Sound on board buzzer
//--------------------------------------------------------------------------------

void sound_buzzer(int no_times, int16 time_delay)
{
   int i = 0;

   for (i=1;i<=no_times;++i)
   {
      output_high(OP_BUZZER_OB);
      delay_ms(time_delay);
      output_low(OP_BUZZER_OB);
      delay_ms(time_delay);
   }
   
}

void initialise_pic(void)
{
   
   //   Setup ports         //  76543210
   SET_TRIS_A( 0xC0 );            //  11000000      1 - Input, 0 - Output
   SET_TRIS_B( 0xFF );           //  11111111      1 - Input, 0 - Output
   SET_TRIS_C( 0xFF );            //  11111111      1 - Input, 0 - Output

   //switch off buzzer
   output_low(OP_BUZZER_OB);
   
   //set all outputs OFF
   output_low(OP_STAT);
   output_low(OP_SAFETY_CHK);
   output_low(OP_INV_1);
   output_low(OP_INV_2);
   output_low(OP_INV_3);
   output_low(OP_TL_ENT);
   output_low(OP_TL_EXT_BS);
      
   //   Setup Internal Clock
   setup_oscillator(OSC_4MHZ);
   
   //   Setup Interrupts
   enable_interrupts(INT_TIMER1);
   
   // Setup Timer1 and CCP1 for Capture mode so that
   // we can measure the input signal's frequency.
   // The input signal comes from the CCP2 pin, 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);

}

void measure_speed(void)
{
   
   //code from http://www.ccsinfo.com/forum/viewtopic.php?t=29963&postdays=0&postorder=asc&start=0

   // Now calculate the frequency. 
   
   disable_interrupts(GLOBAL);
   current_ccp_delta = g32_ccp_delta;;
   enable_interrupts(GLOBAL);
   
   if(gc_capture_flag == TRUE)
     {
      frequency = (int16)((1000000L + (current_ccp_delta >> 1)) / current_ccp_delta);
   
      //printf("%lu Hz, delta = %lx \n\r", frequency, current_ccp_delta);
   
      gc_capture_flag = FALSE;
     }
   //else
   //{
   //   printf("No signal\n\r");
    // }
}

   

void main()
{

   int restart_on_wdt = 0;
   
   //   check if restarting on watchdog timer
   if (restart_cause() == WDT_TIMEOUT)
   {
      restart_on_wdt = 1;
   }
   else
   {
      restart_on_wdt = 0;
   }
   
   if (start_up_sequence == 1)         //   check if starting up
   {
      //config_mode_check ();   //   check if config mode needs to be enabled
      initialise_pic ();               //   initialise the uC
      start_up_sequence = 0;      //   reset bit so on next cycle uC not re-initialised
   }

   //setup watchdog timer
   setup_wdt(WDT_ON);
   
   //if restarted on watchdog then remain in this loop
   //keep beeping to alert that there was an abnormal shutdown
   if(restart_on_wdt == 1)
   {
      while(1)
      {
         restart_wdt();
         sound_buzzer(1,500);
      }         
   }
   

   if(restart_on_wdt == 0)
   {
      while(1)
      {
         restart_wdt();
         //determine_status();
         //set_status_output(); 
         //process_inputs(); 
         measure_speed();
      }
   }
}   


Thanks for your help.

Gurdeep
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Dec 22, 2010 3:06 pm     Reply with quote

Quote:
Errors are:

Undefined identifier CCPR1_REG
Undefined identifier TMR1IF_BIT

Add the lines shown in bold below to your program:
Quote:

int32 isr_ccp_delta;
int32 current_ccp_delta;
int16 frequency;

int gc_capture_flag = 0;
int32 g32_ccp_delta;
int32 gc_timer1_extension;

#byte CCPR1_REG = getenv("SFR:CCPR1")
#byte PIR1 = getenv("SFR:PIR1")
#bit TMR1IF = PIR1.0


gurdeepsembi



Joined: 22 Dec 2010
Posts: 14
Location: UK

View user's profile Send private message

PostPosted: Thu Dec 23, 2010 5:34 am     Reply with quote

Hi PCM Programmer,

Thanks for your help. That worked, I just had to name the variable as TMR1IF_BIT instead of TMR1IF as that is what it is referred to as in the rest of the code.

Code:
#byte CCPR1_REG = getenv("SFR:CCPR1")
#byte PIR1 = getenv("SFR:PIR1")
#bit TMR1IF_BIT = PIR1.0


The code now compiles and I will test it to see if I can get the frequency readings.

Once again thanks a lot for your help, much appreciated.

Gurdeep
Flowmeter



Joined: 29 Oct 2013
Posts: 3

View user's profile Send private message

Problem with BytePtr
PostPosted: Tue Oct 29, 2013 1:09 am     Reply with quote

Hi, I have used the code presented in this thread but have problems with the BytePtr

A quick test shows:
Code:

#define BytePtr(var, offset) (char*)(&var + offset)

INT32 test0 = 0x0000ff00;
INT32 test1 = 0x0000ff00;
INT32 test2 = 0x0000ff00;
INT32 test3 = 0x0000ff00;
INT8 addOn=0x0f;

void main(void)
{   
*BytePtr(test0,0)=addOn;
*BytePtr(test1,1)=addOn;
*BytePtr(test2,2)=addOn;
*BytePtr(test3,3)=addOn;
}

Result from watch after processing *BytePtr(test3,3)=addOn;
Symbol - Address - Value - Comment
test0 - 064 - 0x0000FF0F - as expected
test1 - 068 - 0x0000FF00 - not sure what went wrong?!
test2 - 06C - 0x0000FF0F - written into wrong byte?!
test3 - 070 - 0x0000FF00 - not sure what went wrong?!
addOn - 074 - 0X0F - as expected

I am using a PIC18F67J50, MPLAB IDE v8.92, MPLAB C18 C v3.46, MPLINK v.4.48, MPASM v5.50, MPLIB v4.48

Would appreciate any help to understand, what is going wrong with the BytePtr.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Oct 29, 2013 1:35 am     Reply with quote

That code was written for a very old version of the CCS compiler, in which
all pointer arithmetic automatically defaulted to byte operations.
That's incorrect, and CCS did fix it. The BytePtr macro shown above
should be replaced with the following code. This will do the pointer
arithmetic correctly:
Code:
#define BytePtr(var, offset)   (&(char)var + offset)
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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