What's the syntax for writing to ATMega TCCR1A and OCR1A registers?

I'm a newbie to Arduino, and haven't coded in several decades. I'm learning C and its Arduino flavor as I go, which is certainly part of my problem.

I can't be the first with this issue - can you point me to a page that will help me?

I've tried hard for over 8 hours of searching with every keyword and phrase I know, but failed to find anything on this site that tells me how to write to the Timer 1 hardware control Registers on the Uno R3's ATMega328 chip. digitalWrite() seems to be purely a pin-oriented function; there has to be byte- or word-wise read/write capability for internal chip hardware control registers.

The Language Reference doesn't help. I figured there'd be something on reading and writing registers in the Constants section, ideally just a simple sentence like "Every register and bit name in the Atmel data sheet is implemented as a constant in Library XXXX". or a memory space mapping of the registers. Not that I could find.

IN CASE YOU'RE INTERESTED - WHAT I'M DEVELOPING - AND WHY I NEED THIS INFORMATION I need to set up a variable 56-60 Hz square wave for a telescope tracking motor 115VAC frequency control. The challenge is that I need very fine variations in that range. The output will control a 12VDC-115VAC inverter that powers a 115VAC synchronous motor that's geared to the telescope's equatorial axis.

Using a Uno R3, I plan to set up Timer 1 to toggle on OCR1A, and drive that square wave of the chip's pin 15 and the board's pin 9 to the frequency control input of the power inverter. With a prescaler of divide-by-8, I should get out a proper frequency with OCR1A input values in the neighborhood of 16,000, the actual values varying depending on: (a) Compensation for imperfect frequency accuracy of each board's particular crystal, and (b) Whether I'm tracking stars, the sun or the moon, which move across our field of view at three different angular rates.

So I want to be able to: (1) Set up Timer 1 for /8 prescaling, count up, toggle-on-match / reset, and output a square wave on pin 15 (2) Load a start value into OCR1A, then increment, decrement, or otherwise rewrite it during the telescope calibration process.

Help, please?

TCCR1A = 0b00001111;


Thanks, Robin! That answers the immediate question, but is can you link me a source that documents all of the registers?

RTFM http://www.atmel.com/Images/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_Datasheet.pdf

Study the relevant Atmel datasheet - for the Atmega 328 if you are using an Uno.


Thanks, Robin2 and Whandall.

Sorry for the slow reply - Christmastime and the grandkids are here - my priorities are clear.

As I re-examined the 328 data sheet, I now realize that the register addresses are "Offsets", and the addresses of Control Registers TCCR1A, TCCR1B and TCCR1C, are offsets 0x80, 0x81 and 0x82, correct?

Now, all I have to do is figure out how to write to those registers using those offsets. Haven't yet found an instruction in the reference that tells me how to write a value to a register.

The registers are memory mapped. ;)

So you will often see something like 'volatile byte* SOMEREG', the value of the pointer is your offset.

Robin2: TCCR1A = 0b00001111;


Sorry, learning opportunity. Doesn't this show the pattern for all register access? If you know the names.

I ask because you mention "volatile", "pointer", "byte" & "offset" and it seems like I could skip this for now.

I understand that if I live long enough I'll want to know, but for now won't both the above for setting and this obvious extension work?

myCopyOfThatRegister = TCCR1A;

Results varying by whether the bits in the register are read/write &.

-- a7

Doesn’t this show the pattern for all register access? If you know the names.

Yep. All the offsets, “volatile”, and sizing are handled by the compiler and the definitions that are provided via
#include <avr/io.h>” (which is done by Arduino.h in the core, so you probably don’t need to do it again.)
The compiled knows how to use the “set bit instruction” when it can, the “IN/OUT” instructions when those are possible and LDD/STD when it must. You just use the names from the datasheet in assignment statements…

There is an example in this thread: http://forum.arduino.cc/index.php?topic=443343.msg3051379#msg3051379 You have to adapt it to suit your desired frequency.

westfw - Thanks!!

You finally gave me the clarification I was asking for. That was exactly what I needed to know.. That's not documented anywhere that I've seen, and that puzzles me.

Well, here: http://nongnu.org/avr-libc/user-manual/group__avr__sfr.html And related pages. It doesn't really say very much before diving into more complex internal details, but it's the best I could find. In general, the avr-libc documentation is more useful than the gcc documentation, because the latter is very general to nearly all versions/targets of the compiler.

So, will you experts please confirm my summary from this thread. I want to make sure I understand correctly, since there's nothing like what's below the Arduino introductory material:

You can write to a hardware control register on your Arduino board's microcontroller chip by simply using the register's name from the chip manufacturer's data sheet.

For example: The Arduino Uno uses the ATMega328 microcontroller. The Atmel data sheet for the ATmega328 describes Output Compare Register A for its 16-bit Timer 1 using the register name "OCR1A".

The following will write a trigger value (decimal) into Output Compare Register A for Timer 1, and then read out that value to check it:

unsigned int triggervalue = 16327; unsigned int checkvalue = 0; ... ... OCR1A = triggervalue; // causes the current 16-bit value of 'triggervalue' to be written into OCR1A checkvalue = OCR1A // causes the current value of OCR1A to be written to the variable 'checkvalue' ...



Thanks, Robin2! Over and out.