Arduino Playground is read-only starting December 31st, 2018. For more info please look at this Forum Post

AVR Code

The Arduino environment is based on Atmel Atmega microcontrollers. The AVR language is a "C" environment for programming Atmel chips. Much of the Arduino language is written with AVR constants and functions and there are many things that are still not easy to accomplish with the Arduino language without using some AVR code.

The good news is that because the Arduino environment uses GCC to compile code, all of the port and register variables found in the Atmega 168 datasheet and tutorials on AVR code assembly language are supported when using the Arduino IDE.

This page is an attempt to document the most useful AVR functions and code snippets.

Inline Assembler Cookbook

http://www.nongnu.org/avr-libc/user-manual/inline_asm.html

Interrupts

To disable interrupts:
 cli();                // disable global interrupts

and to enable them:  
 sei();                // enable interrupts

Note that the millis timer, and serial communication will be affected by disabling interrupts. The delayMicroseconds() function disables interrupts while it is running.

Timing

The Arduino delayMicroseconds() function creates the shortest delay possible from within the Arduino language. The shortest delay possible is about 2 us (microseconds).

For shorter delays use assembly language call 'nop' (no operation). Each 'nop' statement executes in one machine cycle (at 16 MHz) yielding a 62.5 ns (nanosecond) delay.

  __asm__("nop\n\t"); 

  __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");  \\ gang them up like this

Port Manipulation

Manipulating ports and pins with AVR code is faster than using Arduino digitalWrite() function. It is also possible to make two pins change states at exactly the same time. You can read about it here.

Setting Bits in Variables

cbi and sbi are standard (AVR) methods for setting, or clearing, bits in PORT (and other) variables.

You will find them in lots of AVR code, posted in the forum and elsewhere. Both need to be defined within an Arduino sketch, so you'll need to paste in the following #define headers at the top of a sketch.

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif 

To use them pass them a PORT variable, and a pin to set (or clear).