i know that -> is a pointer |= is OR.
what is the logical meaning of such line?
TIMER0->ROUTELOC0 |= TIMER_ROUTELOC0_CC0LOC_LOC15
|= does not mean OR. | means OR.
|= is similar to +=, that is
A |= B is the equivalent of A = A | B
So to answer your question:
It looks like TIMER0 is a structure with a member ROUTELOC0. The above expression is setting the ROUTELOC0 as the result when ROUTELOC0 is ORed with TIMER_ROUTELOC0_CC0LOC_LOC15
You're ORing in (setting) a value to a register. Your processor has a TIMER0 with a register ROUTELOC0. It likely has a bit that is "CC0LOC_LOC15"
I recommend looking at the data sheet for your processor to figure out what that means specifically.
The -> is the structure dereference operator, and |= is the bitwise OR assignment operator (compound assignment).
The compound assignment:
x |= y ;
is equavilent to:
x = x | y ;
It is important here to understand that bitwise-OR (|) is distinct from boolean-OR (||). It is used here to set specific bits in x leaving other bits unset.
For example, to set the two least significant bits of x to 1:
x: 10100000
y: 00000011
---------
x|y: 10100011
Related
In my lab I'm supposed to test a 9 bit value but each port only contains 8 bits. According to the instructions, I use all bits on PORTD including PB0 to make this 9 bit value, but I have no plan on how I can do that and that's essentially the whole challenge of this problem. The rest of it should be easy, I only need to store a 9 bit value "borrowing" a bit from another port.
Microcontroller: ATmega1284
Problem:
(Challenge): A car's passenger-seat weight sensor outputs a 9-bit value (ranging from 0 to 511) and connects to input PD7..PD0PB0 on the microcontroller. If the weight is equal to or above 70 pounds, the airbag should be enabled by setting PB1 to 1. If the weight is above 5 but below 70, the airbag should be disabled and an "Airbag disabled" icon should light by setting PB2 to 1. (Neither B1 nor B2 should be set if the weight is 5 or less, as there is no passenger).
Bits from separate registers can be combined in any way necessary using the bit-wise operators:
& – Bitwise AND
| – Bitwise OR
~ – Bitwise NOT
^ – Bitwise XOR
<< – Left Shift
>> – Right Shift
The somewhat vague notation "PD7..PD0PB0" suggests that PB0 is the LSB or the weight value. In that case, given:
PORTD DDDDDDDD
PORTB xxxxxxxB
then:
uint16_t weight = ((uint16_t)PORTD << 1u) | (PORTB & 0x01) ;
will result in a value for weight composed of bits:
0000000DDDDDDDDB
The sub-expression ((uint16_t)PORTD << 1u) shifts the value of PORTD left by 1 bit:
0000000DDDDDDDD0
(PORTB & 0x01) zeros all but bit-0, leaving bit-0 unchanged:
0000000B
The two sub-expressions are then bit-wise OR'ed:
0000000DDDDDDDD0
OR 0000000B
----------------
= 0000000DDDDDDDDB
Note that it might be possible (safety considering) to simplify the task by using just the 8 bit value in PORTD and halving the limit values. Currently you have: "above 5 but below 70", if you just read PORTD, the limits would be 3 >= PORTD < 35. This may in fact be safer - when reading a single value from two separate registers you need to be certain the values you have are for the same sample, and that the value in the first register read did not change before you read the second. With only the one LSB in the PORTB register this will have little impact, but also makes it of limited value unless the data is somehow latched while it is read.
It depends on if PB0 is the MSB or LSB of register B. But what you cand do is using uint16_t variable and some masks to get the value you need. For example, you could do one of the following things.
PB0 is MSB
uint16_t sensor;
sensor = (PORTD << 1) | (PORTB >> 7);
PB0 is LSB
uint16_t sensor;
sensor = (PORTD << 1 ) | (PORTB & 0x01);
It can be done in many ways, and it is just one of them. In both solutions, all bits of register D are the most significant bits, and LSB, in the first one, would be the MSB of register B, and in the second one, would be the LSB of register B.
If you want your code is MISRA-C compliant you should initialize sensor variable.
Can you tell me what convertLedNumberToBit and LedDriver_TurnOn do? I do not understand what is happening with 1 << (num - 1) and |=
static uint16_t * ledsAddress;
static uint16_t convertLedNumberToBit(int ledNumber)
{
return 1 << (ledNumber - 1);
}
void LedDriver_TurnOn(int ledNumber)
{
*ledsAddress |= convertLedNumberToBit(ledNumber);
}
<< is a bitwise shift to the left. A uint16_t of 1 in binary is 0b0000000000000001, so when you shift left by the quantity ledNumber-1, the result is a uint16_t with a single-bit set to the position specified by ledNumber.
From the variable name ledNumber, I'm guessing that this function sets a specific LED to work on.
| performs a bitwise OR on the two operands it is passed.
For example,
byte b = 0x0A | 0x50;
If you look at the underlying bits for 0x0A and 0x50, they are 0b00001010 and 0b01010000 respectively. When combined with the OR operator the result in b is 0b01011010, or 0x5A in hexadecimal.
|= is a bitwise OR assignment. |= is analogous to operators like += and -= in that it will perform a bitwise OR on the two operands then store the result in the left operator.
byte b = 0x0A;
b |= 0x50;
// after this b = 0x5A
To switch 'ON' the LED[ledNumber] at I/O port ledsAddress, it is necessary to set the equivalent bit to '1'. But, when changing the I/O port value, you have to keep the state of all others LED still 'ON'.
The convertLedNumberToBit(int ledNumber) is using a mask b0000000000000001 (16bits) to set the ledNumber bit to '1' by switching to left of (ledNumber-1) { no shift needed when ledNumber is 1.
Ex: (ledNumber = 4) => returned value is b0000000000001000= 0x0008.
Then the call |= convertLedNumberToBit(ledNumber) will force only the ledNumber bit to '1' without changing others by a binary-OR.
Ex: (led1, led3 & led7 are 'ON')
before the OR b0000000001000101 = 0x0045.
LedDriver_TurnOn(4) => b0000000000001000= 0x0008
after the OR b0000000001001101 = 0x004D.
To switch 'OFF' the same LED, you have just to replace the OR function by the AND function of the NOT mask.
void LedDriver_TurnOff(int ledNumber)
{
*ledsAddress &= ~(convertLedNumberToBit(ledNumber));
}
cppreference - Arithmetic operators to the rescue
The bitwise shift operator expressions have the form
lhs << rhs (1)
lhs >> rhs (2)
1) left shift of lhs by rhs bits
2) right shift of lhs by rhs bits
So 1 << (ledNumber - 1) shifts the least significant bit to the left, e.g. if ledNumber = 5
0x0001 << (5 - 1)
will become
0x0010
Also cppreference - Assignment operators
|= is a (bitwise OR) assignment operator, where
*ledsAddress |= convertLedNumberToBit(ledNumber);
is equivalent to
*ledsAddress = *ledsAddress | convertLedNumberToBit(ledNumber);
I want to verify two bits (for example the bit number 3 and 5) values of a uint8
if their value is 0, I want to return 1
uint8 a;
if ((a & !(1<<3)) && (a & !(1<<5)))
{
Instructions..
}
Is this code correct ?
No, your code won't work in way that you want. ! operator results only in 0 or 1 and info about actual non-zero bit is lost anyway. You may use something like this:
if(!(a & ((1 << 3) | (1 << 5))) {
/* ... */
}
At first stage you are creating mask with | operator. This mask has non-zero bits only at positions that you are interested in. Then this mask is combined with tested value via &. As result you get 0 only if value has zero bits at tested positions. And then just inverse 0 to 1 with ! to obtain true condition.
It is not correct.
The ! operator is boolean NOT, not a bitwise NOT.
So, if you want to check if bits 3 & 5 are both zeroes you should write:
uint8 a;
...
if (!(a & (1<<3)) && !(a & (1<<5)))
{
Instructions..
}
Further optimisation of the expression in if is possible.
This is trivial if you don't attempt to write it as a single, messy expression. There is no advantage of doing so - contrary to popular belief, mashing as many operators into a single line is actually very bad practice. It destroys readability and you gain no performance benefits what-so-ever.
So start by creating a bit mask:
uint8_t mask = (1<<3) | (1<<5);
(The parenthesis are actually not needed, but not everyone can cite the C operator precedence table in their sleep, so this is recommended style.)
Then check the data against the mask:
if(data & mask) // if any bit contains value 1
return 0;
else // if no bit contains value 1
return 1;
Which, if you will, can be rewritten as a boolean expression:
return !(data & mask);
The complete function could look like this:
bool check_bits (uint8_t data)
{
uint8_t mask = (1<<3) | (1<<5);
return !(data & mask);
}
Your expression is false, you should not negate the masks this way and you must ignore other bits so don't use a negation. Simply:
(a & (1<<3)) + (a & (1<<5))
gives 0 if both are 0s.
Assuming that a actually is initialized, then the expression will not work as you expect. The logical not operator ! gives you a one or a zero (boolean true or false), which you then use in a bitwise and operation. That will not give you the correct result.
I suppose you mean to use the bitwise complement operator ~ instead, as in ~(1 << 3). Not that it would work anyway, as that will just check that any of the other bits in a is non-zero.
Instead check if the bit is one, and then turn around the logic using the logic not operator !, as in !(a & 1 << 3).
No. ! operator does logical negation, and since 1<<3 is not zero, !(1<<3) is zero. It means a & !(1<<3) will always be zero and therefore the condition will never be true.
I think masking is one of good ways to do what you want to do.
uint8 a;
/* assign something to a */
return (a & ((1 << 3) | (1 << 5))) == 0;
a & ((1 << 3) | (1 << 5)) is a value in which the 3rd and 5th bit (0-origin) of a keep their original value and all other bits is turned to zero. Checking if the value is zero means checking if all of the bits to check are zero while not careing other bits. == operator will return 1 if two operands are equal and 0 otherwise.
If you want to test for some combination of BIT_A and BIT_B (or whatever number of bits you can have) You can do this:
#define BIT_A (1 << 3)
#define BIT_B (1 << 5)
...
#define BIT_Z (1 << Z)
...
/* |here you put all bits |here you put only the ones you want set */
/* V V */
if (a & (BIT_A | BIT_B | ... | BIT_Z) == (BIT_A | ... | BIT_I | ...))
{
/* here you will know that bits BIT_A,..., BIT_I,... will **only**
* be set in the mask of (BIT_A | BIT_B | ... | BIT_Z) */
}
as with a & (BIT_A | BIT_B | ... ) you force all bits not in the set to be zero, so only the bits in the set will conserve their values. With the second mask, you generate a bitmap with only the bits of the set you want to be set (and of course the bits that are not in the set forced zero) so if you compare both values for equalness, you'll get the expected result.
NOTE
As an answer to your question, the particular case in which you want all the bits equal to one, is to make both masks equal. For your case, you want to check if both bits are zero, then your test is (the second mask has no bits set, so it is zero):
if (a & ((1 << 3) | (1 << 5)) == 0) { ...
(All bits in the second mask are zero as the required mask, and both, the third and the fifth bits are set in the first mask) This can be written in a more compact form as (you can see it written as):
if (!(a & 0x28)) { /* 0x28 is the octal for 00101000, with the bits you require */
WHY THE CODE YOU WROTE IS NOT CORRECT
First you mix logical operators like ! with bitmasks, making !(1<<3)to eval to 0 (1<<3 is different of 0 so it is true, negating gives 0) and the same for the !(1<<5) subexpression. When you mask a with those values makes you get a & 0 ==> 0 and a & 0 ==> 0 and anding both together gives 0 && 0 ==> 0. So the result value of your expression is 0 -- false always, independent of the original value of a.
descriptor = limit & 0x000F0000;
descriptor |= (flag << 8) & 0x00F0FF00;
descriptor |= (base >> 16) & 0x000000FF;
descriptor |= base & 0xFF000000;
I understood the fact that the and operation is used for masking certain bits. But what is OR operation used here for??? Please elaborate.
This is part of the code for creating a Global Descriptor Table.
If you look at just a single bit, the truth table is given by
0 | 0 == 0
0 | 1 == 1
1 | 0 == 1
1 | 1 == 1
So, bitwise or sets a bit if and only if that bit is set in at least one of the operands.
When you use bitwise or on a variable with more that a single bit, the above truth table is applied in a bitwise fashion.
So, suppose that you had two variables whose binary representations were
001101
011001
When you combine them with bitwise or, you collect all the bits that are set in either variable. So the result is
011101
The bitwise or operator is commonly used to add new flags to a set of bit flags. The value is used to represent a mathematical set. Each bit is assigned a particular meaning, that is associated with a member of the universal set. When the bit is 1, that member is included in the set, and when the bit is 0, the associated member is not in the set.
So, let us have a very simple example with a universal set having two members. Let us call the variable, controlState. Bit 0 represents the visible property, and bit 1 represents the enabled property. So, you can define flags like so
const int visibleFlag = 1; // 01 in binary
const int enabledFlag = 2; // 10 in binary
Then you can build the controlState variable like this:
int controlState = 0; // empty set
if (isVisible)
controlState |= visibleFlag;
if (isEnabled)
controlState |= enabledFlag;
It gets more interesting if you don't know whether or not a particular bit is set. So, you can ensure that the visible bit is set like this:
controlState = ...; // could set visible flag, or not ...
controlState |= visibleFlag;
It does not matter whether the original value of controlState included the flag or not. After this operation, it will be set for sure, and no other flags altered.
This is what is happening in your code example. So,
descriptor = limit & 0x000F0000;
initializes descriptor. Then
descriptor |= (flag << 8) & 0x00F0FF00;
adds (flag << 8) & 0x00F0FF00. And so on.
What the code you've shown is doing is constructing descriptor by selecting different parts of it from other boolean expressions.
Notice that the constants that (flag << 8), (base >> 16) and base are being ANDed with, when themselves ORed together, produce 0xFFFFFFFF.
The point of the OR is to say, "the first 8 bits come from (base >> 16), the next 8 bits from flag << 8, the next 4 from limit, the next 4 from flag << 8 and the last 8 from base." So finally, descriptor looks like this:
d[7], d[6], b[5], a[4], b[3], b[2], c[1], c[0]
Where each comma separated variable is a hexadecimal digit, and a, b, c, and d are
limit, (flag << 8), (base >> 16) and base respectively. (The commas are just there for readability, they stand for concatenation of the digits).
The use of |= here is essentially short hand for the following
descriptor = destriptor | ((flag << 8) & 0x00F0FF00);
descriptor is a collection of values packed together as bitfields. This code is building it up from four values (limit, flag, and two parts of base). Each step is shifting the value to the correction bit position and then ANDing with a mask to ensure the bits don't spill over into other positions. The A |= B operator expands to A = A | B and merges together all of the individual results. This could also be done using a struct with bitfields, although perhaps with less portability.
Bit-wise OR | operator (copies a bit if it exists in either operand) used here to ORing the descriptor with right hand operator of = and store the result to descriptor. It is equivalent to
descriptor = descriptor | (flag << 8) & 0x00F0FF00;
Truth table fo OR operation:
For x = 1 1 0 0 and Y = 1 0 1 0 OR operation works as follows:
I'm trying to implement a data compression idea I've had, and since I'm imagining running it against a large corpus of test data, I had thought to code it in C (I mostly have experience in scripting languages like Ruby and Tcl.)
Looking through the O'Reilly 'cow' books on C, I realize that I can't simply index the bits of a simple 'char' or 'int' type variable as I'd like to to do bitwise comparisons and operators.
Am I correct in this perception? Is it reasonable for me to use an enumerated type for representing a bit (and make an array of these, and writing functions to convert to and from char)? If so, is such a type and functions defined in a standard library already somewhere? Are there other (better?) approaches? Is there some example code somewhere that someone could point me to?
Thanks -
Following on from what Kyle has said, you can use a macro to do the hard work for you.
It is possible.
To set the nth bit, use OR:
x |= (1 << 5); // sets the 6th-from
right
To clear a bit, use AND:
x &= ~(1 << 5); // clears
6th-from-right
To flip a bit, use XOR:
x ^= (1 << 5); // flips 6th-from-right
Or...
#define GetBit(var, bit) ((var & (1 << bit)) != 0) // Returns true / false if bit is set
#define SetBit(var, bit) (var |= (1 << bit))
#define FlipBit(var, bit) (var ^= (1 << bit))
Then you can use it in code like:
int myVar = 0;
SetBit(myVar, 5);
if (GetBit(myVar, 5))
{
// Do something
}
It is possible.
To set the nth bit, use OR:
x |= (1 << 5); // sets the 5th-from right
To clear a bit, use AND:
x &= ~(1 << 5); // clears 5th-from-right
To flip a bit, use XOR:
x ^= (1 << 5); // flips 5th-from-right
To get the value of a bit use shift and AND:
(x & (1 << 5)) >> 5 // gets the value (0 or 1) of the 5th-from-right
note: the shift right 5 is to ensure the value is either 0 or 1. If you're just interested in 0/not 0, you can get by without the shift.
Have a look at the answers to this question.
Theory
There is no C syntax for accessing or setting the n-th bit of a built-in datatype (e.g. a 'char'). However, you can access bits using a logical AND operation, and set bits using a logical OR operation.
As an example, say that you have a variable that holds 1101 and you want to check the 2nd bit from the left. Simply perform a logical AND with 0100:
1101
0100
---- AND
0100
If the result is non-zero, then the 2nd bit must have been set; otherwise is was not set.
If you want to set the 3rd bit from the left, then perform a logical OR with 0010:
1101
0010
---- OR
1111
You can use the C operators && (for AND) and || (for OR) to perform these tasks. You will need to construct the bit access patterns (the 0100 and 0010 in the above examples) yourself. The trick is to remember that the least significant bit (LSB) counts 1s, the next LSB counts 2s, then 4s etc. So, the bit access pattern for the n-th LSB (starting at 0) is simply the value of 2^n. The easiest way to compute this in C is to shift the binary value 0001 (in this four bit example) to the left by the required number of places. As this value is always equal to 1 in unsigned integer-like quantities, this is just '1 << n'
Example
unsigned char myVal = 0x65; /* in hex; this is 01100101 in binary. */
/* Q: is the 3-rd least significant bit set (again, the LSB is the 0th bit)? */
unsigned char pattern = 1;
pattern <<= 3; /* Shift pattern left by three places.*/
if(myVal && (char)(1<<3)) {printf("Yes!\n");} /* Perform the test. */
/* Set the most significant bit. */
myVal |= (char)(1<<7);
This example hasn't been tested, but should serve to illustrate the general idea.
To query state of bit with specific index:
int index_state = variable & ( 1 << bit_index );
To set bit:
varabile |= 1 << bit_index;
To restart bit:
variable &= ~( 1 << bit_index );
Try using bitfields. Be careful the implementation can vary by compiler.
http://publications.gbdirect.co.uk/c_book/chapter6/bitfields.html
IF you want to index a bit you could:
bit = (char & 0xF0) >> 7;
gets the msb of a char. You could even leave out the right shift and do a test on 0.
bit = char & 0xF0;
if the bit is set the result will be > 0;
obviousuly, you need to change the mask to get different bits (NB: the 0xF is the bit mask if it is unclear). It is possible to define numerous masks e.g.
#define BIT_0 0x1 // or 1 << 0
#define BIT_1 0x2 // or 1 << 1
#define BIT_2 0x4 // or 1 << 2
#define BIT_3 0x8 // or 1 << 3
etc...
This gives you:
bit = char & BIT_1;
You can use these definitions in the above code to sucessfully index a bit within either a macro or a function.
To set a bit:
char |= BIT_2;
To clear a bit:
char &= ~BIT_3
To toggle a bit
char ^= BIT_4
This help?
Individual bits can be indexed as follows.
Define a struct like this one:
struct
{
unsigned bit0 : 1;
unsigned bit1 : 1;
unsigned bit2 : 1;
unsigned bit3 : 1;
unsigned reserved : 28;
} bitPattern;
Now if I want to know the individual bit values of a var named "value", do the following:
CopyMemory( &input, &value, sizeof(value) );
To see if bit 2 is high or low:
int state = bitPattern.bit2;
Hope this helps.
There is a standard library container for bits: std::vector. It is specialised in the library to be space efficient. There is also a boost dynamic_bitset class.
These will let you perform operations on a set of boolean values, using one bit per value of underlying storage.
Boost dynamic bitset documentation
For the STL documentation, see your compiler documentation.
Of course, you can also address the individual bits in other integral types by hand. If you do that, you should use unsigned types so that you don't get undefined behaviour if decide to do a right shift on a value with the high bit set. However, it sounds like you want the containers.
To the commenter who claimed this takes 32x more space than necessary: boost::dynamic_bitset and vector are specialised to use one bit per entry, and so there is not a space penalty, assuming that you actually want more than the number of bits in a primitive type. These classes allow you to address individual bits in a large container with efficient underlying storage. If you just want (say) 32 bits, by all means, use an int. If you want some large number of bits, you can use a library container.