You are on page 1of 40

UNIT II

8051 PROGRAMMING

Assembly language programming – Arithmetic Instructions – Logical Instructions –


Single bit Instructions – Timer Counter Programming – Serial Communication
Programming Interrupt Programming – RTOS for 8051 – RTOSLite – FullRTOS –
Task creation and run – LCD digital clock/thermometer using FullRTOS

Assembly language programming Arithmetic Instructions

Example:
MOV A,#88H
ADD A,#93H

88 10001000
+93 +10010011
---- --------------
11B 00011011
CY=1 AC=0 P=0

Example:
MOV A,#38H
ADD A,#2FH

38 00111000
+2F +00101111
---- --------------
67 01100111
CY=0 AC=1 P=1

Example:
MOV A,#9CH
ADD A,#64H

9C 10011100
+64 +01100100
---- --------------
100 00000000
CY=1 AC=1 P=0
MUL AB ;B|A = A*B
MOV A,#25H
MOV B,#65H
MUL AB ;25H*65H=0E99
;B=0EH, A=99H
DIV AB ;A = A/B, B = A mod B
MOV A,#25
MOV B,#10
DIV AB ;A=2, B=5
Looping

Repeating a sequence of instructions a certain number of times is called a loop

Loop action is performed by


DJNZ reg, Label
The register is decremented one
If it is not zero, it jumps to the target address referred to by the label
Prior to the start of loop the register is loaded with the counter for the number of
repetitions
reg can be R0 – R7 or RAM location

MOV A ,#0 ;A=0, clear ACC

MOV R2 ,#10 ;load counter R2=10

AGAIN:
ADD A ,#03 ;add 03 to ACC
DJNZ R2 ,AGAIN ;repeat until R2=0,10 times
MOV R5 ,A ;save A in R5
This program adds value 3 to the ACC ten times
How many times this loop can be repeated?
Nested Loop

MOV A,#55H ;A=55H

MOV R3,#10 ;R3=10, outer loop count


NEXT :
MOV R2,#70 ;R2=70, inner loop count
AGAIN :
CPL A ;complement A register
DJNZ R2 ,AGAIN ;repeat it 70 times
DJNZ R3 ,NEXT
Port 1 as Output(Write to a Port)

Send data to Port 1

MOV A,#55H
BACK: MOV P1,A
ACALL DELAY
CPL A
SJMP BACK

Let P1 toggle.
You can write to P1 directly.

Reading Input v.s. Port Latch

When reading ports, there are two possibilities :


Read the status of the input pin. ( from external pin value )
MOV A, PX
JNB P2.1, TARGET ; jump if P2.1 is not set
JB P2.1, TARGET ; jump if P2.1 is set
Figures C-11, C-12
Read the internal latch of the output port.
ANL P1, A ; P1 ← P1 AND A
ORL P1, A ; P1 ← P1 OR A
INC P1 ; increase P1
Figure C-17
Table C-6 Read-Modify-Write Instruction (or Table 8-5)
See Section 8.3

Port 1 as Input(Read from Port)

In order to make P1 an input, the port must be programmed by writing 1


to all the bit.

MOV A,#0FFH ;A=11111111B


MOV P1,A ;make P1 an input port
BACK: MOV A,P1 ;get data from P0
MOV P2,A ;send data to P2
SJMP BACK

To be an input port, P0, P1, P2 and P3 have similar methods.


Indicate which mode and which timer are selected for each of the
following.
(a) MOV TMOD,#01H (b) MOV TMOD,#20H
(c) MOV TMOD,#12H

Solution:(a) TMOD = 00000001, mode 1 of timer 0 is selected.


(b) TMOD = 00100000, mode 2 of timer 1 is selected.
(c) TMOD = 00010010
mode 2 of timer 0, and mode 1 of timer 1 are selected.

Find the timer’s clock frequency and its period for various 8051-

based systems, with the following crystal frequencies.


(a) 12 MHz (b) 16 MHz (c) 11.0592 MHz

Solution:

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.
In the following program, we are creating a square wave of 50% duty cycle (with
equal portions high and low) on the P1.5 bit. Timer 0 is used to generate the time
delay.

Analyze the program.

;generate delay using timer 0

DELAY:
SETB TR0 ;start the timer 0
AGAIN:JNB TF0,AGAIN
CLR TR0 ;stop timer 0
CLR TF0 ;clear timer 0 flag
RET
Solution:

