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

Question about output_bit() function

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



Joined: 29 Jan 2013
Posts: 1

View user's profile Send private message

PostPosted: Tue Jan 29, 2013 6:45 am     Reply with quote

This question might seem odd but I'm coming from ANSI C compliant compiler and I'm trying to understand CCS syntax.

For example is this expression
Code:
output_bit(ONE_WIRE_PIN, shift_right(&data,1,0)); // set output bit on 1-wire


the equivalent of this one?

Code:
      data >>= 1;
      data &= 0x7F;
      ONE_WIRE_PIN = data;
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jan 29, 2013 4:33 pm     Reply with quote

The easiest way to see what the compiler is doing, is to make a small
test program, compile it and look at the .LST file. Then add comments
to the ASM code to describe what's happening:
Code:

..... output_bit(ONE_WIRE_PIN, shift_right(&data,1,0)); 
0032:  BCF    STATUS.C   // Clear the Carry bit   
0034:  RRCF   data,F     // Rotate data right, so Carry = LSB of data
0036:  BC     003C       // Jump to 003C if Carry bit = 1
0038:  BCF    LATB.LATB0 // If Carry = 0, set the pin = 0
003A:  BRA    003E
003C:  BSF    LATB.LATB0 // If Carry = 1, set the pin = 1
003E:  BCF    TRISB.RB0  // Set TRIS on pin = output

Test program (compiled with vs. 4.140):
Code:

#include <18F4520.h>
#fuses INTRC_IO,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)

#define ONE_WIRE_PIN  PIN_B0

//======================================
void main(void)
{
int8 data;

output_bit(ONE_WIRE_PIN, shift_right(&data,1,0));

while(1);
}
 
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Wed Jan 30, 2013 3:02 am     Reply with quote

lighty wrote:
This question might seem odd but I'm coming from ANSI C compliant compiler and I'm trying to understand CCS syntax.

For example is this expression
Code:
output_bit(ONE_WIRE_PIN, shift_right(&data,1,0)); // set output bit on 1-wire


the equivalent of this one?

Code:
      data >>= 1;
      data &= 0x7F;
      ONE_WIRE_PIN = data;


This is NOT an ANSI compliance issue. It's an understanding CCS library functions issue. CCS C can be set to be (mostly) ANSI compliant, and you'll still have those functions. They are simply library functions implemented by the compiler as are pretty much essential for all embedded programming. Realistically there cannot be any totally ANSI compliant and therefore fully portable embedded C code. There will always be some hardware dependence, which requires some sort of processor or hardware family-specific non-portable code of some kind; for example pin I/O. CCS C tries, generally successfully, to abstract all that and provide a set of library functions and the like that cover almost all PIC processors.

The answer to your question however is no. The equivalent, assuming data was a byte, which is what the shift function call suggests, would be:

Code:
     
      ONE_WIRE_PIN = (int1)(data & 0x01);
      data >>= 1;


This is because the function shift_right, shifts the single byte pointed to by the address of data by one bit, shifting in a zero - which is a don't care - and returning the old LSB. The reason this function is provided is that it maps far better onto the opcodes provided by the PIC hardware than any generic version such as ANSI C. In other words its a processor specific optimisation.

This code is unlikely to be on its own, it only makes sense as part of a loop, probably through all eight bits of a byte. Though you clearly are unlikely to code it that way as output bit with a variable is inefficent. Much better to do something like:
Code:

if (shift_right(&data,1,0))
{
   output_high(ONE_WIRE_PIN); // set output bit on 1-wire
}
else
{
   output_low(ONE_WIRE_PIN); // set output bit on 1-wire
}


RF Developer
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Wed Jan 30, 2013 3:22 am     Reply with quote

The 'equivalence' question is also missing another thing. 'ONE_WIRE_PIN', is just a number. It is not physically the pin, and can't be written directly. If you read the manual for 'output_bit', it tells you:
"The actual number is a bit address. For example, port a (byte 5 ) bit 3 would have a value of 5*8+3 or 43"

So using the example number above, "ONE_WIRE_PIN = data;"

would translate as "43 = data;".

Duh......

Best Wishes
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