3 Simple Ways to
Share What You Make

With Instructables you can share what you make with the world — and tap into an ever-growing community of creative experts.

PhotosPhotos

Share one or more photos of a project, recipe, or whatever you've made, quickly and easily.

Step by StepStep-By-Step

Share your step-by-step photos with text instructions of what you made so others can do it too!

VideoVideo

Share your how-to video. You'll need your embed code from a video site such as YouTube.

A complete starter guide to AVRs

A complete starter guide to AVRs
Have you played with Arduino's and now have a taste for microcontrollers?
Have you tried to go beyond Arduino but got stopped by the dense datasheets?

This is the instructable for you!
I was working on an instructable for the epilog contest which would wirelessly link two smoke alarms.
I wrote all the code and prototyped on a breadboard.
As the deadline drew near I built the hardware but no matter what I tried I couldn't make it squeeze into the tiny space available.

As I wallowed in self pity, I thought of what a waste it would be for all that I learnt to be left in my head, so here it is!

This instructable will take you from the basics of bitwise manipulation to making good use of standard AVR peripherals such as timers, interrupts & serial communications.
It will also cover common extras such as Infrared remote controls, radio communications and more.

So jump in, skip what you know and brush up on what you need to.
Create the breadboard projects presented and learn new things!

 
Remove these adsRemove these ads by Signing Up
 

Step 1Binary and bitwise operations

Binary and bitwise operations
 Before we dive into datasheets we need to understand some low level concepts that you will use every time you want to do anything interesting with a micro.

Lets start at the most basic, the bit.
A bit is the smallest unit of data to a computer, it is either a '1' or a '0'.
In other words it is either on, or off.

To do anything useful in a computer though, a single bit is not enough, so they are combined into bytes.
A byte is 8 bits together, and using binary counting a byte can either store 0-255 (256 numbers) or -128 to 128.
For example:
00000000 = 0
00000001 = 1
00000010 = 2
00000011 = 3
00000100 = 4

Just like when you are counting in decimal (base 10, as in 10 fingers!), when you go past  9, you put a 1 in front and put the second digit as 0.
It is the same with binary, except as there is only 0 or 1, when you go past '1' you put a 1 in front and a '0' as the second digit.

The features of a microcontroller are controlled by registers. In the case of an 8-bit AVR they are either 8 or 16 bits long.
Instead of the whole thing representing a number however, each bit determines if a certain feature is on or off.

We will look at a lot of different registers later, but for now let's make up an imaginary one so we can see how to manipulate them.


Imagine we find a register in the datasheet that connects to 8 LEDs called LEDREG.
Each bit in the register is either a 1 or a 0, the LED is either on, or it is off.

We could turn on the first LED like so:
LEDREG = 1; // 00000001
2nd LED
LEDREG = 2; //00000010

But what about the 3rd LED?
If we did this:
LEDREG = 3; //00000011
We wouldn't get the 3rd LED, we would get LED 1 & 2 lit up instead!

With registers it isn't the number that matters, but what the underlying bits look like.
The 3rd LED would look be like this:
LEDREG = 4; //00000100

If you wanted to turn on different patterns of LEDs you could work out all 256 combinations, but that would be tedious.
There is a better way!

Boolean logic
Computers at the lowest level work with something called boolean logic.
They use logic gates to combine binary numbers.
For example an AND gate will only output a 1 if both inputs are 1.
An OR gate will output a 1 if either of it's inputs are 1.

Have a look here:
http://www.electronics-tutorials.ws/boolean/bool_6.html

It shows the 'truth tables' for common logic gates.

So, what use is all this to us?
We can make use of these logic gates directly using bitwise operators

Bitwise operations

Lets say we already have the 3rd LED on:
LEDREG = 4; //00000100

How can we turn on the first LED?
We could put in the value of 5 (00000101) but we don't want to have to figure out which combination each time.
Instead we can use an OR operator like so:
LEDREG = LEDREG | 1;
What this means is this
00000100 OR
00000001
--------------
00000101


The OR operator lines up each bit and if it is on in either byte, it will be on in the output.
A quicker way to write "LEDREG = LEDREG | 1;" is:
LEDREG |= 1;

You can also chain your operators like so:
LEDREG |= 1 | 2;
This will come in handy when we learn shift operators.

