Microcontroller 8051 Programming in C

Download as pdf or txt
Download as pdf or txt
You are on page 1of 22

Microcontroller 15EE52

Module – 3: 8051 Programming in C

8051 Timer programming in Assembly and C: Programming 8051 timers, Counter programming, Programming
timers 0 and 1 in 8051 C

8051 Timer Programming in Assembly & C: Programming 8051 timers:


The 8051 has two timers/counters T0 & T1. They can be used either as timers to generate a time delay or as counters to
count events happening outside the microcontroller.

Basic registers of the timer


Both Timer 0 and Timer 1 are 16 bits wide. Since the 8051 has an 8-bit architecture, each 16-bit timer is accessed as
two separate registers of low byte and high byte.

Timer 0 registers
The 16-bit register of Timer 0 is accessed as low byte and high byte. The low byte register is called TLO (Timer 0 low
byte) and the high byte register is referred to as THO (Timer 0 high byte). These registers can be accessed like any
other register, such as A, B, RO, Rl, R2, etc. For example, the instruction “MOV TLO, #4FH” moves the value 4FH
into TLO, the low byte of Timer 0. These registers can also be read like any other register. For example, “MOV R5 ,
THO” saves THO (high byte of Timer 0) in R5.

Fig.-1. Timer 0 Registers


Timer 1 registers

Fig.-2. Timer 1 Registers

Timer 1is also 16 bits, and its 16-bit register is split into two bytes, referred to as TLl (Timer 1 low byte) and TH1
(Timer 1 high byte). These registers are accessible in the same way as the registers of Timer 0.

TMOD (timer mode) register:

Both timers 0 and 1 use the same register, called TMOD, to set the various timer operation modes. TMOD is an 8-bit
register in which the lower 4 bits are set aside for Timer 0 and the upper 4 bits for Timer 1. In each case, the lower 2
bits are used to set the timer mode and the upper 2 bits to specify the operation.

Dept. of EEE, SJBIT


1
Microcontroller 15EE52
7 6 5 4 3 2 1 0
Gate C/ ₸ M1 M0 Gate C/ ₸ M1 M0
Timer 1 Timer0

Bit Symbol Function


Gating control when set. The timer/counter is enabled only while the INTx pin is high and the
7/3 Gate
TRx control pin is set. When cleared, the timer is enabled whenever the TRx control bit is set.
Timer or counter selected cleared for timer operation (input from internal system clock). Set
6/2 C/ ₸
for counter operation (input from Tx input pin).
5/1 M1 Timer/counter operating mode select bit 1
4/0 M0 Timer/counter operating mode select bit 0
M1 M0 Mode Operating mode
13-bit timer/counter
0 0 mode 0
8-bit timer/counter THx with TLx as 5-bit prescaler
16-bit timer/counter
0 1 mode 1
16-bit timer/counter THx & TLx are cascaded; there is no prescaler
8-bit Auto reload timer/counter
1 0 mode 2 8-bit auto reload timer/counter; THx holds a value that is to be reloaded
into TLx each time it overflows.
Split timer mode
1 1 mode 3
02 8-bit timers using T0

M1, MO
M0 and M1 select the timer mode. As shown above, there are four modes: 0, 1, 2 and 3. Mode 0 is a 13-bit timer, mode
1 is a 16-bit timer, mode 2 is an 8-bit timer, and mode 3 is a 8-bit split timer.

C/₸ (clock/timer)
This bit in the TMOD register is used to decide whether the timer is used as a delay generator or an event counter. If C/
₸ = 0, it is used as a timer for time delay generation. The clock source for the time delay is the crystal frequency of the
8051.

Clock source for timer


If C/₸= 0, the crystal frequency attached to the 8051 is the source of the clock for the timer. This means that the size of
the crystal frequency attached to the 8051 also decides the speed at which the 8051 timer ticks. The frequency for the
timer is always 1/12th of the frequency of the crystal attached to the 8051. Although various 8051-based systems have
an XTAL frequency of 10 MHz to 40 MHz, XTAL frequency of 11.0592 MHz is preferred as it is suitable for baud
rate generation in serial communication.

Ex-1: Indicate which mode and which timer is selected for each of the following.
(a) MOV TMOD, #01H (b) MOV TMOD, #20H (c) MOV TMOD, #12H
Solution:

We convert the values from hex to binary.


(a) TMOD = 00000001, mode 1 of Timer 0 & mode 0 Timer 1 is selected.
(b) TMOD = 00100000, mode 0 of timer 0 & mode 2 of Timer 1 is selected.
(c) TMOD = 00010010, mode 2 of Timer 0, and mode 1 of Timer 1 is selected.

Dept. of EEE, SJBIT


2
Microcontroller 15EE52
Ex-2: Find the values of TMOD to operate as timers in the following modes. (a) Mode 1 Timer 1 (b) Mode 2
Timer 0, Mode 2 timer 1, (c) Mode 0 Timer 1.
Solution:

(a) Mode 1 Timer 1: TMOD = 0001 0000 = 10h


(b) Mode 2 Timer 0, Mode 2 timer 1: TMOD = 0010 0010 = 22h
(c) Mode 0 Timer 1: TMOD = 0000 0000 = 00h

