|
|
View previous topic :: View next topic |
Author |
Message |
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Thu Jan 25, 2018 2:00 am |
|
|
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
|
|
Posted: Thu Jan 25, 2018 4:04 am |
|
|
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
I will read again and again Thank you very much. I appreciated. |
|
|
|
|
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
|