In the above program notice the following steps.

1. TMOD = 0000 0001 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 the passing of each clock, which is provided by the crystal
oscillator.
As the timer counts up, it goes through the states of FFF3, FFF4, FFF5, FFF6, FFF7,
FFF8, FFF9, FFFA, FFFB, FFFC, FFFFD, FFFE, 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.

8. Remember to clear TF0 by the instruction “CLR TF0”.

Notice that to repeat the process, we must reload the TL and TH registers, and start
the timer again (in the main program).

In the above Example, calculate the amount of time delay in the DELAY subroutine
generated by the timer. Assume that XTAL = 11.0592 MHz.

Solution:
The timer works with the internal system clock.
frequency of internal system clock = 11.0592/12 = 921.6 KHz
machine cycle = 1 /921.6 KHz = 1.085 s (microsecond)
The number of counts = FFFFH – FFF2H +1 = 14 (decimal).
The delay = number of counts × 1.085 s = 14 × 1.085 s = 15.19 s for half the
clock.
For the entire period of a clock, it is T = 2 × 15.19 s = 30.38 s as the time delay
generated by the timer.
In the above Example, calculate the accurate frequency of the square wave

generated on pin P1.5.

Solution:
In the time delay calculation of Example 9-5, we did not include
the overhead due to instructions in the loop.
To get a more accurate timing, we need to add clock cycles from Table A-1 in
Appendix A, as shown below.

HERE: MOV TL0,#0F2H 2

MOV TH0,#0FFH 2
CPL P1.5 1
ACALL DELAY 2
SJMP HERE 2
;----------delay using timer 0
DELAY:
SETB TR0 1
AGAIN: JNB TF0,AGAIN 14
CLR TR0 1
CLR TF0 1
RET 20
Total 28
T = 2 × 28 × 1.085 s = 60.76 s, and F = 16458.196 Hz.
Find the delay generated by timer 0 in the following code, using

both of the methods of Figure 9-4. Do not include the overhead due
to instructions.

Solution:

(a) or (b) is OK.


(a) (FFFF – B83E + 1) = 47C2H = 18370 in decimal and 18370 ×
1.085 s = 19.93145 ms.
(b) Since TH-TL = B83EH = 47166 (in decimal ) we have
65536 – 47166 = 18370. This means that the timer counts from
B83EH to FFFF. 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 × 1.085 s = 19.93145 ms
as the width of the pulse.
Modify TL and TH in Example 9-7 to get the largest time delay

possible. Find the delay in ms. In your calculation, exclude the


overhead due to the instructions in the loop.
Solution:

TH0=TL0=0 means that the timer will count from 0000 to FFFF, and then roll over to
raise the TF0 flag.
As a result, it goes through a total of 65536 states. Therefore, we have delay = (65536
– 0) × 1.085 s = 71.1065 ms.

The following program generates a square wave on pin P1.5

continuously using timer 1 for a time delay. Find the frequency of


the square wave if XTAL = 11.0592 MHz. In your calculation do
not include the overhead due to instructions in the loop.

MOV TMOD,#10H ;timer 1, mode 1


AGAIN:MOV TL1,#34H ;timer value=3476H
MOV TH1,#76H
SETB TR1 ;start
BACK: JNB TF1,BACK
CLR TR1 ;stop
CPL P1.5 ;next half clock
CLR TF1 ;clear timer flag 1
SJMP AGAIN ;reload timer1
Solution:

In mode 1, the program must reload the TH1, TL1 register every timer if we want to
have a continuous wave.
FFFFH – 7634H + 1 = 89CCH = 35276 clock count
Half period = 35276 × 1.085 s = 38.274 ms
Whole period = 2 × 38.274 ms = 76.548 ms
Frequency = 1/ 76.548 ms = 13.064 Hz.

Also notice that the high portion and low portion of the square wave are equal.
In the above calculation, the overhead due to all the instructions in the loop is not
included.
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:
XTAL = 11.0592 MHz  MC = 1.085 s.
5 ms / 1.085 s = 4608 MCs.
To achieve that we need to load into TL0 and TH0 the value 65536 – 4608 = 60928 =
EE00H.
Therefore, we have TH0 = EE and TL0 = 00.