Ex-3: Find the timer’s clock frequency and its period for various 8051-based systems, with the following crystal
frequencies. a) 13MHz b) 16MHz c) 11.0592 MHz
Solution:

a) f = (1/12) × 12×106 = 1MHz


T = 1/(1×106) = 1µs

b) f = 1/12×16×106 = 1.333MHz
T = 1/1.333×106 = 0.75 µs

c) f = 1/12×11.0592×106 = 921.6KHz
T = 1/921.6×106 = 1.085 µs

GATE

The timers in 8051 have two means of starting & stopping: i) controlled by way of software by the TR (timer start)
bits TRO and TR1. This is achieved by the instructions “SETB TR1” and “CLR TR1″ for Timer 1, and “SETB TRO”
and “CLR TRO” for Timer 0. The SETB instruction starts it, and it is stopped by the CLR instruction. ii) Controlled by
hardware switch connected to external interrupt pins. Selection of these two means is done using the GATE bit.
Software way of starting & stopping the timers is enabled when GATE = 0 in the TMOD register. The hardware way
of starting and stopping the timer by an external source is achieved by making GATE = 1 in the TMOD register.

Dept. of EEE, SJBIT


3
Microcontroller 15EE52

Ex-4: Find the value for TMOD if we want to program Timer 0 in mode 2, use 8051 XTAL for the clock source,
and use instructions to start and stop the timer.
Solution:

TMOD = 0000 0010 Timer 0, mode 2, XTAL clock source and internal control for start & stop

TCON register:
 bit addressable as TCON.0 to TCON.7
7 6 5 4 3 2 1 0
TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
Timer Control Interrupt control

Bit Symbol Function


 Timer-1 overflow flag
7 TF1  Set when timer rolls from all 1s to 0
 Cleared when processor vectors to execute ISR located at program address 001BH
 Timer-1 run control bit
 Set to 1 by program to enable timer to count
6 TR1
 Cleared to 0 by program to halt timer
 Doesn’t reset timer
 Timer-0 overflow flag
5 TF0  Set when timer rolls from all is to 0
 Cleared when processor vectors to execute ISR located at program address 000bh
 Timer-0 run control bit
 Set to 1 by program to enable timer to count
4 TR0
 Cleared to 0 by program to halt timer
 Doesn’t reset timer
 External interrupt-l edge flag
3 IE1  Set to 1 when a high-to-low edge signal is received on INT1
 Cleared when processor vectors to ISR located at program address 0013h
 External interrupt-1 signal type control bit
 Set to 1 by program to enable external interrupt-1 to be triggered by a falling edge signal
2 IT1
 Set to 0 by program to enable a low-level signal on external interrupt 1 to generate an
interrupts
 External interrupt 0 edge flag
1 IE0  Set to 1 when a high-to-low edge signal is received on INT0
 Cleared when processor vectors to ISR located at program address 0003h
 External interrupt 0 signal type control bit
 Set to 1 by program to enable external interrupt 0 to be triggered by a falling edge signal
0 IT0
 Set to 0 by program to enable a low-level signal an external interrupt 0 to generate an
interrupt

Dept. of EEE, SJBIT


4
Microcontroller 15EE52
Mode 1 programming:

The following are the characteristics and operations of mode 1:


1. It is a 16-bit timer; therefore, it allows values of 0000h to FFFFh to be loaded
into the timer’s registers 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 “SETB TRO” for
Timer 0 and “SETB TR1″ for Timer 1.
3. After the timer is started, it starts to count up. It counts up until it reaches its limit of FFFFH. When it rolls over
from FFFFH to 0000, it sets high a flag bit called TF (timer flag). This timer flag can be monitored. When this
timer flag is raised, one option would be to stop the timer with the instructions “CLR TRO” or “CLR TR1″, for
Timer 0 and Timer 1, respectively. Each timer has its own timer flag: TFO for Timer 0, and TF1 for Timer 1.
4. After the timer reaches its limit and rolls over, in order to repeat the process the registers TH and TL must be
reloaded with the original value and TF must be reset to 0.
Steps to program in mode 1
To generate a time delay, using the timer’s mode 1, the following steps are taken.
1. Load the TMOD value register indicating which timer (Timer 0 or Timer 1) is
to be used and which timer mode (0 or 1) is selected.
2. Load registers TL and TH with initial count values.
3. Start the timer.
4. Keep monitoring the timer flag (TF) with the “JNB TFx, target” instruction to see if it is raised. Get out of the
loop when TF becomes high.
5. Stop the timer.
6. Clear the TF flag for the next round.
7. Go back to Step 2 to load TH and TL again.

Calculation of amount of time delay generated by timer:


If, f = 11.0592 MHz
Timer works with 1/12 of crystal frequency
i.e., (1/12) ×11.0592 MHz = 921.6 KHz
Each clock = 1/921.6K = 1.085µs = t

i.e., the timer counts up each for every 1.085µs

Total delay = count × 1.085 µs, where count = (FFFF – YYXX+1), YYXX are TH & TL values initially

Finding values to be loaded into the timer:

1. Divide the desired time delay by the clk time t.