What if you wanted to toggle all of the LEDs?
You could use a NOT operator:
LEDREG = ~LEDREG;

A NOT operator flips all the bits, so you get:
00000101 NOT
--------------
11111010


Next lets look at an AND operator.
AND is used to mask a value.
That is, it is used to blank out sections of a byte but keep the value of the unmasked section, like so:

11111010 AND
00001111
-------------
00001010

You can use an AND to turn off a whole group of LEDs without changing the state of the rest.
In the above example it would be used like:
LEDREG &= 15; //00001111

One more useful operator before we move on is the XOR.
XOR stands for eXclusive OR.
It is similar to an OR gate, however if both bits are on, then they are turned off.
For example:

LEDREG ^= 15;

00001010 XOR
00001111
-------------
00000101


Now, by themselves the operators are limited, you still need to convert from binary to the equivalent decimal number.
This is where shift operators come in

Shift operators
A shift operator simply shifts all the digits left or right.

For example a left shift of 1:
x = 5 << 1;
gives you x == 10
in binary that is:
00000101 <<
-------------
00001010

A right shift simply moves the bits to the right:
00001010 >>
--------------
00000101

Any bits at the ends are simply lost (or stored in a carry register, but lets ignore that for now!)
A shift operator can be used as a very fast multiplication & division, as long as you are happy with only multiplying / dividing by powers of 2, eg:

x << 1 == x*2
x << 2 == x*4
x << 3 == x*8

Shifts are used a lot in setting registers.
Lets return to our LED example.

If we want to set the 6th bit, instead of working out what number that would be and then ORing it with the register, we can use a left shift like so:
LEDREG |= (1<<5);

NB: It is '5', not '6' as we only need to move the '1' 5 times.
In binary it would look like so:

00000001 <<
-------------
00100000 

Which is then ORed with the register like so:

00000101 OR
00100000
-------------
00100101


In datasheets, the position of a certain bit is usally given a name such as "RXEN" which is used to turn on receive mode in the serial peripheral and "TXEN" for transmit.
Together they would look something like this:
UCSRB |= (1<<RXEN) | (1<<TXEN);

This should be enough to get you started, lets move onto some real examples!


« Previous StepDownload PDFView All StepsNext Step »
7 comments
Nov 29, 2011. 7:56 PMhardwarehank says:
Fantastic. Thanks for writing this. I'm disappointed that the MAKE/arduino community isn't more supportive of arduino programmers growing into AVR programmers (but I guess they'd make less money if that happened). Arduino should be a gentle introduction to AVR, IMHO. Once you know how to write a sketch, the C program for AVR is basically exactly the same, and the AVR tools make the chips pretty easy to work with.

I bought a USBTinyISP to program my chips, and built it - that was good fun. Then, I learned a bit more about AVR, and built the VUSBTinyISP, which is an instructable. I highly recommend both of these, since they'll teach you all about burning chips.
Dec 1, 2011. 5:28 AMhardwarehank says:
Yeah I've messed with a ATTiny2313, ATTiny85s, and a few others. The 6-pin chips are challenging. What bothers me isn't arduino vs. AVR really; it's more the marketing push behind arduino. I applaud things like Freeduino, which take an arduino programmer and throw them into chip programming.

I was really turned off by the latest issue of MAKE. They had a 12-year-old kid write in about how he was doing really cool stuff with raw AVR in the Q&A section. Reading this, I was extremely happy, since obviously this is superior to arduino development. Their response? "Go find some arduino resources here and read our biased article about how arduino is better than everything else." That was the entire response. No commendation, just a quick "if you're thinking about doing any sort of microcontroller development, you better do it with arduino." That's anti-intellectual.

So, thanks again. Hopefully people will see the light once they've spent hundreds of dollars on about $10 worth of AVR chips.
Mar 24, 2011. 5:09 AMtodell-1 says:
I could not find the referred appendix. Link?
Mar 24, 2011. 5:02 AMtodell-1 says:
Where is the appendix mentioned in step 3?

Pro

Get More Out of Instructables

Already have an Account?

close

All Steps Viewing
View all steps of an Instructable on the same page when you're a Pro Member.

Upgrade to Pro today!
52
Followers
4
Author:NathanWilliams
Software engineer, using electronics and micro controllers as a hobby to keep me sane!