Viewing two contiguous 8 bits SFRs as a single 16 bit register in correct for almost all situations. However, it fails
when accessing the TIMER0 registers, because TMR0L and TMR0H SFR are continuously modified by the
hardware clock and need to be managed in a very special way (this is also true for TMR1H/L
, TMR2H/L
, etc.).
A write in TMR0H only stores data in a temporary register. During write to TMR0L, this temporary register is transferred to real TMR0H, so TMR0L and TMR0H are simultaneously updated. This feature is a trick imagined by Microchip's designers to allow atomic writes to 16 bit data on a 8 bit processor, but forces to write hi byte first, then low byte. Please see Microchip documentation for details.
Unfortunatly, the code generated by cpik may write low byte first, so TMR0H is loaded with spurious data, and dataH is lost. The solution is simple, but need to split access in two parts:
TMR0H = value_to_load >> 8 ; // hi byte first TMR0L = value_to_load & 0xFF ;
The same feature exists for reads, but doesn't cause problem because reads are performed in the correct order. However, this point might be changed if code generator or run-time library is changed, so I recommend to perform reads with same care.
AG 2013-04-10