GICR |= (1<<INT0)

hello there,

GICR |= (1<<INT0)

i am fiddling with this expression. It is used to set a single bit in the GICR register, but i have no clue about how that is done.

|= means logic NOR

but from there i'm confused.

anyway, this is the code to set the bit, but how to set it again to 0? not by changing the one with a zero. i've tryed that.

The above expression enables the INT0 interupt on the arduino, but i want to disable it further down the code.

The |= is called the "bitwise-OR assignment operator". Doing this:

x |= y;

is the same as the following:

x = x | y;

Both expressions do a bitwise OR of the values of x and y, then store the result in x.
What is a bitwise OR? That means each bit of both x and y are independently processed according to this rule: if either or both bits are 1, the result is 1, but if both bits are 0, the result is 0.

The expression like (1<<INT0) is called a left-shift. It literally causes the bits in the left operand to be shifted left by the count specified by the right operand. Because the computer represents all numbers internally using binary, doing (1<<A) is the same as raising 2 to the A power. For example:

1 << 0 == 1
1 << 1 == 2
1 << 2 == 4
...
1 << 8 == 256
etc

This might make more sense if we express everything in binary, as is now supported by Arduino:

1 << 3 == B1000

So, when I look in various header files, I find:

#define INT0 6

Now let us consider what happens when you do: GICR |= (1<<INT0). Suppose the current value stored in GICR (in binary) is 00000011. The value of (1<<INT0) is (1<<6), which in binary is 01000000. So when you do a bitwise or of 00000011 and 01000000, you get: 01000011. Then this value is stored in GICR. So the net result is that you have made sure that the given bit is set to 1 inside GICR.

So now, the other part of your question: how do you turn that bit back off? To do this, we need to introduce 2 more operators: bitwise AND, and bitwise NOT (also known as one's complement). The expression

x &= y;

is the same as:

x = x & y;

In both cases, a given bit in both x and y must be 1 for a 1 to end up being stored back in x. For example, expressed in binary, 00001111 & 01010101 == 00000101.

The bitwise NOT operator is a tilde character '~'. It is a unary operator, meaning it operates only a single value that follows it. In binary, the value of ~01000000 == 10111111. So, to answer your question, the way to turn off a bit would be something like:

GICR &= ~(1<<INT0);

Let's see how this works: Suppose that GICR is 01000011, because you have already set the bit, and now you want to turn that bit back off. The value of (1<<INT0), as we have already seen, is 01000000. So the value of ~(1<<INT0) is 10111111. Then when we AND 01000011 with 10111111, only the bits that are 1 in both will be 1 in the result, which is 00000011.

I hope this helps explain the bitwise operators in C++.

This is by far the most comprehensive answer I ever had. Absolutely fabuleus! I found it very difficult to search the net with this expression to look for a answer like this.

maybe we should put this in the FAQ somewhere.

Thanx a lot.

Hey Macsimski,

I'm glad I could be of help! I have been programming in C/C++ for over 15 years now, so it is fun to use some of that experience to help other people.

On the other hand, one thing I have no experience with is how the Wiki stuff here is used... I don't know what is appropriate or how to format things. I would be willing to take the stuff I wrote here and expand it for a general FAQ entry, but I have no idea where to begin. Can someone "official" at Arduino help me?

  • Don

hey Don,

there's a 'sandbox' page in the wiki where you can just fool around and learn how the wiki works.. you can change the page any way you like. Formatting rules appear just below the text entry window when you're editing. Once you're ready to make a page, find the appropriate section of the wiki, and type in the URL you'd like to use, and it will says something liek the page doesn't exist; just click edit on that page, and voila, the page exists!

D

OK, I have started a new page in the Playground that expands upon this topic:

http://www.arduino.cc/playground/Code/BitMath

I am not finished yet; I want to write up a section at the end showing how to encode/decode multiple pieces of binary data inside bytes to save memory, but I have been writing for hours now and I need a break.

I would love it if everyone would take a look and let me know...

What is confusing?
What is helpful, or explained something you did not already know?
Are there other examples of weird bit-manipulations you have seen that you do not understand?
Are there any typos or mistakes?
Is this article formatted correctly on your browser? (I used Firefox v 2.0.0.1)

Thanks,

  • Don

Nice reader!

the browser should'nt matter, because the formatting is all done by the wiki engine. The only thing to take care of is that if you include code, it will not be wrapped on your page.

anyway, it looks fine here in camino and safari

HI!

I've got error vhen i use this code:

  const prog_uint8_t BitMap[5] = {   // store in program memory to save RAM
        B1100011,
        B0010100,
        B0001000,
        B0010100,
        B1100011
    };

error says

error: 'prog_uint8_t' does not name a type In function 'void blink()':

code for function blink

            byte data = (byte) pgm_read_byte (&kombinacije1[x]);   // fetch data from program memory
            for (byte y=0; y<7; ++y) {
                if (data & (1<<y)) {
                    digitalWrite(y+6, HIGH);
                } else {
                    digitalWrite(y+6, LOW);
                }
            }

Hello ccdust,

My guess is that you need to add this to the top of your source code:

#include <avr/pgmspace.h>