Assuming that XTAL = 11.0592 MHz, write a program to generate a square wave of
2 kHz frequency on pin P1.5.

Solution:
This is similar to Example 9-10, except that we must toggle the bit to generate the
square wave. Look at the following steps.
(a) The period of square wave = 1 / frequency
= 1 / 2 kHz = 500 s.
(b) The half period = 500 s /2 = 250 s.
(c) 250 s / 1.085 s = 230
65536 – 230 = 65360 = FF1AH.
(d) TL1 = 1AH and TH1 = FFH

Assuming XTAL = 11.0592 MHz, write a program to generate a


square wave of 50 Hz frequency on pin P2.3.

Solution:
Look at the following steps.
(a) The period of the square wave = 1 / 50 Hz = 20 ms.
(b) The high or low portion of the square wave = 10 ms.
(c) 10 ms / 1.085 s = 9216
65536 – 9216 = 56320 in decimal = DC00H in hex.
(d) TL1 = 00H and TH1 = DCH.
Examine the following program and find the time delay in seconds.
Exclude the overhead due to the instructions in the loop.

MOV TMOD,#10H
MOV R3,#200
AGAIN: MOV TL1,#08
MOV TH1,#01
SETB TR1
BACK: JNB TF1,BACK
CLR TR1
CLR TF1
DJNZ R3,AGAIN
Solution:
TH1-TL1 = 0108H = 264 in decimal
65536 – 264 = 65272.
One of the timer delay = 65272 × 1.085 s = 70.820 ms
Total delay = 200 × 70.820 ms = 14.164024 seconds
• Mode 0 is used to compatible with MSC-48
• Mode 0 is exactly like mode 1 except that it is a 13-bit timer instead of 16-bit.
• The counter can hold values between 0000 to 1FFF
• 213 -1= 2000H-1=1FFFH
• When the timer reaches its maximum of 1FFFH, it rolls over to 0000, and TF0 is
raised.
Assuming that XTAL = 11.0592 MHz, find

(a) the frequency of the square wave generated on pin P1.0 in the following program
(b) the smallest frequency achievable in this program, and the TH value to do that.

Example

MOV TMOD,#20H ;Timer 1,mode 2


MOV TH1,#5 ;not load TH1 again
SETB TR1 ;start (no stop TR1=0)
BACK:JNB TF1,BACK
CPL P1.0
CLR TF1 ;clear timer flag 1
SJMP BACK ;mode 2 is auto-reload
Solution:

(a) First notice that target address of SJMP. In mode 2 we do not


need to reload TH since it is auto-reload.
Half period = (FFH – 05 +1) × 1.085 s = 272.33 s
Total period = 2 × 272.33 s = 544.67 s
Frequency = 1.83597 kHz.
(b) To get the smallest frequency, we need the largest period and that is achieved
when TH1 = 00.
Total period = 2 × 256 × 1.085 s = 555.52 s
Frequency = 1.8kHz.
Find the frequency of a square wave generated on pin P1.0.
Solution:
MOV TMOD,#2H ;Timer 0,mode 2
MOV TH0,#0
AGAIN:MOV R5,#250 ;count 250 times
ACALL DELAY
CPL P1.0
SJMP AGAIN
DELAY:SETB TR0 ;start
BACK: JNB TF0,BACK
CLR TR0 ;stop
CLR TF0 ;clear TF
DJNZ R5,DELAY ;timer 2: auto-reload
RET
T = 2 (250 × 256 × 1.085 s) = 138.88 ms, and frequency = 72 Hz.
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 TH0,#-60 (c) MOV TH1,#-3
(d) MOV TH1,#-12 (e) MOV TH0,#-48
Solution:
Some 8051 assemblers provide this way.
-200 = -C8H  2’s complement of –200 = 100H – C8H = 38 H

Find (a) the frequency of the square wave generated in the

following code, and (b) the duty cycle of this wave.

Solution:
“MOV TH0,#-150” uses 150 clocks.
The DELAY subroutine = 150 × 1.085 s = 162 s.
The high portion of the pulse is twice that of the low portion (66% duty cycle).
The total period = high portion + low portion
= 325.5 s + 162.25 s = 488.25 s
Frequency = 2.048 kHz.
MOV TMOD,#2H ;Timer 0,mode 2
MOV TH0,#-150 ;Count=150
AGAIN:SETB P1.3
ACALL DELAY
ACALL DELAY
CLR P1.3
ACALL DEALY
SJMP AGAIN
DELAY:SETB TR0 ;start
BACK: JNB TF0,BACK
CLR TR0 ;stop
CLR TF0 ;clear TF
RET
Counter Programming