2. Perform 65536-n, where n is the decimal value resulted in step 1.
3. Convert result in step 2 to hex, where YYXX is the initial hex value to be loaded into the timer’s registers.
4. Set TL = XX & TH = YY
Dept. of EEE, SJBIT
5
Microcontroller 15EE52
Ex-5: Write an ALP to generate a square wave of 50% duty cycle (with equal portions high and low) on the P1.5
bit. Use Timer 0 to generate the time delay. Analyze the program. Also i) calculate the time delay
assuming XTAL = 11.0592 MHz, ii) calculate the frequency of the square wave generated on P1.5
Solution:

MOV TMOD, #01h ; Timer 0, mode 1 (16-bit mode)


Here: MOV TL0, #0F2h ; low byte
MOV TH0, #0FFh ; high byte
CPL P1.5 ; toggle P1.5
ACALL Delay
SJMP Here ; repeat
; delay using timer 0
Delay: SETB TR0 ; start timer 0
Again: JNB TF0, Again ; monitor timer 0 flag until it rolls over
CLR TR0 ; stop timer 0
CLR TF0 ; clear timer 0 flag
RET
In the above program notice the following steps.
1. TMOD is loaded.
2. FFF2H is loaded into TH0:TL0.
3. P1.5 is toggled for the high and low portions of the pulse.
4. The Delay subroutine using the timer is called.
5. In the Delay subroutine, Timer 0 is started by the “SETB TR0” instruction.
6. Timer 0 counts up with passing of each clock, which is provided by crystal oscillator. As the timer counts up, it
goes through the states of FFF3, FFF4, FFF5, FFF6, FFF7, & so on until it reaches FFFFH. One more clock rolls
it to 0, raising the timer flag (TF0 = 1). At that point, the JNB instruction falls through.
7. Timer 0 is stopped by the instruction “CLR TR0”. The Delay subroutine ends, and the process is repeated.
Notice that to repeat the process, we must reload the TL and TH registers and start the timer again.

i) Time delay:

Timer works with 1/12 of crystal frequency


i.e., (1/12) ×11.0592 MHz = 921.6 KHz
Each clock = 1/921.6K = 1.085µs = t

i.e., the timer counts up each for every 1.085µs

Total delay = count × 1.085 µs, where count = (FFFF-YYXX+1)

Number of counts for roll over if the loaded value in TH:TL register FFF2h
Count = FFFFh - FFF2h = 0Dh (13d) + 1 for the extra clock to roll over from FFFF h to 0000h & raise the TF flag.
i.e., 13+1=14
Delay = 14×1.085µs= 15.19µs
Dept. of EEE, SJBIT
6
Microcontroller 15EE52

ii) Frequency of the square wave generated on pin P1. 5:


To get a more accurate timing, we need to add clock cycles due to the instructions in the loop. To do that, we use
the machine cycles, as shown below.

Cycles
Here: MOV TL0, #0F2h ; low byte 2
MOV TH0, #0FFh ; high byte 2
CPL P1.5 ; toggle P1.5 1
ACALL Delay 2
SJMP Here ; repeat 2
; delay using timer 0
Delay: SETB TR0 ; start timer 0 1
Again: JNB TF0, Again ; monitor timer 0 flag until it rolls over 14
CLR TR0 ; stop timer 0 1
CLR TF0 ; clear timer 0 flag 1
RET 2
Total 28

T = 2x28x1.085µs = 60.76 µs
F = 16458.2 Hz
Ex-6: Find the delay generated by Timer 0 in the following code. Do not include the overhead due to
instructions.

CLR P2.3 ; clear P2.3


MOV TMOD, #01 ; Timer 0, mode 1
HERE: MOV TL0, #3EH ; low byte
MOV THO, #0B8H ; high byte
SETB P2.3 ; set high P2.3
SETB TR0 ; start timer 0
AGAIN: JNB TF0, AGAIN ; monitor timer 0 flag
CLR TR0 ; stop timer 0
CLR TF0 ; clear timer 0 flag for next round
CLR P2.3

1. In hexadecimal: (FFFF – B83E + 1) = 47C2H= 18370 in decimal and 18370 x 1.085 µs = 19.93145ms.
2. In Decimal: Since TH:TL = B83EH = 47166 (in decimal) we have 65536 – 47166 = 18370.
This means that the timer counts from B83EH to FFFFH. This plus rolling over to
0 goes through a total of 18370 clock cycles, where each clock is 1.085 µs in duration. Therefore, we have 18370
x 1.085 µs = 19.93145 ms as the width of the pulse.

Dept. of EEE, SJBIT


7
Microcontroller 15EE52

Ex-7: Calculate the Time delay generated in the below program and also find the largest time delay generated
considering XTAL = 22 MHz.
CLR P1.3 ; clear P1.3
MOV TMOD, #10H ; Timer 1, mode
MOV TH0, #0FFH ; load high byte value
MOV TL0, #00H ; load low byte
SETB P1.3 ; set bit P1.3
SETB TCON.6 ;TR1 is set to start Timer 1
AGAIN: JNB TCON.7, AGAIN ; monitor Timer 1 flag
CLR TCON.6 ; stop Timer 1 by making TR1=0
CLR TCON.7 ; clear Timer 1 flag for next round
CLR P1.3 ; clear the port for next round
Solution:

