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

Accessing a specific bit of a variable

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



Joined: 04 Feb 2016
Posts: 11

View user's profile Send private message Send e-mail

Accessing a specific bit of a variable
PostPosted: Wed Feb 10, 2016 11:10 pm     Reply with quote

Hi guys, I'm trying to access to a specific bit of an unsigned short, but i can't do it right. Here is an example of my function:
Code:
unsigned short function(unsigned short address)
{
address.b7 = 0; // I NEED HERE A VALID EXPRESSION
address.b6 = 0; // I NEED HERE A VALID EXPRESSION
return address;
}

As argument i have a byte variable (address: "b7,b6,...b1,b0") and i want to make the first 2 bits (bit7 and bit6) zeros, but i want to keep the rest of the bits as original.
Example:
address = 10110010
dir = function(address);
dir = 00110010

Which command should i use to get access to an specific bit in a byte?
Ttelmah



Joined: 11 Mar 2010
Posts: 19569

View user's profile Send private message

PostPosted: Thu Feb 11, 2016 2:17 am     Reply with quote

Step back.
What you post can't work in any way, unless you are in ANSI mode?.

A standard 'short', in CCS, is a single bit.
So you are handing the function a single bit, and expecting a single bit back. As such the variable does not 'have' a bit 6, or a bit 7....

Use 'unsigned int8', which then has eight bits, and importantly will have eight bits in just about every compiler/configuration.
This is why you will see the 'old hands', pushing the use of the numbered sizes, rather than using names like 'short', 'long' etc., since these have different meanings in different environments...

Then, there are a huge number of different ways of doing this.

The first, is to simply use the CCS bit_set/bit_clear operation.

So:
Code:

unsigned short function(unsigned short address)
{
   bit_clear(address,7); //Clear bit 7
   bit_clear(address,6); //Clear bit 6
   return address;
}

Used on a fixed bit like this, the compiler codes each of these as the processor bit set and clear instructions. Super efficient. These exist because the processor has these instructions, so CCS offered these instructions as an alternative to the standard methods of using masks etc..

Then use a structure/union with bitfields:
Code:

#include <18F4620.h>
#device ADC=10
#use delay(crystal=20000000)
struct bits
{
   int8 b0:1;
   int8 b1:1;   
   int8 b2:1;
   int8 b3:1;
   int8 b4:1;
   int8 b5:1;   
   int8 b6:1;
   int8 b7:1;
}; //This declares a structure type, called 'bits'.

typedef union {
   struct bits b;
   int8 byt;
} bitaccess; //declares a new 'type' called 'bitaccess', that is
//both a bitaccess structure, and a int8

unsigned int8 function(bitaccess address)
{
   address.b.b7=0; //Clear bit 7
   address.b.b6=0; //Clear bit 6
   return address.byt;
}
   
void main()
{
   int8 val;
   val=0xFF;
   val=function(val);
   while(TRUE)
   {
   }
}

Here we declare two different ways of accessing the same memory. A structure of single bits, and a single byte.

This can then be expanded as:
Code:

struct bits2
{
   int8 dummy:6; //six dummy bits
   int8 twobits:2; //The upper two bits   
};

typedef union {
   struct bits2 part;
   int8 byt;
} bitaccess;

unsigned int8 function(bitaccess address)
{
   address.part.twobits=0; //Clear bit 6, and 7
   return address.byt;
}


Here the structure is declared to have 6 dummy bits, and a 2 bit variable called 'twobits'. Writing to this, then operates both bits in one instruction line. This is a very 'neat' way to work with things where you need to access two or three bits 'together' in a variable. So you could say:
address.part.twobits=2;
and bit 7 will be set, and bit 6 cleared!.

Then there is the simple old 'use a bit mask' method.
So you wouldn't even use a function:

dir=address & 0x3F;

would give you the low six bits of 'address'.
germans



Joined: 04 Feb 2016
Posts: 11

View user's profile Send private message Send e-mail

PostPosted: Thu Feb 11, 2016 7:39 am     Reply with quote

Hey, Thanks a lot for your complete answer! Smile
avatarengineer



Joined: 13 May 2013
Posts: 51
Location: Arizona

View user's profile Send private message Visit poster's website

PostPosted: Tue Mar 01, 2016 4:04 pm     Reply with quote

I use a Global union variable for many many operations.

Code:

union {                                                           
  int32 asDLong;                         
  int16 asWord[2];                                         
  int8 asByte[4];
  int1 asBit[32];         
} XferDL;


Often manipulating bits or bytes in countless routines,
this single global variable makes life easier.
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Tue Mar 01, 2016 6:33 pm     Reply with quote

two ways to restructure your function:
Code:

unsigned short function(unsigned int8 address)
{
#bit b7 =address.7
#bit b6 =address.6
b6=0;b7=0;
return (address);
}

// or

unsigned short function(unsigned int8 address)
{ return (address&0b00111111;); }


in reality the argument 'address' could be a byte too-
and CCS will merrily treat it as an unsigned int8 for you


Last edited by asmboy on Wed Mar 09, 2016 6:26 pm; edited 1 time in total
soonc



Joined: 03 Dec 2013
Posts: 215

View user's profile Send private message

Lots of good replies... but
PostPosted: Tue Mar 08, 2016 9:34 am     Reply with quote

No one mentioned the built in functions:

bit_test(Variable,bit); which can handle 8,16,and 32bit variables.

If you need to manipulate bit then look at:

bit_clear() and bit_set()
Ttelmah



Joined: 11 Mar 2010
Posts: 19569

View user's profile Send private message

PostPosted: Tue Mar 08, 2016 9:48 am     Reply with quote

Er. Actually (quote from first answer):

"The first, is to simply use the CCS bit_set/bit_clear operation. "

Followed by an example showing these being used.
soonc



Joined: 03 Dec 2013
Posts: 215

View user's profile Send private message

PostPosted: Tue Mar 08, 2016 11:00 am     Reply with quote

Ttelmah wrote:
Er. Actually (quote from first answer):

"The first, is to simply use the CCS bit_set/bit_clear operation. "

Followed by an example showing these being used.


But not bit_test()
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