Accessing registers in Arduino?

In all the Arduino docs I don’t see any mention of registers. I’m sure this is because the beginner (the target of Arduino) probably won’t need such low-level access.

But once one sees the advantage of using the timer/counter or other features of the AVR, where does one look for how to do this within Arduino? All the details are in the Atmel manual, but nothing I can find in Arduino docs mentions how to do this.

Specifically, I want to read and reset TCNT1, the 16-bit timer/counter register in the ATmega168.

I found a code sample that sets bits in the timer/counter control register thus:

   TCCR2 |= (1< <CS22);          //Timer2 Settings: Timer Prescaler /64,
   TCCR2 &= ~((1<<CS21) | (1<<CS20));       
   TCCR2 &= ~((1<<WGM21) | (1<<WGM20));          // Use normal mode  
   ASSR  |= (0<<AS2);          // Use internal clock - external clock not used in Arduino 
   TIMSK |= (1<<TOIE2) | (0<<OCIE2);          //Timer2 Overflow Interrupt Enable

I understand all the bitwise stuff. But these register names aren’t declared anywhere in the sample sketch. Are these names automatically linked to the registers without need for declaration? Or should they simply be declared as INT as ordinary variables are?

Any pointers to how to use registers on a simple level in Arduino would be greatly appreciated.

Thanks,
Dave
Arduino 0011
Mac OS X 10.5.2

I read your other post about TCNT1, and this one too.

I'm not an expert about this, but since nobody answered you, I'll tell you my opinion. I think you don't need to declare the registers; You can find many examples of the use of registers inside a sketch. Search in www.arduino.cc search box (not in the forum search), and you'll find the examples.

Adilson’s opinion is quite correct. The registers are all pre-declared for you so you can use them in a sketch.

This is done ‘under the covers’ by the arduino build process, which adds various header files when you compile the sketch. The actual header is determined by the hardware selected in the IDE, the register names are different for different target chips.

If you want to know the gory details, here is the how the appropriate register names are derived:

Compiling a sketch creates a file in the applet directory that includes “WProgram.h”

  • WProgram.h includes <avr/interrupt.h>
  • interrupt.h includes <avr/io.h>
  • io.h declares the generic registers and includes a chip specific file which for the ATmega168 is <avr/iom168.h>
  • iom168.h defines a few ATMega168 registers and includes <avr/iomx8.h>
    which has the definitions common with other family members of this chip

So if you look in the following directory in your Arduino distribution directory:
hardware\tools\avr\avr\include\avr\iom168.h
you can view all the register names that the compiler knows about.

Ah, that's good info -- thanks mem!

What's the thinking on using the SFR format of macros for referring to registers...?

Or, to put it another way, what's the preferred way to refer to ports etc. to allow portability between various models of processors?

cheers

The SFR macro allows the C compiler to access the registers as if they were variables. The registers are actually addresses in the io space.

Testing for conditional defines in your source code is a common way to cope with different hardware. You can do something like

if defined (AVR_ATmega168)

// do something specific to the ATmega168

elif defined (AVR_ATmega8)

// else something specific for the ATmega8

The processor define that is tested is the one selected in the Arduino IDE.