For a crystal frequency of 22 MHz, the value of the instruction cycle = 1/12 of 22 MHz = 1.833 MHz and T=0.546 µs.

i) Delay generated:
The delay is calculated as FFFFH – FF00H = FFH = 255+1 = 256.
Delay = 256x0.546 = 139.2µs.
ii) Maximum delay:
The maximum delay possible is when both TH and TL stores values of 00.
The FFFFH - 0000 = FFFFH = 65,535+1=65,536.
DELAY = 65,536X0.546=35,782µs = 35.75ms.

Ex-8: Assume that XTAL = 11.0592 MHz. What value do we need to load into the timer’s registers if we want to
have a time delay of 5 ms (milliseconds)? Show the program for Timer 0 to create a pulse width of 5 ms
on P2.3.
Solution:
Since XTAL = 11.0592 MHz, the counter counts up every 1.085 µs.
No. of clocks required to generate 5ms using 1.085 µs pulse is = 5 ms/ 1.085 µs = 4608 clocks.
Value to load into timer registers TH0:TL0 = 65536 – 4608 = 60928 = EEOOH.
Therefore, we have TH0 = EEh and TL0 = 00h.

CLR P2.3 ; clear P2.3


MOV TMOD, #01 ; Timer 0, mode 1 (16-bit mode)
HERE: MOV TL0, #0 ; TL0=0, Low byte
MOV TH0, #0EEH ; TH0=EE(hex), High byte
SETB P2.3 ; SET P2.3 high
SETB TR0 ; start Timer 0
AGAIN: JNB TF0, AGAIN ; monitor Timer 0 flag
; until it rolls over
CLR P2.3 ; clear P2.3
CLR TR0 ; stop Timer 0
CLR TF0 ; clear Timer 0 flag

Dept. of EEE, SJBIT


8
Microcontroller 15EE52
Ex-9: Assume XTAL = 22 MHz, generate a frequency of 100 KHz on pin P2.3. Use timer 1 in mode 1.
Solution:

For a crystal frequency of 22 MHz, the value of the instruction cycle = 1/12 of 22 MHz = 1.833 MHz and T=0.546 µs.

a) T=1/f= 1/100K = 0.01ms = 10µs


b) ½ of it for high and low portions each = 5µs
c) No. of cycles required = 5µs/0.546 µs = 9 cycles
d) Value to be loaded into timer registers = 65,536 – 9 = 65,527 = FFF7h

MOV TMOD, #10H ;Timer 1, Mode 1


BACK: MOV TL1, #0F7H ; TL1=F7H
MOV TH1, #0FFH ; TH1=FFH
SETB TR1 ; start Timer 1
Again: JNB TF1, AGAIN ; wait for timer rollover
CLR TR1 ; stop Timer 1
CPL P2.3 ; complement P2.3
CLR TF1 ; clear timer flag
SJMP BACK ; reload timer
Ex-10: Generate a square wave with an ON time of 3ms and an OFF time of 10ms on all pins of port 0. Assume
an XTAL of 22 MHz.
Solution:
For a crystal frequency of 22 MHz, the value of the instruction cycle = 1/12 of 22 MHz = 1.833 MHz and T=0.546 µs.

For OFF time calculation:


10ms/0.546µs=18,315 cycle 65,536-18,315=47221=B875H
For ON time calculation:
3ms/0.546µs = 5494 cycle 65536 – 5494 = 60042 = EA8Ah.

Let us use Timer 0 in Mode 1.


MOV TMOD, #01H ; Timer 0 in mode 1
BACK: MOV TL0, #075H ; to generate the OFF time, load TL0
MOV TH0, #0B8H : load OFF time value in TH0
MOV P0, #00H ; make port bits low
ACALL DELAY ; call delay routine
MOV TL0, #8AH : to generate the ON time, load TL0
MOV TH0, #0EAH ; load ON time value in TH0
MOV P0, #0FFH ; make port bits high
ACALL DELAY ; call delay
SJMP BACK ; repeat for reloading counters to get a
; continuous square wave
ORG 300H
DELAY: SETB TR0 ; start the counter
AGAIN: JNB TF0, AGAIN : check timer overflow
CLR TR0 ; when TF0 is set, stop the timer
CLR TF0 ; clear timer flag
RET
END ; end of file

Dept. of EEE, SJBIT


9
Microcontroller 15EE52
Generating a large time delay
The size of the time delay depends on two factors,
(a) the crystal frequency, and
(b) the timer’s 16-bit register in mode 1. Both of these factors are beyond the control of the 8051 programmer.
The largest time delay is achieved by making both TH and TL zero. What if that is not enough?

Ex-11: Assuming XTAL=22 MHZ, Write A Program to generate a pulse train of 2 seconds period on pin P2.4.
Use Timer 1 in mode1.
Solution:
For a crystal frequency of 22 MHz, the value of the instruction cycle = 1/12 of 22 MHz = 1.833 MHz and T=0.546 µs.

For a time period of 2 seconds, the half period should be 1 second.

The maximum delay possible is when both TH and TL stores values of 00.
The FFFFH - 0000 = FFFFH = 65,535+1=65,536.
DELAY = 65,536X0.546=35,782µs = 35.75ms.

