Download as pdf or txt
Download as pdf or txt
You are on page 1of 4

5/20/2014 C BIT MATH - QEEWiki

https://sites.google.com/site/qeewiki/books/avr-guide/c-bit-math 1/4
QEEWiki
Home
My Projects
Leonard Birchall Exhibit
PLC [Hardware Project]
Q's MAX7456 Img Gen
Briefcase Controller [In
Development]
My Books
AVR GUIDE
Elect. Eng. for Techs
My Bike
Shadow RS Saddlebag
Mounts
Viper Security System
Fail
SolidWorks Projects
Datasheet Library
Friends Tutorials
Components
Usefull Engineering Stuff
Resources
Sparkfun
Arduino Reference
EEVBlog
Fritzing Projects
Ada Fruit
Pololu
Atmel
Atmega8 Datasheet
ATMega168/328
Datasheet
AVR Freaks
Software Links
None EE Faves
Minecraft !!!
Escapist Magazine
Ongoing History of New Music
There Will Be BRAWL
White Wolf Ent.
The Game Overthinker
My Books > AVR GUIDE >
C BIT MATH
BIT OPERANDS:
The most confusing part of micro controller programming is the fact that we have to manipulate data at a
bit level. While that may seem scary at first it becomes second nature over time. The problem itself is that
there is no really good examples of how this works .... hopefully this chapter will change that.
Most of the time we work with 8 bit data within the AVR (with the exception of the 10 bit ADC).
Understanding bit math gives us a very powerful tool that reduces a lot of manual work.
So, were do shall we begin? How about the Bit shift function.
BIT SHIFT FUNCTIONS ( << and >>)
The bit shift function does just what it says it does, it shifts the data over to the left or over to the right
by one bit. The Bit Shift Function is the most used bit math function when dealing with the AVR.
So lets see this in action in mathematical format. Please note that I will put a space every 4th character
to make the numbers easy to read, so 00011000 will read as 0001 1000.
Bit shift left:
(0000 0001 << 2) = 0000 0100
(0000 0001 << 3) = 0000 1000
(0000 0010 << 1) = 0000 0100
(0000 1000 << 5) = 0000 0000

Ok what happened in that last example? why does the math come out to be 0000 0000 and not 1 0000
0000, well this is actually what happens in an 8 bit register if you shift bites too fare over they basically fall
off the edge of the world never to bee seen again. So be careful not to shift bits too far, as this will end up
loosing data.
Bit Shift Right:
(0000 0010 >> 1) = 0000 0001
(0001 0000 >> 3) = 0000 0010
(1000 0000 >> 0) = 1000 0000
(0000 0001 >> 1) = 0000 0000
Did I do something strange again? in the 3rd example perhaps? nothing moved did it, because as you can
see, the byte was shifted by 0 spaces. But I bet you noticed that the bit in the last example fell of the ....
well beginning of the world this time.
Bit Shifts in C:
So now that we have seen a bit of bit shifting in the mathematical model lets take a look at it in code.
i = 1; // i = 0000 0001
i = i << 2; // i is now = 0000 0100
i = i >> 2; // i is now = 0000 0001
See its not as hard as it may seem. However, if you don't understand the theory so far please go back
and re-read this tutorial or post a question, the following theory will build upon this.
There is one final thing to note about bit shifts, they could be used to multiply or divide any number by
any power of 2 (ie 2, 4, 8, 16, 32 ... etc). Lets see this in action:
i = 10; // i = 0000 1010
i = i >> 1; // i = 0000 0101 = 5 (Shift >> by 1 to divide by 2)
i = i << 2; // i = 0001 0100 = 20 (Shift << by 2 to multiply by 4)
Now this is useful because multiplication and division use 2 clock cycles, while bit shifting uses 1, so start
Search this site
5/20/2014 C BIT MATH - QEEWiki
https://sites.google.com/site/qeewiki/books/avr-guide/c-bit-math 2/4
Now this is useful because multiplication and division use 2 clock cycles, while bit shifting uses 1, so start
replacing that / and * with a bit shift the next time you need to divide or multiply by 2s 4s and 8s and save
those cycles.
So whats next?
NOT (~)
Not is fairly simple, it basically flips the bit to its opposite.
~0 = 1
~1 = 0
If used in a big register if will change each individual bit to the opposite state.
~ 0000 1111 = 1111 0000
Not in C:
Not is very simple to use, so here it is.
i = 0b10101010;
i = ~i; // i is now 01010101
i = 0b11111111;
i = ~i; // i is now 0
AND ( & )
Mathematically and is fairly easy, you compare 2 numbers together, and if they are both TRUE(1) then
your answer is TRUE(1). I like to remember this as: If a AND b is TRUE(1) then the answer is TRUE(1).
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
On a bit level it looks fairly easy, however, when we expand the length of bits is looks a bit confusing, so
it is sometimes best to rewrite the byte and put them one on top of the other.
15 & 170 = 10
0000 1111 & 1010 1010 = 0000 1010
0000 1111
& 1010 1010
----------
0000 1010
153 & 170 = 136