Assuming that clock pulses are fed into pin T1, write a program for

counter 1 in mode 2 to count the pulses and display the state of the
TL1 count on P2.
Solution:

We use timer 1 as an event counter where it counts up as clock pulses are fed into
pin3.5

MOV TMOD,#01100000B ;mode 2, counter 1

MOV TH1,#0
SETB P3.5 ;make T1 input port
AGAIN:SETB TR1 ;start
BACK: MOV A,TL1
MOV P2,A ;display in P2
JNB TF1,BACK ;overflow
CLR TR1 ;stop
CLR TF1 ;make TF=0
SJMP AGAIN ;keep doing it
Notice in the above program the role of the instruction “SETB
P3.5”. Since ports are set up for output when the 8051 is powered
up , we must make P3.5 an input port by making it high.
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:
Note that on the first round, it starts from 0 and counts 256 events, since on RESET,
TL0=0. To solve this problem, load TH0 with -60 at the beginning of the
program.

ACALL LCD_SET_UP ;initialize the LCD

MOV TMOD,#00000110B ;Counter 0,mode2


MOV TH0,#C4H ;C4H=-60
SETB P3.4 ;make T0 as input
AGAIN:SETB TR0 ;starts the counter
BACK: MOV A,TL0 ; every 60 events
ACALL CONV ;convert in R2,R3,R4
JNB TF0,BACK ;loop if TF0=0
CLR TR0 ;stop
CLR TF0
SJMP AGAIN
;converting 8-bit binary to ASCII

CONV: MOV B,#10 ;divide by 10


DIV AB
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
MOV A,B
ORL A,#30H
MOV R3,A
MOV A,R2
ORL A,#30H
MOV R2,A ;ACALL LCD_DISPLAY here
RET
Write an 8051 C program to toggle bits of P1 continuously with some time delay. Use
Timer 0, 16-bit mode.

Solution:

#include <reg51.h>
void T0Delay(void);
void main(void) {
while(1) { //repeat forever
P1=0x55;
T0Delay(); //time delay
P1=0xAA;
T0Delay(); }}
Assume XTML=11.0592MHz for the AT89C51

FFFFH-3500H+1=CB00H=51968
1.085s 51968  56.384ms

void T0Delay() {
TMOD=0x01; //Timer 0, Mode 1
TL0=0x00; TH0=0x35; //initial value
TR0=1; //turn on T0
while (TF0==0); //text TF to roll over
TR0=0; //turn off T0
TF0=0; } //clear TF0
A switch is connected to P1.7. Write an 8051 C program to monitor SW and create
the following frequencies on P1.5.

SW=0: 500 Hz; SW=1: 750 Hz. Using Timer 0, mode 1.


Assume XTML=11.0592MHz for the AT89C51

Solution:

#include <reg51.h>
sbit mybit=P1^5;
sbit SW=P1^7;
void T0Delay(void);
void main(void) {

SW=1; //make P1.7 an input pin


while(1) { //repeat forever
mybit=~mybit; //toggle
if (SW==0)
T0Delay(0); //500Hz time delay
else
T0Delay(1); //750Hz time delay
}}
void T0Delay(unsigned char c) {

TMOD=0x01; //Timer 0, Mode 1


if (c==0) { TL0=0x67; TH0=0xFC };
// FFFFH-FC67H+1=921, about 999.285s, 500 Hz
else { TL0=0x9A; TH0=0xFD };
// FFFFH-FD9AH+1=614, about 666.19s, 750 Hz
TR0=1;
while (TF==0);
TR0=0;
TF0=0;
}
Write an 8051 C program to toggle bits P1.5 continuously every 50 ms. Use Timer 0,
mode 1 for (a) AT89C51 and

(b) DS89C420.
Solution:

#include <reg51.h>
void T0Delay(void);
sbit mybit=P1^5;
void main(void) {
while(1) { //repeat forever
mybit=~mybit;
T0Delay(); }}
(a) Assume XTML=11.0592MHz for the AT89C51

FFFFH-4BFDH+1=B403H=46083
1.085s 46083  50ms