If this delay is repeated 28 times, we can get a delay of 1001ms ≈ 1second.

MOV TMOD, #10H ; Timer 1, mode1


REPT: MOV R0, #28 ; counter for multiple delay
CPL P2.4 ; complement P2.4
BACK: MOV TL1, #00H ; load count value in TL1
MOV TH1, #00H ; load count value in TH1
SETB TR1 ; start timer
AGAIN: JNB TF1, AGAIN ; stay until timer rolls over
CLR TR1 ; stop timer
CLR TF1 ; clear timer flag
DJNZ R0, BACK ; if R0 is not zero, reload timer
SJMP REPT ; repeat for continuous pulse generation

Calculation=28x35.75ms=1001ms.

Ex-12: generate the following waveform on P1.2. XTAL=22MHz

Solution:
For a crystal frequency of 22 MHz, the value of the instruction cycle = 1/12 of 22 MHz = 1.833 MHz and T=0.546 µs.

This means first creating a delay of 50ms ON time and 50ms OFF time, followed by five repetitions of 10ms ON time
and 10ms OFF time.
To generate a delay of 50ms, a 10ms delay is repeated 5 times.

Dept. of EEE, SJBIT


10
Microcontroller 15EE52
START: SETB P1.5 ; set port pin for generating the ON time

MOV R1, #02 ; one ON time and one OFF time


MOV TMOD, #10H ; Timer 1, Mode 1
BACK: MOV R0, #05 ; repeat the 10ms delay 5 times
RPT: MOV TL1, #75H
MOV TH1, #0B8H
SETB TR1
AGAIN: JNB TF1, AGAIN
CLR TR1
CLR TF1
DJNZ R0, RPT
CPL P1.5
DJNZ R1, BACK ; stop after 2 periods of 50ms are over
SETB P1.5 ; start the sequence of 5 pulses of T=20ms
MOV R1, #10 ; this part for 10 ON-OFF periods of 10ms
BACK1: MOV TL1, #75H
MOV TH1, #0B8H
SETB TR1
AGAIN1: JNB TF1, AGAIN1
CLR TR1
CPL P1.5
CLR TF1
DJNZ R1,BACK1
SJMP START ; repeat

Mode 0
Mode 0 is exactly like mode 1 except that it is a 13-bit timer instead of 16-bit. The 13-bit counter can hold values
between 0000 to 1FFFH in TH – TL. Therefore, when the timer reaches its maximum of 1FFH, it rolls over to 0000,
and TF is raised.
Mode 2 programming
The following are the characteristics and operations of mode 2.
1. It is an 8-bit timer; therefore, it allows only values of 00 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 TRO” for Timer 0 and “SETB TR1” for Timer 1. This is just like mode 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 00, it sets high the TF (timer flag). If we are using Timer 0, TFO goes
high; if we are using Timer 1, TF1 is raised.
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.

It must be emphasized that mode 2 is an 8-bit timer. However, it has an auto-reloading capability. In auto-reload, TH is
loaded with the initial count and a copy of it is given to TL. This reloading leaves TH unchanged, still holding a copy
of the original value. This mode has many applications, including setting the baud rate in serial communication.

Dept. of EEE, SJBIT


11
Microcontroller 15EE52
Steps to program in mode 2
To generate a time delay using the timer’s mode 2, take the following steps.
1. Load the TMOD value register indicating which timer (Timer 0 or Timer 1) is
to be used, and select the timer mode (mode 2).
2. Load the TH registers with the initial count value.
3. Start the timer.
4. Keep monitoring the timer flag (TF) with the “JNB TFx, target” instruction to see whether it is raised. Get out
of the loop when TF goes high.
5. Clear the TF flag.
6. Go back to Step 4, since mode 2 is auto-reload.

Ex-13: Assuming that XTAL = 11.0592 MHz, find (a) the frequency of the square wave generated on pin P1.0 in
the following program, and (b) the smallest frequency achievable in this program, and the TH value to
do that.

MOV TMOD, #20H ; T1/ mode 2/8-bit /auto-reload


MOV TH1, #5 ; TH1=5
SETB TR1 ; start Timer 1
BACK: JNB TF1, BACK ; stay until timer rolls over
CPL P1.0 ; comp. P1.0 to get hi, lo
CLR TF1 ; clear Timer 1 flag
SJMP BACK ; mode 2 is auto-reload
Solution:

a) First notice the target address of SJMP. In mode 2 we do not need to reload TH since it is auto-reload. Now (256 –
05) x 1.085 µs = 251 x 1.085 µs = 272.33 µs is the high portion of the pulse.
Since it is a 50% duty cycle square wave, the period T is twice that;
T = 2 x 272.33 µs = 544.67 µs and the f = 1.83597 kHz.

b) To get the smallest frequency, we need the largest T and that is achieved when TH= 00. In that case, we have T = 2
x 256 x 1.085 µs = 555.52 µs and the frequency = 1.8kHz.

Ex-14: Assuming that XTAL=22MHz, write a program to generate a square wave of frequency 1 kHz on pin
P1.2.
Solution:
For a crystal frequency of 22 MHz, the value of the instruction cycle = 1/12 of 22 MHz = 1.833 MHz and T=0.546 µs.

