View previous topic :: View next topic |
Author |
Message |
notbad
Joined: 10 Jan 2013 Posts: 68
|
A better substitute for bit_set, bit_clear |
Posted: Fri Jul 11, 2014 10:11 am |
|
|
Is there a function or a macro to write a Boolean variable to a bit in another variable? If not, how can I write one?
like this:
or
Code: | func(a , 7 ,f_boolean()); |
Thanks |
|
![](templates/subSilver/images/spacer.gif) |
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Fri Jul 11, 2014 10:40 am |
|
|
two instances of what you ask for come to mind:
a bit that has the same offset in it's home byte
or
an arbitrary offset in the register/byte?
and what's the problem with the ccs function? |
|
![](templates/subSilver/images/spacer.gif) |
notbad
Joined: 10 Jan 2013 Posts: 68
|
|
Posted: Fri Jul 11, 2014 1:31 pm |
|
|
Thanks for your answer asmboy.
arbitrary offset is what I need.
Quote: | and what's the problem with the ccs function? |
Nothing. I just wanted to be able to assign the return value of a Boolean function to a bit without having to use "if else". |
|
![](templates/subSilver/images/spacer.gif) |
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Fri Jul 11, 2014 1:58 pm |
|
|
check your .LST file
when assigning to a defined bit , it won't get more efficient than
a.7 = whatever_1bit_value
as the compiler dos a pretty slick job with it.
Recall that the only PIC opcodes (16f/18f)
are BCF/BSF and their matching branch-tests.
you are stuck with bit level compares and set/clr
OR a more elaborate AND/OR masking process that
i estimate will take more cycles than just IF/ELSE type code.
Last edited by asmboy on Fri Jul 11, 2014 2:15 pm; edited 1 time in total |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jul 11, 2014 2:09 pm |
|
|
It does ? This doesn't even compile:
|
|
![](templates/subSilver/images/spacer.gif) |
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Fri Jul 11, 2014 2:16 pm |
|
|
Code: |
int8 a;
#bit mine a.7
mine = 1;
|
which we all know is an efficient way to do it-
i'm guessing that's what he intended ![Question](images/smiles/icon_question.gif) |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19359
|
|
Posted: Fri Jul 11, 2014 2:40 pm |
|
|
Why not just #define the test?.
Code: |
#define bit(v,x,n) if(n) bit_set(v,x); else bit_clear(v,x)
//then use as:
int val;
bit(val,7,func());
//assigns the true/false return from func, to bit 7 in val.
|
Using a union/structure is the another choice:
Code: |
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;
};
union
{
int i;
struct bits b;
} val;
//val.b.b0 to 7 are the bits, and val.i, the whole integer
val.b.b0=func();
|
Or you can generate #bit defines for the bits in a variable, and use these exactly as you show. |
|
![](templates/subSilver/images/spacer.gif) |
notbad
Joined: 10 Jan 2013 Posts: 68
|
|
Posted: Fri Jul 11, 2014 3:31 pm |
|
|
Thanks guys
Ttelmah's first solution is exactly what I was looking for.
Thanks ![Smile](images/smiles/icon_smile.gif) |
|
![](templates/subSilver/images/spacer.gif) |
jeremiah
Joined: 20 Jul 2010 Posts: 1328
|
|
Posted: Fri Jul 11, 2014 4:45 pm |
|
|
Sometimes I use a combination of both of the options that Ttelmah suggested:
Code: |
typedef struct{
int8 bit0 : 1;
int8 bit1 : 1;
int8 bit2 : 1;
int8 bit3 : 1;
int8 bit4 : 1;
int8 bit5 : 1;
int8 bit6 : 1;
int8 bit7 : 1;
} bits_t;
#define bit(var,offset) ((bits_t)var).bit##offset
|
Then calls are just:
It provides the nice macro simplicity look/use, but with the optimized code of the union (no if/else checking) |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19359
|
|
Posted: Sat Jul 12, 2014 12:58 am |
|
|
You still have the if/else checking.
It is the only way to do the bit operations with the instruction code.
The point is that the checking is only generated, if the value being written is a variable (return from a function etc.).
The same is true with the original macro version (the compiler optimiser knows to remove the test if the value is fixed).
On the PIC24/30, the if/else, and the structure macro will work, but Jeremiah's version has to be changed to use an 'int', rather than an int8, and the extra 8 bits have to be added for the high byte, otherwise the compiler will give an error.
I too like this approach, and ran into the problems when shifting to a PIC24.... |
|
![](templates/subSilver/images/spacer.gif) |
jeremiah
Joined: 20 Jul 2010 Posts: 1328
|
|
Posted: Sat Jul 12, 2014 9:19 am |
|
|
Yep, my mistake. I assumed since the decision was actually placed in the macro itself that it wouldn't optimize it out. I should have checked first. That's good to know for the future though. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19359
|
|
Posted: Sat Jul 12, 2014 11:05 am |
|
|
Just occasionally the optimiser is quite smart!... ![Smile](images/smiles/icon_smile.gif) |
|
![](templates/subSilver/images/spacer.gif) |
|