void T0Delay() {
TMOD=0x01; //Timer 0, Mode 1
TL0=0xFD; TH0=0x4B; //initial value
TR0=1; //turn on T0
while (TF0==0); //BACK: JNZ TF0,BACK
TR0=0; //turn off T0
TF0=0; } //clear TF0
(b) Assume XTML=11.0592MHz for the DS89C4x0

FFFFH-4BFDH+1=B403H=46083
1.085s 46083  50ms

void T0Delay() {
TMOD=0x01; //Timer 0, Mode 1
TL0=0xFD; TH0=0x4B; //initial value
TR0=1; //turn on T0
while (TF0==0); //BACK: JNZ TF0,BACK
TR0=0; //turn off T0
TF0=0; } //clear TF0
Assume that a 1-Hz external clock is being fed into T1 (P3.5). Write a C program for
counter 1 in mode 2 to count up and display the state of the TL1 count on P1.
Start the count at 0H.

Solution:

P1 is connected to 8 LEDs.

T1 is connected to 1Hz external clock.

#include <reg51.h>

sbit T1=P3^5;
void main(void) {
T1=1; //make T1 an input pin
TMOD=0x60; //counter 1, mode 2
TH1=0; //reload value
while(1) { //repeat forever
do {TR1=1; P1=TL1;} while (TF1==0);
TR1=0; TF1=0; //clear flags
}}

RTOS for 8051

RTOS is a program that controls the execution of multiple ‘threads’ of an


application in a computing system by prioritizing their execution and allowing them
to communicate with each other.” Thread is the term used to describe the individual
subtasks (of just tasks) of an application.
There may be multiple threads, but each one is following its own path. An
important point about threads is that if the operating system is executing more than
one of them simultaneously, then it is known as a multithreaded operating system or a
multitasking operating system (often abbreviated to multitasker). The RTOS provides
an abstraction layer between the hardware and application software.
They are often called akernel or executiveprocess..

Tasks
Application software is split up into multitasking blocks called ‘Tasks’.

Tasks are generic computational blocks with

Timing constraints

Synchronization and communication relationships with other tasks

Generally each device is represented by its own task.


Tasks can be in one of four states

SLEEPING

READY

RUNNING
BLOCKED

Ways to move between tasks:

SLEEPING -> READY through an RTOS system function called from a different
task.

READY -> RUNNING from being selected for execution by the RTOS. There can
only be one RUNNING task at a time.

RUNNING -> BLOCKED when the task is told to wait for an event to occur.

BLOCKED -> RUNNING

After the event, a task has been waiting for occurs and has higher
priority than current RUNNING task.

RUNNING -> SLEEPING

once task has finished execution.


Task scheduling
RTOS decides which task to run using a scheduler, based on a machine clock
cycle. RTOS system clock ‘machine cycles’ based on hardware timer overflow,
generally Timer 0.

At each machine clock cycle:

• Processor executes RTOS program


• RTOS updates tables that track task state, interval count, timeout count, etc.

• RTOS decides which task should get to execute

RTX51-Tiny
• RTX51 is a commercial RTOS from Keil, available in Full or Tiny version.

• RTX51-Tiny comes with the PK51 Professional Developer’s Kit.

• RTX51-Tiny features:

• Only 900 bytes of code space required

• Requires one hardware timer, Timer 0

• Supports inter-task signaling


• RTX51-Full supports extra features:

• Preemptive task scheduling

• Task priorities

• Task interrupts

• Messaging routines

• Memory allocation routines

Task declaration
#include <rtx51tny.h>

int counter1;

void task0 (void) _task_ 0 { // RTX51 begins task 0

counter1 = 0; // initialize counter

os_create_task (1); // make task 1 ready

os_delete_task (0); // stop task 0 (init is

// completed).
}