The smallest frequency possible in this setup is when the delay is maximum. Largest delay is when TH reduces to 00
from FF, i.e., delay is 256x0.546 µs = 139µs.
T = 2x139 = 278µs i.e., the smallest frequency is 3.6 kHz. Hence, to get a smaller frequency, we need to use a register
for creating the additional delay.
To get a delay of 0.5ms, we need 0.5ms/0.546µs=915 cycles.
To use the TH register to get a delay of 915/5=183cycles, and a register R0 to get the rest of it.
183 cycles have to be covered by the TH register when it rolls from its count value to FFH.
183=B7H. The TH value should be FFH-B7H=48H.
Thus the effective delay is 183x0.546x5 = 499µs = 0.5ms, T = 0.5msx2 =1ms and frequency = 1 kHz.

Dept. of EEE, SJBIT


12
Microcontroller 15EE52
MOV TMOD, #02H ; Timer 0, mode 2
REPT: CPL P1.2 ; complement P1.2
MOV R0, #05 ; count for multiple delay
AGAIN: MOV TH0, #48H ; load TH0 value
SETB TR0 ; start timer 0
BACK: JNB TF0, BACK ; stay until timer rolls over
CLR TR0 ; stop timer
CLR TF0 ; clear timer flag
DJNZ R0, AGAIN ; repeat until R0=0
SJMP REPT ; repeat to get a train of pulses
END

Ex-15: Assuming that we are programming the timers for mode 2, find the value (in hex) loaded into TH for
each of the following cases.
a) MOV TH1, # -200
b) MOV TH1, # -3
c) MOV TH0, # -48
d) MOV TH0, # -60
e) MOV TH1, # -12
Solution:
The following is what we get.
Decimal 2’s complement (TH value)
-200 38H
-60 C4H
-3 FDH
-12 F4H
-48 D0H

Assemblers and negative values

Since the timer is 8-bit in mode 2, we can let the assembler calculate the value for TH. For example, in “MOV
TH1 ,#-10 0″, the assembler will calculate the -100 = 9C, and makes TH1 = 9C in hex.

Counter Programming:
When the timer/counter is used as a timer, the 8051's crystal is used as the source of the frequency. When it is used as a
counter, however, it is a pulse outside the 8051 that increments the TH, TL register. In counter mode, the TMOD and
TH, TL registers are the same as for the timer; they even have the same names. The timer’s are the same as well.

C/T bit in TMOD register:


C/T bit in the TMOD register decides the source of the clock for the timer. If C/T=0, the timer gets pulses from the
crystal. In contrast, when C/T = 1, the timer is used as a counter and gets its pulses from outside the 8051 through the
timer input pins 14 (P3.4 - Timer 0 input) and 15 (P3.5 - Timer 1 input).

Ex-1: Design a counter for counting the pulses of an input signal. The pulses to be counted are fed to pin P3.4.
XTAL = 22 MHz.
Solution:

Dept. of EEE, SJBIT


13
Microcontroller 15EE52
In this, Timer 1 is used as time base for timing 1 second. During this 1 second, Timer 0 is run as a counter, with input
pulses fed into pin P3.4. At the end of 1 second, the values in TL0 and TH0 give the number of pulses that were
received at pin P3.4 during this 1 second. This gives the frequency of the unknown signal, i.e., the number of pulses
received in 1 second.

ORG 0000H
RPT: MOV TMOD, #15H ; timer 1 as timer and Timer 0 as counter
SETB P3.4 ; make port P3.4 an input port
MOV TL0, #00 ; clear TL0
MOV TH0, #00 ; clear TH0
SETB TR0 ; start counter
MOV R0, #28 ; R0=28, to time 1 second
AGAIN: MOV TL1, #00H ; TL1=0
MOV TL1, #00H ; TL1=0
SETB TR1 ; start Timer 1
BACK: JNB TF1, BACK ; test Timer 1 flag
CLR TF1 ; clear Timer 1 flag
CLR TR1 ; stop Timer 1
DJNZ R0, AGAIN ; repeat the loop until R0=0
MOV A, TL0 ; since 1 sec has elapsed, check TL0
MOV P2, A ; move TL0 to port 2
MOV A, TH0 ; move TH0 to ACC
MOV P1, A ; move it to port 1
SJMP RPT ; repeat
END

Ex-2: Assume that a 1-Hz frequency pulse is connected to input pin 3.4. Write a program to display counter 0
on an LCD. Set the initial value of TH0 to -60.
Solution:

To display the TL count on an LCD, we must convert 8-bit binary data to ASCII.

ACALL LCD_SET_UP ; initialize the LCD


