TMOD

TMOD is a 8-bit register, the lower 4 bits are for Timer 0, the upper 4 bits are for Timer 1, In each case, the lower 2 bits are used to set the timer mode, the upper 2 bits to specify the operation

TMOD

M1 M0 Mode Operating Mode
0 0 0 13-bit timer mode, 8-bit timer/counter THx with TLx as 5-bit prescaler
0 1 1 16-bit timer mode, 16-bit timer/counter THx and TLx are cascaded; there is no prescaler
1 0 2 8-bit auto reload, 8-bit auto reload timer/counter; THx holds a value which is to be reloaded TLx each time it overflows
1 1 3 Split timer mode
TMOD = 0x00; // 0000 0000  // timer 1, mode 0, 13-bit, TH1 all bits and TL1 lower 5 bits
TMOD = 0x10; // 0001 0000  // timer 1, mode 1, 16-bit, TH1 and TL1
TMOD = 0x20; // 0010 0000  // timer 1, mode 2, 8-bit reload,load TL1 with value of TH1 when overflow 
TMOD = 0x30; // 0011 0000  // timer 1, mode 3, invalid

TMOD = 0x02; // 0000 0010  // timer 0, mode 2, 8-bit reload, load TL0 with value of TH0 when overflow
TMOD = 0x03; // 0000 0011  // timer 0, mode 3, two separate 8-bit couter, i.e TH0 and TH1

TCON |= 0x40; // 0100 0000 // start timer/counter 1
TCON |= 0x10; // 0001 0000 // start timer/counter 0

if (TF1) {/** timer/counter 1 overflows */}
if (TF0) {/** timer/counter 2 overflows */}

mode1 characteristics

  1. It is a 16-bit timer; therefor it allows value of 0000H to FFFFH to be loaded into the the timer's register TL and TH
  2. After TH and TL are loaded with a 16-bit initial value, the timer must be started. This is done by the instruction SETB TR0 for timer 0 and SETB TR1 for timer 1
  3. After the timer is started, it starts to count up, unitl it reaches its limit of FFFFH, when it rolls over from FFFFH to 0000H, it sets high a flog bit called TF(timer flag, TF0 for timer 0, TF1 for timer 1), when this timer flag is raised, one option would be to stop the timer with the instructions CLR TR0 or CLR TR1, for timer 0 and timer 1, respectively
  4. After the timer reaches its limit and rolls over, in order to repeat the process: TH and TL must reloaded with the original value, and TF must be reloaded to 0
// Task: use Timer 0, mode 1(16-bit) to create 50ms delay
#include <reg51.h>

// in 8051, the machine cycle frequency is always of 1/12 of the XTAL frequency, therefore
// 11.0529MHz / 12 = 921.6kHz;
// T = 1/921.6kHz = 1.085μs

void T0M1_Delay(void) {
  TMOD=0x01; // set TMOD as mode 1(16-bit) as timer
  TL0=0xFD; // set initial value of low 8-bit
  TH0=0x4B; // set initial value of high 8-bit, together is 4BFDH
  // FFFFH - 4BFDH = B402H = 46082 + 1(wait until flag is set) = 46083
  // 46083 x 1.085μs = 50ms
  TR0=1; // start the timer
  while (TF0==0); // wait unitl TF is set by HW
  TR0=0; // reset start
  TF0=0; // reset flag
}

mode2 characteristics

  1. It is an 8-bit timer; therefor, it allows only values of 00H to FFH to be loaded into the timer's register TH
  2. After TH is loaded with the 8-bit value, the 8051 gives a copy of it to TL, then the timer must be started, this is done by the instruction SETB TR0 for timer 0 and SETB TR1 for timer 1
  3. After the timer is started, it starts to count up by incrementing the TL register, it counts up until it reaches its limit of FFH, when it rolls over from FFH to 00H, it sets high the TF(timer flag)
  4. When the TL register rolls from FFH to 0 and TF is set to 1, TL is reloaded automatically with the original value kept by the TH register. To repeat the process, we must simply clear TF and let it go without any need by the programmer to reload the original value. This makes mode 2 an auto-reload, in contrast with mode 1 in which the programmer has to reload TH and TL
// Task: Use Timer 0, mode 2 (8-bit auto-reload) create 250ms delay continuously toggle pin P1.5
#include <reg51.h>

void T0M2_Delay(void);
sbit mybit = P1^5;
void main(void) {
  unsigned char x,y;
  while (1) {
    mybit = ~mybit;
    for (x=0;x<250;x++) // 25μs x 250 x 40 = 250ms
      for (y=0;y<36;y++) // Due to overhead of the for loop in C, we put 36 instead of 40
        T0M2_Delay();
  }
}

void T0M2_Delay(void) {
  TMOD = 0x02; // use Timer 0, mode 2
  TH0 = -23; // set initital value of TH0
  // 23 x 1.085μs = 25μs
  TR0 = 1; // start timer
  while (TF0 == 0); // wait unitl TF0 is set by HW
  TR0 = 0; // reset start
  TF0 = 0; // reset flag
}
// Task: create a frequency of 2500Hz on pin P2.7, use Timer 1, mode 2 to create delay
#include <reg51.h>
// 1/2500Hz = 400μs
// 400μs /2 = 200μs
// 200μs / 1.085μs = 184

void T1M2_Delay(void);
sbit mybit = P2^7;
void main(void) {
  unsigned char x;
  while (1) {
    mybit = ~mybit;
    T1M2_Delay();
  }
}
void T1M2_Delay(void) {
  TMOD = 0x20; // use Timer 1, mode 2;
  TH1 = -184; // set initial value: 0x48
  TR1 = 1; // start timer
  while (TF1 == 0); // wait until time flag is set by HW
  TR1 = 0; // reset start
  TF1 = 0; // reset flag
}

Page Source