void task1 (void) _task_ 1 {

while (1) { // infinite loop

counter1++; // increment counter 1

Task declaration is similar to C function declaration with a ‘_task_’ attribute.


Each task must be assigned a number from 0-255 in Full or 0-15 in Tiny.

Tasks do not return or take any parameters except void. RTX51-Tiny always starts
execution at task number 0. RTX51-Full must start the RTOS from main()
Task Scheduling
RTX51 supports preemptive, round-robin, and cooperative task scheduling
algorithm. RTX51 scheduler chooses the task to run by: The highest priority of all
tasks that are READY The task that has been waiting for the longest time if all tasks
have the same priority RTOS only switches tasks if the first rule is violated, except in
round-robin scheduling
Multitasking
1. Round-Robin Multitasking

• Default scheduling method for RTX51-Tiny

• Every task is run in turn for an equal length of time called the time-slice

• Time-slice is defined during compile, based on number of machine cycles of


the system clock
Round-Robin example
#include <rtx51tny.h>

int counter0;

int counter1;

int counter2;

void job0 (void) _task_ 0 { // RTX51 begins in task0

counter0 = 0; // initialize counters

counter1 = 0;

counter2 = 0;

os_create_task (1); // start task 1

os_create_task(2); // start task 2

while (1) { // infinite loop

counter0++; // increment counter 0

void job1 (void) _task_ 1 {

while (1) { // infinite loop

counter1++; // increment counter1

}
}

void job2 (void) _task_ 2 {

while (1) { // infinite loop

counter2++; // increment counter2

When there is only one task, the RTOS always chooses job0 to run after its
time-slice. When all three tasks are READY to run, job1 runs after job0, and job2
runs after job1.

The time-slice is defined in ‘Conf_tny.A51’.

; Define Hardware-Timer machine cycle time in 8051 machine cycles

INT_CLOCK EQU 10000

;default is 10000 cycles


;

; Define Round-Robin Timeout in Hardware-Timer machine cycles.

; Default is 5 Hardware-Timer machine cycles.

; 0 disables Round-Robin Task Switching

TIMESHARING EQU 5

2. Cooperative Multitasking
A type of multitasking in which the process currently controlling the CPU must
offer control to other processes. It is called cooperative because all programs must
cooperate for it to work
Configure RTX51 to schedule in cooperative mode by setting the TIMESHARING
variable in ‘Conf_tny.A51’ to 0.

TIMESHARING EQU 0

Tasks switches are only performed when the running task voluntarily gives up control
of the processor.
Code example
#include <rtx51tny.h>

int counter0;

int counter1;

void job0 (void) _task_ 0 { // RTX51 begins in task 0

os_create (1); // make task 1 READY

while (1) { // infinite loop

// increment counter

if (++counter0 == 0) {

// signal task 1

os_send_signal (1);
// wait for signal; releases CPU control

os_wait (K_SIG, 0, 0);

}
os_wait (K_TMO, 1, 0); // wait for 1 machine cycle, give up CPU

void job1 (void) _task_ 1 {

while (1) { // infinite loop

os_wait (K_SIG, 0, 0); // wait for signal

// give up CPU

// increment counter 1

counter1++;

os_send_signal (0); // signal task 0

}
Task 0 gives up control of processor at ‘os_wait’, where it waits for an event to
occur. Before doing so, task 0 signals task 1 making it READY to execute. Tasks
have to manually control execution order using communication methods like signals.

3. Priority-Driven Preemptive Multitasking


Requires task priorities that are not available in RTX51-Tiny. Tasks can be
assigned a priority from 0-3, with 0 being the lowest priority. 0 is also the default
priority for RTX51-Tiny tasks. Declare task priority by adding a ‘_priority_’
parameter.

void job1 (void) _task_ 1 _priority_ 1 {


Preemption is necessary sometimes to meet task deadlines.

Preemptive scheduler can switch tasks before the time-slice for the RUNNING task
runs out.
Preemption example
#include <rtx51tny.h>
int counter0;

int counter1;

void job0 (void) _task_ 0 _priority_ 0 {// RTX51 starts off in task 0

os_create (1); // start task 1

while (1) { // infinite loop

// increment counter 0

if (++counter0 == 0)

// signal task 1

os_send_signal (1);

os_wait (K_TMO, 1, 0); // wait for 1 machine cycle

void job1 (void) _task_ 1 _priority_ 1 {

while (1) { // infinite loop

os_wait (K_SIG, 0, 0); // wait for signal

// increment counter 1

counter1++;

}
}
RTOS Events
Events can be used by tasks to communicate between each other or to help
coordinate execution flow.

Four common RTOS events:

• Signals

• Messages

• Semaphores

• Interrupts
Signal Event Based Communication
• Signaling is the fastest method of communication.

• No actual information is exchanged, a signal is simply a single-bit flag.

• It is important for coordinating execution flow amongst tasks.


• Only one signal can be saved per task, and any extra signals are ignored.
void task1 (void) _task_ 1 {

...

os_send_signal (2); // signal task 2

os_clear_signal (1); // clear task 1 flag

os_wait (K_SIG, 0, 0); // wait for signal

...

• Tasks can send and clear signal for any other task, including itself.

• Tasks waiting for signal are BLOCKED. The RTOS unblocks that task once
the event is received.

Message Event Based Communication


• Messaging is only available in RTX51-Full.

• A message is a set of data that gets transferred through message queues or


mailboxes.

• Messages in RTX51 are 16-bit data values or a pointer to data buffer.

• RTX51 has eight mailboxes that are not tied to any single task, numbered 0-7.
• Tasks which send messages are BLOCKED until the message can be sent or
timeout occurs.

int message;

...

// send data in variable ‘message’ to mailbox 2;

// timeout after 10 machine cycles

os_send_message (2, message, 10);


Tasks can wait for messaging event and store the message to variable.

// wait for message in mailbox 3 and store

// in &message; or timeout in 10 machine cycles

os_wait (K_MBX + K_TMO + 3, 10, &message);


Semaphores
• Semaphores are only available for RTX51-Full.

• Semaphores help prevent resource sharing conflicts between tasks.

• RTX51 has eight binary semaphores, numbered 8-15.

// wait for token from semaphore 14

os_wait (K_MBX + 14, 0, 0);

// protected task functions

...

// finished with semaphore, return token

os_send_token (14);
Task Interrupts
• RTX51-Full supports attaching hardware interrupt vectors to tasks.

• Each interrupt source can only be assigned to one task.

• Multiple interrupts can be assigned to a single task.

• Attaching an interrupt does not automatically set the corresponding interrupt


enable flag. In fact, the relevant flags are only enabled when tasks begin to
wait for an interrupt event.
void task1 (void) _task_ 1 {

// attach interrupt 14 (Timer 3 overflow)

os_attach_interrupt (14);
while (1) {

// wait for interrupt

os_wait (K_INT, 0, 0);

...

}
When to use RTOS
• Large projects benefit from using an RTOS

• Standardized system functions (task switching, task communication, etc.)


makes coding easier

• Tasks makes large systems more modular and easier to debug

• Generally when a system has a dozen or more tasks that all have timing
constraints
• Ultra-compact systems may be better off without using an RTOS

• Small systems are easier to code from scratch and can incorporate processor
optimizations, making the system more efficient than one using RTOS

• A full-featured RTOS may not fit within the size limits of an ultra-compact
system.
• RTOS standardizes system functions and makes coding real-time systems
easier.

• Three predominant scheduling methods are: preemptive, round-robin, and


cooperative

• Intertask communication can be done through signals or messages.

• Large systems benefit from RTOS, while compact systems can be more
efficient if it is custom-written.
LCD based digital alarm clock with digital thermometer using 8051
microcontroller

Celsius scale thermometer displays the ambient temperature through a LCD


display. It consists of two sections. One is that which senses the temperature. This is a
temperature sensor LM 35. The other section converts the temperature value into a
suitable number in Celsius scale which is done by the ADC0804. A digital
thermometer can be easily made by interfacing a temperature sensor to the
microcontroller AT89C51. The temperature sensor used in the project isLM35. The
LM 35 IC generates a 10mV variation to its output voltage for every degree Celsius
change in temperature. The Output of the temperature sensor is analog in nature so
we need an analog to digital convertor for converting the analog input to its
equivalent binary output.ADC 0804 is an analog to digital convertor IC used in the
project. 0804 is a single channel convertor which converts the analog input up to a
range of 5V to an equivalent 8-bit binary output.
This project incorporates the functionality of a digital clock and a digital
thermometer. The digital clock works in 12 hour mode and is configured by
programming the 8051 microcontroller (AT89C51). The program uses a delay
function for producing a delay of 1 second. The clock and alarm times can be set
through a set of external tactile switches. The digital thermometer employs a
temperature sensor LM35. The sensor responds to the temperature change by giving
varying output. These analog signals of LM35 are converted to digital equivalent by
ADC0804. The reference voltage (Vref) should be set properly corresponding to the
desired temperature range. The data bits are taken as input by the microcontroller at
port P0. The microcontroller AT89C51 also gives control signals to ADC0804.

You might also like