MOV TMOD, #00000110B ; counter 0, mode 2, C/T=1
MOV TH0, #-60 ; counting 60 pulses
SETB P3.4 ; make T0 as input
AGAIN: SETB TR0 ; starts the counter
BACK: MOV A, TL0 ; get copy of count TL0
ACALL CONV ; convert in R2, R3, R4
ACALL DISPLAY ; display on LCD
JNB TF0, BACK ; loop if TF0=0
CLR TR0 ; stop the counter 0
CLR TF0 ; make TF0=0
SJMP AGAIN ; keep doing it
; converting 8-bit binary to ASCII
; upon return, R4, R3, R2 have ASCII data (R2 has LSD)
CONV: MOV B, #10 ; divide by 10
DIV AB
Dept. of EEE, SJBIT
14
Microcontroller 15EE52
MOV R2, B ; save low digit
MOV B, #10 ; divide by 10 once more
DIV AB
ORL A, #30H ; make it ASCII
MOV R4, A ; save MSD
MOV A,B
ORL A, #30H ; make 2nd digit an ASCII
MOV R3, A ; save it
MOV A, R2
ORL A, #30H ; make 3rd digit an ASCII
MOV R2, A ; save the ASCII
RET

Programming Timers 0 and 1 in 8051 C

Accessing timer registers in C:

In 8051 C we can access the timer registers TH, TL, and TMOD directly using the reg51.h header file.

Ex-1: Write a 8051 C program to toggle all the bits of port P1 continuously with some delay in between. Use
Timer 0, 16-bit mode to generate the delay.
Solution:

#include <reg51.h>
void T0Delay(void);
void main(void)
{
while (1) //repeat forever
{
P1=0x55; //toggle all bits of P1
T0Delay ( ); //delay size unknown
P1 = 0xAA; //toggle all bits of P1
T0DELAY ();
}
}
void T0Delay ( )
{
TMOD=0x01; //Timer 0, Mode1
TL0=0x00; //load TL0
TH0=0x35; //load TH0
TR0=1; //turn on T0
While (TF0= = 0); //wait for TF0 to roll over
TR0=0; //turn off T0
TF0=0; // clear TF0
}
FFFFH - 3500H = CAFFH = 51967+1 = 51968
51968x1.085µs=56.384 ms is the approximate delay.

Dept. of EEE, SJBIT


15
Microcontroller 15EE52
Ex-2: Write an 8051 C program to toggle only bit P1.5 continuously every 50ms. Use Timer 0, mode 1 (16-bit) to
create the delay.
Solution:

#include <reg51.h>
void T0M1Delay(void);
sbit mybit=P1^5;
void main(void)
{
while (1)
{
mybit=~mybit; //toggle P1.5
T0M1Delay ( ); //Timer 0, mode 1 (16-bit)
}
}
void T0M1Delay (void )
{
TMOD=0x01; //Timer 0, Mode1 (16-bit)
TL0=0xFD; //load TL0
TH0=0x4B; //load TH0
TR0=1; //turn on T0
While (TF0= = 0); //wait for TF0 to roll over
TR0=0; //turn off T0
TF0=0; // clear TF0
}

FFFFH - 4BFDH = B402H = 46082+1 = 46083


Timer delay=46083x1.085µs=50ms

Ex-3: Write an 8051 C program to toggle all bits of P2 continuously every 500 ms. Use Timer 1, mode 1 to create
the delay.
Solution:

#include <reg51.h>
void T1M1Delay(void);
void main(void)
{
unsigned char x;
P2=0x55;
while (1)
{
P2= ~ P2; // toggle all bits of P2
for (x=0; x<20; x++)
T1M1Delay( );
}
}
void T1M1Dealy(void)
{
Dept. of EEE, SJBIT
16
Microcontroller 15EE52
TMOD=0x10; //Timer 1, Mode1 (16-bit)
TL1=0xFE; //load TL1
TH1=0XA5; //load TH1
TR1=1; //turn on T1
While (TF1= = 0); //wait for TF1 to roll over
TR1=0; //turn off T1
TF1=0; // clear TF1
}

A5FEH = 42494 in decimal


65536 – 42494 = 23042
23042x1.085µs = 25ms and 20x25ms = 500ms

Ex-4: Write an 8051 C program to toggle only pin P1.5 continuously every 250ms. Use Timer 0, mode2 (8-bit
auto-reload) to create the delay.
Solution:

#include <reg51.h>
void T0M2Delay(void);
sbit mybit=P1^5;
void main(void)
{
unsigned char x, y;
while (1)
{
mybit = ~mybit // toggle P1.5
for (x=0; x=250; x++) //due to for loop overhead
for(y=0; y=36;y++) //we put 36 and not 40
T0M2Delay( );
}
}
void T0M2Delay (void )
{
TMOD=0x02; //Timer 0, Mode2 (8-bit auto-reload)
TH0=-23; //load TH0 (auto-reload value)

TR0=1; //turn on T0
While (TF0= = 0); //wait for TF0 to roll over
TR0=0; //turn off T0
TF0=0; // clear TF0
}
256 – 23 = 233
23x1.085µs = 25µs
25µsx250x40 = 250ms by calculation.

Ex-5: Write an 8051 C program to create a frequency of 2500 Hz on pin P2.7. Use Timer 1, mode 2 to create the
delay.
Solution:
Dept. of EEE, SJBIT
17
Microcontroller 15EE52
#include <reg51.h>
void T1M2Delay(void);
sbit mybit=P2^7;
void main(void)
{
unsigned char x, y;
while (1)
{
mybit = ~mybit // toggle P2.7
T1M2Delay( );
}
}
void T1M2Delay (void )
{
TMOD=0x20; //Timer 1, Mode2 (8-bit auto-reload)
TH0=-184; //load TH1 (auto-reload value)
TR1=1; //turn on T1
while(TF0= = 0); //wait for TF0 to roll over
TR1=0; //turn off T1
TF1=0; // clear TF1
}
1/2500Hz=400µs
400µs/2 = 200 µs
200µs/1.085µs=184

