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

Flag bit definition question

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



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Thu Jan 25, 2018 2:00 am     Reply with quote

In terms of differences, none really....

'Bit fields' (the : syntax), is standard C. Advantage comes where you are perhaps wanting to work with several bits together. So (for instance), the register AD1CON1 on a PIC24, can be defined like:
Code:

struct __attribute__((packed)) {
   uint done:1;
   uint samp:1;
   uint asam:1;
   uint na:1;
   uint ssrc:4;
   uint form:2;
   uint mode12:1;
   uint dmaen:1;
   uint dmabm:1;
   uint adsidl:1;
   uint na1:1;
   uint adon:1;
} AD1CON1;


And you can talk to AD1CON1.ssrc, as an entity occupying 4 bits.

For single bit use no real difference.

However the #BIT directive, was specifically an optimisation. The PIC itself has a single instruction bit set/clear operation, and the #bit directive automatically accesses this. It was a way to offer the programmer access to this specific machine instruction. There are other (swap for example).

That being said, the current optimiser is quite smart, and for a single bit access into the bit fields form, will substitute the optimised machine instruction.

Remember if using bit fields, that you have to think what order the processor actually allocates bits, and (for the PIC 12/16/18), the 'wrapper' type is a single int8 only - hence the two byte initialisation you show, while with the #bit directive, you can initialise the larger type.

The problem you are having with bitfields, is that with this 'AdresFlags', is not an int16. It is a structure containing the bits. What you have to do is tell the compiler to treat this structure 'as' an int16. This is what PCM_Programmer is showing (the cast is the vital thing here).

You can also take advantage of a union here:
Code:

struct bits {
unsigned   int8 Adres1:1;
unsigned   int8 Adres2:1;
unsigned   int8 Adres3:1;
unsigned   int8 Adres4:1;
unsigned   int8 Adres5:1;
unsigned   int8 Adres6:1;
unsigned   int8 Adres7:1;
unsigned   int8 Adres8:1;
unsigned   int8 Adres9:1;
unsigned   int8 Adres10:1;
}; // Flag Bits

union {
    struct bits b;
    unsigned int16 whole;
} AdresFlags;


     static unsigned int16 ADRESDATA_READ=0;  // ADRESS BUTON DATA
    //You can then talk to single bits:
    AdresFlags.b.Adres9 =1; //for example
    //Or the whole word as

    AdresFlags.whole ^= ADRESDATA_READ;
pyrodigy



Joined: 27 Nov 2017
Posts: 3

View user's profile Send private message

PostPosted: Thu Jan 25, 2018 4:04 am     Reply with quote

PCM programmer wrote:
You should post a complete test program so we don't have to do any work
to make one. Then we can just copy and paste it into our IDE and test it.
I made one below.

My main program contains 68 push button and 100 led indicator over spi, 2 x usart, i2c, lcd...ext so in my opinion if i post complete program it will be hard to focus main question. I only say my main flow control related to these Flag bits test.
About the test functions;
I defined a dummy test program, i test the codes where i stuck and look at the mplab simulator to see what is going on.
This test dedicated to bit definitions to understand difference between bit definitions.
Code:

void TEST(void)
{
static unsigned int16    ADRESDATA_READ=0; //ADRESS BUTTON DATA READ from 2 x 165
   while(TRUE){

         read_ADRES_inputs(&ADRESDATA_READ); // READ 10 Bit from 2 x 74HC165 
                                 // same function as read_expanded_inputs() in 74165.c driver
         ADRESDATA_READ = ADRESDATA_READ & 0x3FF; // MASK High 6 bits (00000011 111111111)      
         if(ADRESDATA_READ)  //Zero Test
            {
            if(MultiCue)   //If MC button pressed
            AdresFlags ^= ADRESDATA_READ; //Toogle bits
            else         //If Not
            AdresFlags = ADRESDATA_READ; // assign whole
            }
         }


My main aim is, as i stated in my previous i am not getting error when i defined as #BYTE and its Flag #bits method. I just would like to know struct type bit definition method. C programming language book explained shallow for the struct type bit definitions.
Code:

(int16)AdresFlags ^= ADRESDATA_READ;    // *** cast to int16

Thank you for your code, i am glad to see CCS sort out easily with redefine as 16 bit (int16) AdresFlags register.

Ttelmah wrote:
In terms of differences, none really....

'Bit fields' (the : syntax), is standard C. Advantage comes where you are perhaps wanting to work with several bits together. So (for instance), the register AD1CON1 on a PIC24, can be defined like:
Code:

struct __attribute__((packed)) {
   uint done:1;
   uint samp:1;
   uint asam:1;
   uint na:1;
   uint ssrc:4;
   uint form:2;
   uint mode12:1;
   uint dmaen:1;
   uint dmabm:1;
   uint adsidl:1;
   uint na1:1;
   uint adon:1;
} AD1CON1;


And you can talk to AD1CON1.ssrc, as an entity occupying 4 bits.

For single bit use no real difference.

However the #BIT directive, was specifically an optimisation. The PIC itself has a single instruction bit set/clear operation, and the #bit directive automatically accesses this. It was a way to offer the programmer access to this specific machine instruction. There are other (swap for example).

That being said, the current optimiser is quite smart, and for a single bit access into the bit fields form, will substitute the optimised machine instruction.

Remember if using bit fields, that you have to think what order the processor actually allocates bits, and (for the PIC 12/16/18), the 'wrapper' type is a single int8 only - hence the two byte initialisation you show, while with the #bit directive, you can initialise the larger type.

The problem you are having with bitfields, is that with this 'AdresFlags', is not an int16. It is a structure containing the bits. What you have to do is tell the compiler to treat this structure 'as' an int16. This is what PCM_Programmer is showing (the cast is the vital thing here).

You can also take advantage of a union here:
Code:

struct bits {
unsigned   int8 Adres1:1;
unsigned   int8 Adres2:1;
unsigned   int8 Adres3:1;
unsigned   int8 Adres4:1;
unsigned   int8 Adres5:1;
unsigned   int8 Adres6:1;
unsigned   int8 Adres7:1;
unsigned   int8 Adres8:1;
unsigned   int8 Adres9:1;
unsigned   int8 Adres10:1;
}; // Flag Bits

union {
    struct bits b;
    unsigned int16 whole;
} AdresFlags;


     static unsigned int16 ADRESDATA_READ=0;  // ADRESS BUTON DATA
    //You can then talk to single bits:
    AdresFlags.b.Adres9 =1; //for example
    //Or the whole word as

    AdresFlags.whole ^= ADRESDATA_READ;


Honestly this is the exactly answer what i am looking for. Your lesson should be the duration of the bit-fields topic in the Dennis Ritchie's book Smile
I will read again and again Thank you very much. I appreciated.
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