Timer0 in PIC18F26J50
Assuming 16 bit tmr0, the offset should bee set like this

Tmr0 = -(fxtal / 4 / prescaler)

At least one of them needs to be 32 type.

For 8bit tmr0, it has to bee done over multiple Isr invokation. The trick there is to only load the counter once.

edit: here is one of many ways to do the trick mentioned above.

//tmr0 isr handle
void my_isr(void) {
    if (tmr0_cnt) {                         //not running out yet
        tmr0_cnt -= 0x100;                  //update tmr0
    } else {
        TMR0 = -TMR_PR;                     //load the TMR0 counter with the initial offset
        tmr0_cnt = TMR_PR &amp;~0xfful;         //initialize the counter - lsb already handled
        IO_FLP(LED_PORT, LED);              //flip the pin
    }
}


the above section will be installed as the isr.

for any given timing period (TMR_PR), it writes to the timer0 counter only once - when it is initialized at the begining of the timer period, regardless of how long the timing period is - in this case, TMR_PR is a 32-bit type.

after that, tmr0_cnt is updated until the timing duration is exhausted.

the timing error (from loading up TMR0) depends on the chips used / frequency it runs on and compiler mode. about 20 - 30 ticks unoptimized.

here is the code in the user space:

tmr0_init(TMR0_PS_1x);                  //reset tmr0 to 1x prescaler, 8-bit
//tmr0_cnt = 0;                         //reset tmr0
tmr0_act(my_isr);                       //install user isr
ei();


and here is the simulation:



TMR_PR is set to F_CPU / 10, or 10 flips per second, as confirmed by the simulation.

The code can be basically ported to any mcu.