Ex-6: A switch is connected to pin P1.2. Write an 8051 C program to monitor SW and create the following
frequencies on pin P1.7: SW=0: 500Hz, SW=1: 750Hz. Use Timer 0, mode 1 for both of them.
Solution:

#include <reg51.h>
sbit mybit=P1^5;
sbit SW=P1^7;
void T0M1Delay(unsigned char);
void main(void)
{
SW=1; //make P1.7 an input
while (1)
{
mybit = ~mybit // toggle P1.5
if(SW= = 0) //check switch
T0M1Delay(0);
else
T0M1Delay(1);
}
}
void T0M1Delay(unsigned char c);
{
TMOD=0x01;
Dept. of EEE, SJBIT
18
Microcontroller 15EE52
If (c= = 0)
{
TL0=0x67; //FC67
TH0=0xFC;
}
else
{
TL0=0x9A; //FD9A
TH0=0xFD;
}
TR0=1;
while(TF0= = 0);
TR0=0;
TF0=0;
}
FC67H = 64615
65536-64615=921
921x1.085µs=999.285µs
1/(999.285µsx2)=500Hz

C programming of timers 0 and 1 as counters:


A timer can be used as a counter if we provide pulses from outside the chip instead of using the frequency of the
crystal oscillator as the clock source. By feeding pulses to the T0 (P3.4) and T1(P3.5) pins, we turn Timer 0 and Timer
1 into counter 0 and counter 1, respectively.

Ex-7: Assume that a 1-Hz external clock is being fed into pin T1 (P3.5). Write a C program for counter 1 in
mode 2 98-bit auto reload) to count up and display the state of the TL1 count on P1. Start count at 0H.
Solution:
#include <reg51.h>
sbit T1 = P3^5;
void main(void)
{
T1=1; // make T1 an input
TMOD = 0x60; //
TH1= 0; //set count to 0
While (1) //repeat forever
{
Do
{
TR1=1; //start timer
P1=TL1; //place value on pins
}
while(TF1= = 0); //wait here
TR1=0; //stop timer
TF1=0; //clear flag
}
}

Dept. of EEE, SJBIT


19
Microcontroller 15EE52
P1 is connected to 8 LEDs. T1 (P3.5) is connected to a 1-Hz external clock.

Ex-8: Assume that a 1-Hz external clock is being fed into pin T0 (p3.4). Write a C program for counter 0 in
mode 1 (16-bit) to count the pulses and display the TH0 and TL0 registers on P2 and P1, respectively.
Solution:
#include <reg51.h>
void main(void)
{
T0=1; // make T0 an input
TMOD=0x05; //
TL0=0; //set count to 0
TH0=-0; //set count to 0
while (1) //repeat forever
{
do
{
TR0=1; //start timer
P1=TL0; //place value on pins
P2=TH0; //
}
while (TF0= = 0); //wait here
TR0=0; //stop timer
TF0=0;
}
}
Ex-9: Assume that a 2-Hz external clock is being fed into pin T1 (P3.5). Write a C program for counter 0 in
mode 2 (8-bit auto reload) to display the count in ASCII. The 8-bit binary count must be converted to
ASCII. Display the ASCII digits (in binary) on P0, P1, and P2 where P0 has the least significant digit. Set
the initial value of TH0 to 0.
Solution:
To display the TL1 count we must convert 8-bit binary data to ASCII.
#include <reg51.h>
void BinToASCII (unsigned char);
void main(void)
{
unsigned char value;
T1=1;
TMOD=0x06;
TH0=0;
while (1)
{
do
{
TR0=1;
value=TL0;
BinToASCII(value);
}
while (TF0= = 0);
Dept. of EEE, SJBIT
20
Microcontroller 15EE52
TR0=0;
TF=0;
}
}
void BinToASCII(unsigned char value) //see Chapter7
{
unsigned char x, d1,d2,d3;
x= value/10;
d1= value%10
d2= x/10;
d3 = x/10
p0 =30 | d1;
p1 =30 | d2;
p2 =30 | d3;
}

Ex-10: Assume that a 60-Hz external clock is being fed into pin T0 (P3.4). Write a C program for counter 0 in
mode 2 (8-bit auto-reload) to display the seconds and minutes on P1 and P2, respectively.
Solution:
#include <reg51.h>
void ToTime (unsigned char);
void main(void)
{
unsigned char val;
T0=1;
TMOD=0x06; //T0, mode 2, counter
TH0=--60; //sec = 60 pulses
while (1)
{
Do
{
TR=1;
Sec=TL0;
ToTime(val);
}
while(TF= = 0);
TR0=0;
TF=0;
}
}
void ToTime (unsigned char val)
{
unsigned char sec, min;
min = value / 60;
sec = value %60;
P1 = sec;
P2 = min;
}
Dept. of EEE, SJBIT
21
Microcontroller 15EE52

Dept. of EEE, SJBIT


22

You might also like