Problem writing high byte

Hello, I have a little problem with 16 bit registers.

Arduino: Leonardo
IDE Version: 1.0.1
gcc version 4.7.2 (GCC)

This is my Code:

void setup()
{
  Serial.begin(115200);
  
  delay(3000); //enough time to start the serial monitor
  
  OCR3A = 15000;
  Serial.println(OCR3A);
}

void loop()
{

}

I was trying to configure the Timer3 for hours until i found out that no high bytes can be written.
The above code displays 152, this is the content of the OCR3AL register.

I also tried to write the low and high byte separately (the high byte first) or read the bytes separately (low byte first) but it doesn't work.
Another thing I tried was not to read the register but comparing it.

OCR3A = 15000;
if(OCR3A == 152)
  Serial.println("Hello World");

This code prints "Hello World".

OCR3A isn't the only 16 bit register that doesn't work all other 16 bit register do neither.

Thanks for your help,
Jonas

16 bit registers on an 8 bit chip? There's no such thing.

Address OCR3AL and OCR3AH separately, and do it in the right order:

Each 16-bit timer has a single 8-bit register for temporary storing of the high byte of the 16-bit access. The same Temporary Register is shared between all 16-bit registers within each 16-bit timer. Accessing the low byte triggers the 16-bit read or write operation. When the low byte of a 16-bit register is written by the CPU, the high byte stored in the Temporary Register, and the low byte written are both copied into the 16-bit register in the same clock cycle. When the low byte of a 16-bit register is read by the CPU, the high byte of the 16-bit register is copied into the Temporary Register in the same clock cycle as the low byte is read.

Not all 16-bit accesses uses the Temporary Register for the high byte. Reading the OCRnA/B/C 16-bit registers does not involve using the Temporary Register.

To do a 16-bit write, the high byte must be written before the low byte. For a 16-bit read, the low byte must be read before the high byte.

The AVR compiler knows all about 16 bit timer registers and compiles the right byte loads
in the right order for reading and writing them - from the datasheet:

The same principle can be used directly for accessing
the OCRnA/B/C and ICRn Registers. Note that when using “C”, the compiler handles the 16-bit
access.

I'm worried by the OP mentioning gcc version number, should be using avr-gcc instead.

Perhaps something is misconfigured for the ATmega32U4?

16 bit registers on an 8 bit chip? There's no such thing.

I beg to differ.
Every 8 bit processor has at least one 16 bit register, the address pointer. In addition many processors including the one in the Arduino has 16 bit registers in it.
The Z80 and 8080 both have 8 bit registers that can be combined to form an 8 bit register as well as the two straight 16 bit registers on the Z80.
So yes you can have 16 bit registers in an 8 bit processor.

Grumpy_Mike:

16 bit registers on an 8 bit chip? There's no such thing.

I beg to differ.
Every 8 bit processor has at least one 16 bit register, the address pointer. In addition many processors including the one in the Arduino has 16 bit registers in it.
The Z80 and 8080 both have 8 bit registers that can be combined to form an 8 bit register as well as the two straight 16 bit registers on the Z80.
So yes you can have 16 bit registers in an 8 bit processor.

All right, mister pedantic!

What I meant was "16 bit ACCESS to 16 bit registers"!

Registers in this context refers to SFRs - Special Function Registers. They are ALL 8 bit, as there is only an 8-bit data bus. Yes, some are, as I already showed, combined internally into 16-bit latches, but the interface to them is, has always been, and will always be 8 bit.

The 16 bit counter modules have a special arrangement so that they can be atomically
written and read - to get this to work properly they must be read or written in pairs in
the right order (see datasheet).

The C compiler should be providing a 16 bit pseudo-register for you (and compiling
the access as the right two 8-bit accesses). Thus from C code its a 16 bit register
(unless you try to access it both in an interrupt routine and from the main code -
in that case you have to disable interrupts around the accesses in the main code).

The original problem seems to be an issue with the compiler, therefore (no interrupts
are involved in the example given).

I see a similar problem with TIMER 1 with an UNO (Arduino 1.0.5, Mac OS X 10.91), except the write succeeds or fails depending upon its location in the code (yuck).

void setup() {
  Serial.begin(28800);
  ICR1   = 0x3d09;
  //OCR1A  = 0x39fb;  // write fails here -- print below gives 0xfb
  TCCR1A = 0xc2;
  //OCR1A  = 0x39fb;  // write fails here -- print below gives 0x1fb (sic)
  TCCR1B = 0x1d;
  OCR1A  = 0x39fb;    // write works here

  Serial.println("");
  Serial.print("ICR1:  0x");
  Serial.println(ICR1, HEX); 
  Serial.print("OCR1A: 0x");
  Serial.println(OCR1A, HEX); 
}

--Wayne

If you set the timer mode first then you know which mode the timer is in when OCR register is written,
perhaps that's important, I'd have to look at the datasheet to see if OCR1A can be overwritten by the
hardware in some modes. For instance changing to an 8 bit mode might zero the high part automatically.

I've only used 16 bit values with timer1 when I've put it in a 16 bit mode. I would never have assumed
that changing mode leaves the other registers untouched BTW, too large an assumption to make. Set
the mode and then all the registers you use... Since the mode bits are in two separate registers you
have to change mode by two 8 bit writes, meaning that for some time the timer may be in a different
mode from the one you want or the one it was in before.

Check out the datasheet (page 136 on the version I have here).

As MarkT says, the mode is important. The sheet says "Update of OCR1x at" followed by IMMEDIATE, Top or BOTTOM depending on the mode. So you can't expect to read back what you just wrote a couple of machine cycles later (necessarily).

Note this reference to:

The double buffered Output Compare Registers (OCR1A/B) are ...

Double-buffered. There is your clue.

Double-buffered. There is your clue.

Thanks! I didn't pay enough attention to that part of the data sheet.

The OCR1x Register is double buffered when using any of the twelve Pulse Width Modulation (PWM) modes... The double buffering synchronizes the update of the OCR1x Compare Register to either TOP or BOTTOM of the counting sequence.

--Wayne