I am using MPLAB X IDE version 5.43 to develop an embedded project for a PIC18F8722 microcontroller.
It has a timer TMR0 which can be configured to be 32 bits.
I had lots of statements:
TMR0L = 0;
TMR0H = 0;
that I wanted to simplify (i.e., replace) to:
TMR0 = 0;
The 3 identifiers above are defined through macro constants in the included file #include <pic18f8722.h> as shown in this snippet:
// Register: TMR0
#define TMR0 TMR0
extern volatile unsigned short TMR0 __at(0xFD6);
#ifndef _LIB_BUILD
asm("TMR0 equ 0FD6h");
#endif
// Register: TMR0L
#define TMR0L TMR0L
extern volatile unsigned char TMR0L __at(0xFD6);
#ifndef _LIB_BUILD
asm("TMR0L equ 0FD6h");
#endif
// Register: TMR0H
#define TMR0H TMR0H
extern volatile unsigned char TMR0H __at(0xFD7);
#ifndef _LIB_BUILD
asm("TMR0H equ 0FD7h");
#endif
However, the above substitution in my code (TMR0L=0 and TMR0H=0 with TMR0=0) surprisingly DOES NOT work, i.e., the functions using TMR0 stop doing their job and give errors.
Did anybody ever notice such bizarre, strange behavior and, above all, could explain WHY it is happening?
First, take a look at section 12.1 of the PIC18F8722 datasheet!
TMR0H is not the actual high byte of Timer0 in 16-bit mode; it is actually a buffered version of the real high byte of Timer0 which is not directly readable nor writable TMR0H is updated with the contents of the high byte of Timer0 during a read/write of TMR0L. This provides the ability to read all 16 bits of Timer0 without having to verify that the read of the high and low byte were valid, due to a rollover between successive reads of the high and low byte.
So it is important the order how to write to registers. First write the high part of 16 bit value in to TMR0H register and then low part to TMR0L.