Bitfields in data
Posted: Sun Jul 26, 2026 12:25 pm
Currently I need to use bitfields in some code.
On a PIC I can do REGISTERbits.FIELD = value for register values. I wanted a simple way to do this for variables.
I could define two constants field_start, field_width
An idea (which came to me as I drove home) to use just one constant....
Here the constant defines the field width and start
e.g. 0b00111100 would define a 4 bit field at position 2
The attached demonstrates this: It will be slower - it has to 'calculate' the shift needed by finding the start of the bitfield (on AVR and PIC this isn't too bad compared to .val = .val << .shift but other processors handle the multiple shifts in the same time as 1) Here I use 16 bit values (which is what I needed - but it could be modified for 8 or 32 bits.)
SetBitField modifies 'data' (it would probably be more correct to return the new value!)
Just added a GetBitfield too
Modern processors (x86 etc) have an instruction that does this (and it allows masks such as 0b10101010)
An alternative:
The constant holds the field start and width - for example as 8 bits each in a 16 bit varIable.
Any thoughts / comments / ideas?
Martin
On a PIC I can do REGISTERbits.FIELD = value for register values. I wanted a simple way to do this for variables.
I could define two constants field_start, field_width
Code: Select all
.mask = pow(2,field_width) - 1
.value = .value & .mask // Check the value will fit in the field
.mask = .mask << .field_start
.value = .value << field_start
.var = (.var & (~.mask)) | .value
Here the constant defines the field width and start
e.g. 0b00111100 would define a 4 bit field at position 2
The attached demonstrates this: It will be slower - it has to 'calculate' the shift needed by finding the start of the bitfield (on AVR and PIC this isn't too bad compared to .val = .val << .shift but other processors handle the multiple shifts in the same time as 1) Here I use 16 bit values (which is what I needed - but it could be modified for 8 or 32 bits.)
SetBitField modifies 'data' (it would probably be more correct to return the new value!)
Just added a GetBitfield too
Modern processors (x86 etc) have an instruction that does this (and it allows masks such as 0b10101010)
An alternative:
The constant holds the field start and width - for example as 8 bits each in a 16 bit varIable.
Any thoughts / comments / ideas?
Martin