1001 1001 & 1010 1010 = 1000 1000
1001 1001
& 1010 1010
----------
1000 1000
6 & 11 = 2

0000 0110 & 0000 1011 = 0000 0010
0000 0110
& 0000 1011
----------
0000 0010
And in C:
As before this function is fairly simple when you see it in C:
i = 6;
i = i & 11; // 6 & 11 therefore i = 2
// see last math example above for details
Now, here is where things get a bit confusing, in micro controller programming you will often see the above
code being abbreviated by using &=
5/20/2014 C BIT MATH - QEEWiki
https://sites.google.com/site/qeewiki/books/avr-guide/c-bit-math 3/4
i = 153;
i = i & 170; // same as i = i & 170 or i = 153 & 170
// see second last math example above for details
OR and XOR ( | and ^ )
This might be a bit confusing, there are 2 types of OR functions, the INCLUSIVE OR ( | ) and the
EXCLUSIVE OR ( ^ ).
OR (INCLUSIVE):
The Inclusive OR is always referred to simply as OR.
The OR function checks to see if ether bit is a 1 so basically your asking is variable a OR b true, and
include both true (get it include, inclusive? that's how I always remember it)
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1
So lets see this in action using a 8 bit number. Once again, I will re-arrange the register one on-top of
the other to make it easier to see what is happening.

15 | 170 = 175
0000 1111 | 1010 1010 = 1010 1111
0000 1111
| 1010 1010
----------
1010 1111
153 | 170 = 187

1001 1001 | 1010 1010 = 1011 1011
1001 1001
| 1010 1010
----------
1011 1011
6 | 11 = 15

0000 0110 | 0000 1011 = 0000 1111
0000 0110
| 0000 1011
----------
0000 1111
OR in C:
So without delay here is what OR looks like in C. As always I use the same numbers in my C code as I do
in my mathematical model above.
i = 15 | 170; // i is now equal to 175 (see above example for the math)
i = 6; // lets set i to 6 for our next example
i = i | 11; // i is now 15 (see above for the math)
XOR:
XOR is the same as OR but it excludes both true values, in other words its only true if both values are
different.
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0
Without delays, lets see the mathematical model once again.

15 ^ 170 = 165
0000 1111 ^ 1010 1010 = 1010 1010
0000 1111
^ 1010 1010
----------
1010 0101
153 ^ 170 = 51

1001 1001
^ 1010 1010
5/20/2014 C BIT MATH - QEEWiki
https://sites.google.com/site/qeewiki/books/avr-guide/c-bit-math 4/4

1001 1001 ^ 1010 1010 = 0011 0011
^ 1010 1010
----------
0011 0011
6 ^ 11 = 13

0000 0110 ^ 0000 1011 = 0000 1101
0000 0110
^ 0000 1011
----------
0000 1101
XOR in C:
And for the final time here is what the XOR logic looks like in C.
i = 15 ^ 170; // i now equals 165
i = 6; //sets set i to 6 for our next example
i = i ^ 11; // i now equals 13 (see above)
Well, that's all, our next chapter will cover advance Bit math functions, which in lamest terms covers how
to use multiple functions together in order to achieve common AVR tasks such as setting a single pit in a
register.
I hope that I was able to shine some light on a difficult topic. This was the topic that gave me the most
amount of problems when I started out with micro controllers.
And now I'm off to watch cartoons!!!!
Cheers
Q
Comments? Questions? Problems with content? q.qeewiki@gmail.com
Sign in | Report Abuse | Print Page | Powered By Google Sites
Comments
You do not have permission to add comments.

You might also like