The 8051 Microcontroller and Embedded Systems: 8051 Assembly Language Programming
The 8051 Microcontroller and Embedded Systems: 8051 Assembly Language Programming
1
and Embedded Systems
CHAPTER 2
8051 ASSEMBLY LANGUAGE PROGRAMMING
2 SECTION 2.1: INSIDE THE 8051
Registers
Figure 2–1a
Some 8-bit Registers of the 8051
3 SECTION 2.1: INSIDE THE 8051
Registers
MOV instruction
MOV destination, source ;copy source to destination
ADD instruction
ADD A, source ;ADD the source operand
;to the accumulator
Figure 2–5
RAM Allocation in the 8051
19 SECTION 2.7: 8051 REGISTER BANKS AND
STACK
JZ (jump if A = 0)
In this instruction the content of register A is checked. If it is zero, it jumps to the
target address.
JZ instruction can be used only for register A.
It can only check to see whether the accumulator is zero, and it does not apply
to any other register.
Don't have to perform an arithmetic instruction such as decrement to use the JZ
instruction.
29 Other conditional jumps
JNZ (jump if A 0)
In this instruction the content of register A is checked. If it is not zero, it jumps to
the target address.
30 Other conditional jumps
Table 3–1
8051 Conditional
Jump
Instructions
33 Unconditional jump instructions
There are two unconditional jumps: LJMP (long jump) and SJMP (short
jump).
LJMP is 3-byte instruction in which the first byte is the op-code, and the second
and third bytes represent the 16-bit address of the target location.
The 2-byte target address.
34 Unconditional jump instructions
Example 3-6
Using the following list tile, verify the jump forward address calculation.
5 0006 08 INC R0
7 0008 04 INC A
10 000D E4 CLR A
18 0017 END
36 Calculating the short jump address
In that program list "JNC AGAIN" has opcode 50 and relative address F2H.
When the relative address of F2H is added to 15H, the address of the
instruction below the jump, we have 15H+F2H=07 (the carry is dropped).
Notice that 07 is the address of label AGAIN. Look also at "SJMP HERE",
which has 80 and FE for the opcode and relative address, respectively. The
PC of the following instruction. 0017H, is added lo FEH, the relative
address, to get 0015H, address of the HERE label ( 17H + FEH =15H).
Notice that FEH is -2 and 17H + (-2) = 15H. For further discussion of the
addition of negative numbers.
37 SECTION 3.2: CALL INSTRUCTIONS
Figure 3–1
8051 Assembly Main Program
That Calls Subroutines
40 SECTION 3.2: CALL INSTRUCTIONS
Table 3–2 Clocks per Machine Cycle (MC) for Various 8051 Versions
43 SECTION 3.3: TIME DELAY FOR VARIOUS 8051
CHIPS
45
46 OBJECTIVES
All the ports upon RESET are configured as inputs, ready to be used as input
ports.
When the first 0 is written to a port, it becomes an output.
To reconfigure it as an input, a 1 must be sent to the port.
To use any of these ports as an input port, it must be programmed.
49 SECTION 4.1: 8051 I/O PROGRAMMING
Port 0
Figure 4–2
Port 0 with Pull-Up Resistors
50 Port 0
Port 1
It can be used as input or output.
This port does not need any pull-up resistors since it already has pull-up
resistors internally.
Upon reset, port I is configured as an input port.
54 Port 1 as input
Port 2
Port 2 occupies a total of 8 pins (pins 21 through 28).
It can be used as input or output.
Port 2 does not need any pull-up resistors since it
already has pull-up resistors internally.
Upon reset, port 2 is configured as an input port.
57 Port 2 as input
Port 3
Table 4–1
Port 3 Alternate Functions
61 SECTION 4.1: 8051 I/O PROGRAMMING
Table 4–3
Single-Bit Addressability
of Ports
67 SECTION 4.2: I/O BIT MANIPULATION
PROGRAMMING
Some instructions read the status of port pins while others read the status of
an internal port latch.
When reading ports there are two possibilities:
1. Read the status of the input pin.
2. Read the internal latch of the output port.
71 Instructions for reading input ports
To make any bit of any 8051 port an input port, we must write 1 (logic high)
to that bit.
After we configure the port bits as input, we can use only certain instructions
in order to get the external data present at the pins into the CPU.
72 Reading latch for output port
Register addressing mode involves the use of registers to hold the data to
be manipulated.
79
SECTION 5.2: ACCESSING MEMORY USING
VARIOUS ADDRESSING MODES
Direct addressing mode
There are 128 bytes of RAM in the 8051.
The RAM has been assigned addresses 00 to 7FH.
1. RAM locations 00 - 1 FH are assigned to the register banks and
stack.
2. RAM locations 20 - 2FH are set aside as bit-addressable space
to save singlebit data.
3. RAM locations 30 - 7FH are available as a place to save byte-
sized data.
80 Direct addressing mode
In the 8051, registers A, B, PSW, and DPTR are part of the group of registers
commonly referred to as SFR.
The SFR can be accessed by their names or by their addresses.
For example, register A has address E0H and register B has been
designated the address F0H.
SFR registers and their addresses
83
84 SFR
85
Stack and direct addressing mode
Bit-addressable RAM
Figure 5–1
16 Bytes of Internal RAM. Note:
They are both bit- and byte-accessible.
95 SECTION 5.3: BIT ADDRESSES FOR I/O AND
RAM
Bit-addressable RAM
Registers bit-addressability
The BIT directive is a widely used directive to assign the bit-addressable I/0
and RAM locations.
The BIT directive allows a program to assign the I/0 or RAM bit at the
beginning of the program, making it easier to modify them.
100 Using EQU directive
Unpacked BCD
The lower 4 bits of the number represent the BCD number.
The rest of the bits are 0.
For example, "0000 1001" and "0000 0101" are unpacked BCD for 9 and 5,
respectively.
Unpacked BCD requires 1 byte of memory or an 8-bit register to contain it.
105 SECTION 6.1: ARITHMETIC INSTRUCTIONS
Unpacked BCD
Packed BCD
A single byte has two BCD numbers in it, one in the lower 4 bits, and one in the
upper 4 bits.
For example, "0101 1001" is packed BCD for 59H.
It takes only 1 byte of memory to store the packed BCD operands.
Its more efficient than unpacked BCD.
107 BCD (binary coded decimal) number
system
MOV A, #17BCD
ADD A,#28BCD ;A = 3F which is not BCD
;should be 17 + 28 = 45BCD
DA instruction
MOV A,#47H ;A=47H first BCD operand
MOV B,#25H ;B=25 second BCD operand
ADD A,B ;hex (binary) addition (A=6CH)
DA A ;adjust for BCD addition (A=72H)
In multiplying or dividing two numbers in the 8051, the use of registers A and
B is required.
The multiplication and division instructions work only with these two
registers.
114 Multiplication of unsigned numbers
In the division of unsigned numbers, the 8051 supports byte over byte only.
DIV AB ;divide A by B
The numerator must be in register A and the denominator must be in B.
After the DIV instruction is performed, the quotient is in A and the remainder
is in B.
117 Division of unsigned numbers
In signed byte operands, D7 (MSB) is the sign and D0 to D6 are set aside for
the magnitude of the number.
If D7 = 0, the operand is positive, and if D7 = 1, it is negative.
121 Positive numbers
Compare instruction
To perform the checksum operation, add all the bytes, including the check-
sum byte.
The result must be zero.
If it is not zero, one or more bytes of data have been changed (corrupted).
The 8051 Microcontroller
133
and Embedded Systems
CHAPTER 9
8051 TIMER PROGRAMMING IN ASSEMBLY
134 OBJECTIVES
Timer 0 registers
low byte register is called TL0 (Timer 0 low byte) and the high
byte register is referred to as TH0 (Timer 0 high byte)
can be accessed like any other register, such as A, B, R0, R1, R2,
etc.
"MOV TL0, #4 FH" moves the value 4FH into TL0
"MOV R5, TH0" saves TH0 (high byte of Timer 0) in R5
137 SECTION 9.1: PROGRAMMING 8051 TIMERS
Timer 1 registers
also 16 bits
split into two bytes TL1 (Timer 1 low byte) and TH1 (Timer 1 high byte)
accessible in the same way as the registers of Timer 0.
139 SECTION 9.1: PROGRAMMING 8051 TIMERS
Table 9–2 Equivalent Instructions for the Timer Control Register (TCON)
Mode 0 (13-bit timer mode)
Mode 0 is 13-bit timer mode for which 8-bit of THx and 5-bit of
TLx (as Prescaler) are used.
As shown in above figure, 8-bit of THx and lower 5-bit of TLx used to form a
total 13-bit timer. Higher 3-bits of TLx should be written as zero while using
timer mode0, or it will affect the result.
Example
1. Load TMOD register value i.e. TMOD = 0x00 for Timer0/1 mode0 (13-bit
timer mode).
2. Load calculated THx value i.e. here TH0 = 0xE3.
3. Load calculated TLx value i.e. here TL0 = 0x14.
4. Start timer by setting TRx bit. i.e. here TR0 = 1.
5. Poll TFx flag till it does not get set.
6. Stop timer by clearing TRx bit. i.e. here TR0 = 0.
7. Clear timer flag TFx bit i.e. here TF0 = 0.
8. Repeat from step 1 to 7 for delay again.
Mode 1 programming
149
T = 1/50 Hz = 20 ms
1/2 of it for the high and low portions of the pulse = 10 ms
10 ms / 1.085 us = 9216
65536 - 9216 = 56320 in decimal = DC00H
TL = 00 and TH = DCH
The calculation for 12MHz crystal uses the same steps
Example 9-12 (cont)
157
Assuming XTAL = 11.0592 MHz, write a program to generate a square
wave of 50 Hz frequency on pin P2.3.
158 SECTION 9.1: PROGRAMMING 8051 TIMERS
Mode 2 programming
8-bit timer, allows values of 00 to FFH
TH is loaded with the 8-bit value
a copy is given to TL
timer is started by ,"SETB TR0" or "SETB TR1“
starts to count up by incrementing the TL register
counts up until it reaches its limit of FFH
when it rolls over from FFH to 00, it sets high TF
TL is reloaded automatically with the value in TH
To repeat, clear TF
mode 2 is an auto-reload mode
162 SECTION 9.1: PROGRAMMING 8051 TIMERS
to LEDs
MAX232
converts from RS232 voltage levels to TTL voltage levels
uses a +5 V power source
MAX232 has two sets of line drivers for transferring and
receiving data
line drivers used for TxD are called T1 and T2
line drivers for RxD are designated as R1 and R2
T1 and R1 are used together for TxD and RxD of the 8051
second set is left unused
198 8051 CONNECTION TO RS232
MAX233
MAX233 performs the same job as the MAX232
eliminates the need for capacitors
much more expensive than the MAX232
200 8051 CONNECTION TO RS233
PC Baud Rates
203 8051 SERIAL PORT PROGRAMMING
11.0592 MHz
XTAL oscillator
207 8051 SERIAL PORT PROGRAMMING
Bit 7 – SMOD
1 = Baud rate is doubled in UART mode 1, 2 and 3.
0 = No effect on Baud rate.
Bit 3:2 – GF1 & GF0:
These are general purpose bit for user.
Bit 1 – PD: Power Down
1 = Enable Power Down mode. In this mode, Oscillator clock turned OFF
and both CPU and peripherals clock stopped. Hardware reset can cancel this
mode.
0 = Disable Power down mode.
Bit 0 – IDL: Idle
1 = Enable Idle mode. CPU clock turned off whereas internal peripheral
module such as timer, serial port, interrupts works normally. Interrupt and
H/W reset can cancel this mode.
0 = Disable Idle mode.
SCON Register
209
•D7-FE – Framing error bit. (If SMOD = 1, then bit 7 (SCON) = FE, and if SMOD = 0, then bit 7 (SCON)
= SM0. FE (Framing Error) is set if a zero is detected in the position of the stop bit while receiving a
character, and cleared by writing zero to the corresponding position of SCON)
•D7-SM0 – This bit is used for serial port mode selection.
•D6-SM1 – This bit is used for serial port mode selection.
•D5-SM2 – This bit is used for serial port mode selection, also known as multiprocessor
communication enable bit. When set, it enables multiprocessor communication in mode 2 and 3, and
eventually mode 1. It should be cleared in mode 0.
•D4-REN – Reception Enable bit enables serial reception when set. When cleared, serial reception is
disabled.
•D3-TB8 – Transmitter bit 8. Since all registers are 8-bit wide, this bit solves the problem of
transmitting the 9th bit in modes 2 and 3. It is set to transmit a logic 1 in the 9th bit.
•D2-RB8 – Receiver bit 8 or the 9th bit received in modes 2 and 3. Cleared by hardware if 9th bit
received is a logic 0. Set by hardware if 9th bit received is a logic 1.
•D1-TI – Transmit Interrupt flag is automatically set at the moment the last bit of one byte is sent.
It’s a signal to the processor that the line is available for a new byte to transmit. It must be cleared
from within the software.
•D0-RI – Receive Interrupt flag is automatically set upon one byte to receive. It signals that byte is
received and should be read quickly prior to being replaced by new data. This bit is also cleared from
within the software.
SCON Register
Mode 0
In mode 0, serial data are transmitted and received through the
RXD pin, while the TXD pin output clocks. The baud rate is fixed
at 1/12 the oscillator frequency. On transmit, the least significant
bit (LSB bit) is sent/received first.
Transmission and Reception process
Transmission – Data transmit is initiated by writing data to the SBUF
register. When all 8 bits have been sent, the TI bit of the SCON register is
automatically set.
Reception – Data received through the RXD pin are recognized when the
following two conditions are met: bit REN=1 and RI=0. When all 8 bits have
been received, the RI bit of the SCON register is automatically set indicating
that one-byte receive is complete. Since there is no START and STOP bits or
any other bit except data sent from the SBUF register in the pulse sequence,
this mode is mainly used when the distance between devices is short, noise
is minimized.
Mode 1
10 bits are transmitted through the TXD pin or received through
the RXD pin in the following manner: a START bit (always 0), 8 data
bits (LSB first) and a STOP bit (always 1). The START bit is only used
to initiate data receive, while the STOP bit is automatically written to
the RB8 bit of the SCON register.
Transmission and Reception process
Transmission – Data transmit is initiated by writing data to the SBUF
register. End of data transmission is indicated by setting the TI bit of the
SCON register.
Reception – The START bit (logic zero (0)) on the RXD pin initiates data
receive. The following two conditions must be met: bit REN=1 and bit RI=0.
Both of them are stored in the SBUF register. The RI bit is automatically set
upon data reception is complete. The Baud rate in this mode is determined
by the timer 1.
Mode 2
11 bits are transmitted through the TXD pin or received through the RXD
pin: a START bit (always 0), 8 data bits (LSB first), a programmable 9th
data bit and a STOP bit (always 1). On transmit, the 9th data bit is
actually the TB8 bit of the SCON register. This bit usually has a function of
parity bit. On receive, the 9th data bit goes into the RB8 bit of the same
register (SCON).The baud rate is either 1/32 or 1/64 the oscillator
𝟐𝑺𝑴𝑶𝑫(𝟎,𝟏)
frequency.: 𝒇𝒃𝒂𝒖𝒅𝟐 = 𝟔𝟒𝒅
× 𝑶𝒔𝒄𝒊𝒍𝒍𝒂𝒕𝒐𝒓 𝑭𝒓𝒆𝒒𝒖𝒆𝒏𝒄𝒚
Transmission and Reception process
Transmission – Data transmit is initiated by writing data to the SBUF register.
End of data transmission is indicated by setting the TI bit of the SCON register.
Reception – The START bit (logic zero (0)) on the RXD pin initiates data receive.
The following two conditions must be met: bit REN=1 and bit RI=0. Both of them
are stored in the SBUF register. The RI bit is automatically set upon data
reception is complete.
Mode 3
Mode 3 is the same as Mode 2 in all respects except the baud
rate.
The baud rate in Mode 3 is variable.
The parity bit is the P bit of the PSW register.
Before initiating data transmit, the byte to transmit is stored in
the accumulator and the P bit goes into the TB8 bit in order to
be “a part of the message”.
The procedure is opposite on receive, received byte is stored in
the accumulator and the P bit is compared with the RB8 bit.
If there are no variations the data received is correct.
215 8051 SERIAL PORT PROGRAMMING
TI (transmit interrupt)
when 8051 finishes the transfer of the 8-bit character, it raises the TI flag to
indicate that it is ready to transfer another byte
RI (receive interrupt)
when the 8051 receives data serially via RxD, it places the byte in the
SBUF register
then raises the RI flag bit to indicate that a byte has been received and
should be picked up before it is lost
8051 SERIAL PORT PROGRAMMING IN
218
ASSEMBLY
Solution:
ORG 0
MOV P2,#0FFH ;make P2 an input port
MOV TMOD,#20H ;timer 1, mode 2
MOV TH1,#0FAH ;4800 baud rate
MOV SCON,#50H ;8-bit, 1 stop, REN enabled
SETB TR1 ;start timer 1
MOV DPTR,#MYDATA ;load pointer for message
H_1: CLR A
MOVC A,@A+DPTR ;get the character
Contd….
Contd from prev slide….
JZ B_1 ;if last character get out
ACALL SEND ;otherwise call transfer
INC DPTR ;next one
SJMP H_1 ;stay in loop
B_1: MOV a,P2 ;read data on P2
ACALL SEND ;transfer it serially
ACALL RECV ;get the serial data
MOV P1,A ;display it on LEDs
SJMP B_1 ;stay in loop indefinitely
;----serial data transfer. ACC has the data-----
SEND: MOV SBUF,A ;load the data
H_2: JNB TI,H_2 ;stay here until last bit gone
CLR TI ;get ready for next char
RET ;return to caller
;----Receive data serially in ACC---------------
RECV: JNB RI,RECV ;wait here for char
MOV A,SBUF ;save it in ACC
CLR RI ;get ready for next char
RET ;return to caller
;-----The message---------------
MYDATA:DB ‘We Are Ready’,0
END
8051 SERIAL PORT PROGRAMMING
223
𝟐𝑺𝑴𝑶𝑫(𝟎,𝟏)
𝒇𝒃𝒂𝒖𝒅𝟐 = × 𝑶𝒔𝒄𝒊𝒍𝒍𝒂𝒕𝒐𝒓 𝑭𝒓𝒆𝒒𝒖𝒆𝒏𝒄𝒚
𝟔𝟒𝒅
228
8051 SERIAL PORT PROGRAMMING
229
230 OBJECTIVES
Contrast and compare interrupts versus polling
Explain the purpose of the ISR (interrupt service routine)
List the 6 interrupts of the 8051
Explain the purpose of the interrupt vector table
Enable or disable 8051 interrupts
Program the 8051 timers using interrupts
Describe the external hardware interrupts of the 8051
Contrast edge-triggered with level-triggered interrupts
Program the 8051 for interrupt-based serial communication
Define the interrupt priority of the 8051
231 8051 INTERRUPTS
Interrupts vs. polling
on receiving interrupt, the microcontroller
interrupts whatever it is doing and executes
interrupt service routine (ISR)
microcontroller can serve many devices
each device gets attention based on the priority
polling wastes time
232 8051 INTERRUPTS
Level-triggered interrupt
INT0 and INT1 pins are normally high
if low-level signal is applied, it triggers the interrupt
microcontroller stops whatever it is doing and jumps to
the interrupt vector table to service the interrupt
the low level signal must be removed before the
execution of the last instruction of the interrupt service
routine, RETI
otherwise, another interrupt will be generated
Example 11-5
Assume that the INT1 pin is connected to a switch that is normally
245 high. Whenever it goes low, it should turn on an LED. The LED is
connected to P1.3 and is normally off. When it is turned on it should
stay on for a fraction of a second. As long as the switch is pressed low,
the LED should stay on.
Solution:
ORG 0000H
LJMP MAIN ;by-pass interrupt vector table
;--ISR for INT1 to turn on LED
ORG 0013H ;INT1 ISR
SETB P1.3 ;turn on LED
MOV R3,#255
BACK: DJNZ R3,BACK ;keep LED on for a while
CLR P1.3 ;turn off the LED
RETI ;return from ISR
;--MAIN program for initialization
ORG 30H
MAIN: MOV IE,#10000100B ;enable external INT 1
HERE: SJMP HERE ;stay here until get interrupted
END
246 PROGRAMMING EXTERNAL HARDWARE
INTERRUPTS
(b) when INT0, INT1, and TF0 interrupts are activated at the same time, the
8051 services INT1 first, then it services INT0, then TF0
257 INTERRUPT PRIORITY IN THE 8051/52
Where,
name: is the name of the SFR bit.
sfr-name: is the name of a previously-defined SFR.
bit-position: is the position of the bit within the SFR.
sfr-address: is the address of an SFR.
sbit-address: is the address of the SFR bit.
Write an 8051 C program to send hex values for ASCII characters of 0, 1,
2, 3, 4, 5, A, B, C, and D to port P1.
Solution:
#include <reg51.h>
void main(void)
{
unsigned char mynum[]=“012345ABCD”;
unsigned char z;
for (z=0;z<=10;z++)
P1=mynum[z];
}
Write an 8051 C program to toggle all the bits of P1 continuously.
Solution:
//Toggle P1 forever
#include <reg51.h>
void main(void)
{
for (;;)
{
p1=0x55;
p1=0xAA;
}
}
Write an 8051 C program to send values of –4 to +4 to port P1.
Solution:
//Singed numbers
#include <reg51.h>
void main(void)
{
char mynum[]={+1,-1,+2,-2,+3,-3,+4,-4};
unsigned char z;
for (z=0;z<=8;z++)
P1=mynum[z];
}
Write an 8051 C program to toggle bits of P1 continuously forever with some delay.
Solution:
//Toggle P1 forever with some delay in between
//“on” and “off”
#include <reg51.h>
void main(void)
{
unsigned int x;
for (;;) //repeat forever
{
p1=0x55;
for (x=0;x<40000;x++); //delay size unknown
p1=0xAA;
for (x=0;x<40000;x++);
}
}
Write an 8051 C program to toggle bits of P1 ports continuously with a 250 ms.
Solution:
#include <reg51.h>
void MSDelay(unsigned int);
void main(void)
{
while (1) //repeat forever
{
p1=0x55;
MSDelay(250);
p1=0xAA;
MSDelay(250);
}
}
void MSDelay(unsigned int itime)
{
unsigned int i,j;
for (i=0;i<itime;i++)
for (j=0;j<1275;j++);
}
LEDs are connected to bits P1 and P2. Write an 8051 C program that shows
the count from 0 to FFH (0000 0000 to 1111 1111 in binary) on the LEDs.
Solution:
#include <reg51.h>
#defind LED P2;
void main(void)
{
P1=00; //clear P1
LED=0; //clear P2
for (;;) //repeat forever
{
P1++; //increment P1
LED++; //increment P2
}
}
Write an 8051 C program to get a byte of data form P0. If it is less than 100,
send it to P1; otherwise, send it to P2.
Solution:
#include <reg51.h>
void main(void)
{
unsigned char mybyte;
P0=0xFF; //make P0 input port
while (1)
{
mybyte=P0; //get a byte from P0
if (mybyte<100)
P1=mybyte; //send it to P1
else
P2=mybyte; //send it to P2
}
}
Write an 8051 C program to toggle only bit P2.4 continuously without
disturbing the rest of the bits of P2.
Solution:
//Toggling an individual bit
#include <reg51.h>
sbit mybit=P2^4;
void main(void)
{
while (1)
{
mybit=1; //turn on P2.4
mybit=0; //turn off P2.4
}
}
Write an 8051 C program to monitor bit P1.5. If it is high, send 55H to P0; otherwise, send
AAH to P2.
Solution:
#include <reg51.h>
sbit mybit=P1^5;
void main(void)
{
mybit=1; //make mybit an input
while (1)
{
if (mybit==1)
P0=0x55;
else
P2=0xAA;
}
}
Logical Operation
#include <reg51.h>
void main(void)
{
P0=0x35 & 0x0F; //ANDing
P1=0x04 | 0x68; //ORing
P2=0x54 ^ 0x78; //XORing
P0=~0x55; //inverting
P1=0x9A >> 3; //shifting right 3
P2=0x77 >> 4; //shifting right 4
P0=0x6 << 4; //shifting left 4
}
Write an 8051 C program to toggle all the bits of P0 and Write an 8051 C program to get bit P1.0 and send it to P2.7
P2 continuously with a 250 ms delay. Using the after inverting it.
inverting and Ex-OR operators, respectively. Solution:
Solution: #include <reg51.h>
#include <reg51.h> sbit inbit=P1^0;
void MSDelay(unsigned int); sbit outbit=P2^7;
void main(void) bit membit;
{ inbit=1;
P0=0x55; Void main(void)
P2=0x55; {
while (1) while (1)
{ {
P0=~P0; membit=inbit; //get a bit from P1.0
P2=P2^0xFF; outbit=~membit; //invert it and send
MSDelay(250); //it to P2.7
} }
} }
switch (z)
Write an 8051 C program to read the P1.0 and P1.1 {
bits and issue an ASCII character to P0 according to case(0):
the following table. {
P1.1 P1.0 P0=‘0’;
0 0 send ‘0’ to P0 break;
0 1 send ‘1’ to P0 }
1 0 send ‘2’ to P0 case(1):
1 1 send ‘3’ to P0 {
Solution: P0=‘1’;
#include <reg51.h> break;
void main(void) }
{ case(2):
unsigned char z; {
z=P1; P0=‘2’;
z=z&0x3; break;
}
case(3):
{
P0=‘3’;
break;
}
}
}
Write an 8051 C program to convert packed BCD
0x29 to ASCII and display the bytes on P1 and P2.
Solution:
#include <reg51.h>
void main(void)
{
unsigned char x,y,z;
unsigned char mybyte=0x29;
x=mybyte&0x0F;
P1=x|0x30;
y=mybyte&0xF0;
y=y>>4;
P2=y|0x30;
}
Write an 8051 C program to convert ASCII digits of ‘4’ and ‘7’ to
packed BCD and display them on P1.
Solution:
#include <reg51.h>
void main(void)
{
unsigned char bcdbyte;
unsigned char w=‘4’; Hex value in w=0x34
unsigned char z=‘7’; Hex value in w=0x37
w=w&0x0F; w=0x04
w=w<<4; w=0x40
z=z&0x0F; z=0x07
bcdbyte=w|z; bcdbyte=0x47
P1=bcdbyte;
}
Write an 8051 C program to get bit P1.0 and send it to P2.7 after
inverting it.
Solution:
#include <reg51.h>
sbit inbit=P1^0;
sbit outbit=P2^7;
bit membit;
void main(void)
{
while (1)
{
membit=inbit; //get a bit from P1.0
outbit=~membit; //invert it and send it to P2.7
}
}
Write an 8051 C program to turn bit P1.5 on and off 50,000
times.
Solution:
sbit MYBIT=0x95;
void main(void)
{
unsigned int z;
for (z=0;z<50000;z++)
{
MYBIT=1;
MYBIT=0;
}
}
Write an 8051 C program to get the status of bit P1.0, save it,
and send it to P2.7 continuously.
Solution:
#include <reg51.h>
sbit inbit=P1^0;
sbit outbit=P2^7;
bit membit; //use bit to declare
//bit- addressable memory
void main(void)
{
while (1)
{
membit=inbit; //get a bit from P1.0
outbit=membit; //send it to P2.7
}
}
Write an 8051 C program to toggle all the bits of P0 and P2 continuously
with a 250 ms delay. Using the inverting and Ex-OR operators, respectively.
Solution:
#include <reg51.h>
void MSDelay(unsigned int);
void main(void)
{
P0=0x55;
P2=0x55;
while (1)
{
P0=~P0;
P2=P2^0xFF;
MSDelay(250);
}
}
Write an 8051 C program to get bit P1.0 and send it to P2.7 after
inverting it.
Solution:
#include <reg51.h>
sbit inbit=P1^0;
sbit outbit=P2^7;
bit membit;
void main(void)
{
while (1)
{
membit=inbit; //get a bit from P1.0
outbit=~membit; //invert it and send it to P2.7
}
}
Write an 8051 C program to calculate the checksum byte for the data 25H,
62H, 3FH, and 52H. Copy the byte to port2 and cumilitive sum to port1. Finally
copy the checksum to port1.
Solution:
#include <reg51.h>
void main(void)
{
unsigned char mydata[]={0x25,0x62,0x3F,0x52};
unsigned char sum=0;
unsigned char x;
unsigned char chksumbyte;
for (x=0;x<4;x++)
{
P2=mydata[x];
sum=sum+mydata[x];
P1=sum;
}
chksumbyte=~sum+1;
P1=chksumbyte;
}
Write an 8051 C program to perform the checksum operation to ensure data
integrity. If data is good, send ASCII character ‘G’ to P0. Otherwise send ‘B’ to P0.
Solution:
#include <reg51.h>
void main(void)
{
unsigned char mydata[]={0x25,0x62,0x3F,0x52,0xE8};
unsigned char chksum=0;
unsigned char x;
for (x=0;x<5;x++)
chksum=chksum+mydata[x];
if (chksum==0)
P0=‘G’;
else
P0=‘B’;
}
Write an 8051 C program to convert 11111101 (FD hex) to
decimal and display the digits on P0, P1 and P2.
Solution:
#include <reg51.h>
void main(void)
{
unsigned char x,binbyte,d1,d2,d3;
binbyte=0xFD;
x=binbyte/10; x=253/10=25; reminder =3
d1=binbyte%10; d1=3 (reminder)
d2=x%10; d2=25%10=5
d3=x/10; d3=25/10 =2
P0=d1;
P1=d2;
P2=d3;
}
Write a C program to send out the value 44H serially one bit at a
time via P1.0. The LSB/ MSB should go out first.
Solution:
#include <reg51.h>
sbit P1b0=P1^0;
sbit regALSB=ACC^0; // sbit regALSB=ACC^7;
void main(void)
{
unsigned char conbyte=0x44;
unsigned char x;
ACC=conbyte;
for (x=0;x<8;x++)
{
P1b0=regALSB;
ACC=ACC>>1; // ACC=ACC<<1;
}
}
Write a C program to bring in a byte of data serially one bit at a
time via P1.0. The LSB should come in first.
Solution:
#include <reg51.h>
sbit P1b0=P1^0;
sbit ACCMSB=ACC^7;
bit membit;
void main(void)
{
unsigned char x;
for (x=0;x<8;x++)
{
membit=P1b0;
ACCMSB=membit;
ACC=ACC>>1;
}
P2=ACC;
}
Write an 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 T0Delay(void); {
void main(void) TMOD=0x01;
{ TL0=0x00;
while (1) TH0=0x35;
{
TR0=1;
P1=0x55;
T0Delay(); while (TF0==0);
P1=0xAA; TR0=0;
T0Delay(); TF0=0;
} }
}
A switch is connected to pin P1.7. Write an 8051 C program to monitor SW and create
the following frequencies on pin P1.5:SW=0: 500Hz; SW=1: 750Hz, use Timer 0, mode
1 for both of them.
void T0M1Delay(unsigned char c)
#include <reg51.h>
{
sbit mybit=P1^5;
TMOD=0x01;
sbit SW=P1^7;
if (c==0)
void T0M1Delay(unsigned char);
{
void main(void)
TL0=0x67;
{
TH0=0xFC;
SW=1;
}
while (1)
else
{
{
mybit=~mybit;
TL0=0x9A;
if (SW==0)
TH0=0xFD;
T0M1Delay(0);
}
else
TR0=1;
T0M1Delay(1);
while (TF0==0);
}
TR0=0;
}
TF0=0;
}
Write a C program for 8051 to transfer the letter “A”
serially at 4800 baud continuously. Use 8-bit data and 1
stop bit.
Solution:
#include <reg51.h>
void main(void)
{
TMOD=0x20; //use Timer 1, mode 2
TH1=0xFA; //4800 baud rate
SCON=0x50;
TR1=1;
while (1)
{
SBUF=‘A’; //place value in buffer
while (TI==0);
TI=0;
}
}
Write an 8051 C program to transfer the message “YES” serially at 9600 baud, 8-bit data, 1 stop bit. Do
this continuously.
Solution:
#include <reg51.h>
void SerTx(unsigned char);
void main(void)
{
TMOD=0x20; //use Timer 1, mode 2
TH1=0xFD; //9600 baud rate
SCON=0x50;
TR1=1; //start timer
while (1)
{
SerTx(‘Y’);
SerTx(‘E’);
SerTx(‘S’);
} void SerTx(unsigned char x)
} {
SBUF=x; //place value in buffer
while (TI==0); //wait until transmitted
TI=0;
}
Program the 8051 in C to receive bytes of data serially and put them in P1. Set
the baud rate at 4800, 8-bit data, and 1 stop bit.
Solution:
#include <reg51.h>
void main(void)
{
unsigned char mybyte;
TMOD=0x20; //use Timer 1, mode 2
TH1=0xFA; //4800 baud rate
SCON=0x50;
TR1=1; //start timer
while (1) //repeat forever
{
While (RI==0); //wait to receive
mybyte=SBUF; //save value
P1=mybyte; //write value to port
RI=0;
}
}
Write a C program using interrupts to do the following: (a) Receive data serially and send it to P0
(b) Read port P1, transmit data serially, and give a copy to P2 (c) Make timer 0 generate a square wave of 5
kHz frequency on P0.1. Assume that XTAL = 11.0592 MHz. Set the baud rate at 4800.
#include <reg51.h> void main()
sbit WAVE =P0^1; {
void timer0() interrupt 1 unsigned char x;
{ P1=0xFF; //make P1 an input
WAVE=~WAVE; //toggle pin TMOD=0x22;
} TH1=0xF6; //4800 baud rate
void serial0() interrupt 4 SCON=0x50;
{ TH0=0xA4; //5 kHz has T=200us
if (TI==1) IE=0x92; //enable interrupts
{ TR1=1; //start timer 1
TI=0; //clear interrupt TR0=1; //start timer 0
} while (1)
else {
{ x=P1; //read value from pins
P0=SBUF; //put value on pins SBUF=x; //put value in buffer
RI=0; //clear interrupt P2=x; //write value to pins
} }
} }
Write a C program that continuously gets a single bit of data from P1.7 and sends it to P1.0, while
simultaneously creating a square wave of 200 s period on pin P2.5. Use Timer 0 to create the square wave.
Assume that XTAL = 11.0592 MHz.
Solution:
We will use timer 0 mode 2 (auto-reload). One half of the period is 100 s. 100/1.085 s = 92, and TH0 = 256 -
92 = 164 or A4H
#include <reg51.h>
sbit SW =P1^7;
sbit IND =P1^0;
sbit WAVE =P2^5;
void timer0(void) interrupt 1
{
WAVE=~WAVE; //toggle pin
}
void main()
{
SW=1; //make switch input
TMOD=0x02;
TH0=0xA4; //TH0=-92
IE=0x82; //enable interrupt for timer 0
while (1) {
IND=SW; //send switch to LED
}
}
Write a C program using interrupts to do the following: (a) Receive data serially and send it to
P0; (b) Read port P1, transmit data serially, and give a copy to P2 (c) Make timer 0 generate a
square wave of 5 kHz frequency on P0.1 Assume that XTAL = 11.0592 MHz. Set the baud rate
at 4800.
void main() {
#include <reg51.h> unsigned char x;
sbit WAVE =P0^1; P1=0xFF; //make P1 an input
void timer0() interrupt 1 { TMOD=0x22;
WAVE=~WAVE; //toggle pin TH1=0xF6; //4800 baud rate
} SCON=0x50;
void serial0() interrupt 4 { TH0=0xA4; //5 kHz has T=200us
if (TI==1) { IE=0x92; //enable interrupts
TI=0; //clear interrupt TR1=1; //start timer 1
} TR0=1; //start timer 0
else { while (1) {
P0=SBUF; //put value on pins x=P1; //read value from pins
RI=0; //clear interrupt SBUF=x; //put value in buffer
} P2=x; //write value to pins
} }
}
Write a C program using interrupts to do the following: (a) Generate a 10 KHz frequency on P2.1 using T0 8-
bit auto-reload (b) Use timer 1 as an event counter to count up a 1-Hz pulse and display it on P0. The pulse is
connected to EX1. Assume that XTAL = 11.0592 MHz. Set the baud rate at 9600.
Solution:
#include <reg51.h> void main() {
sbit WAVE =P2^1; cnt=0; //set counter to 0
Unsigned char cnt; TMOD=0x42;
void timer0() interrupt 1 TH0=0x-46; //10 KHz
{ IE=0x86; //enable interrupts
WAVE=~WAVE; //toggle pin TR0=1; //start timer 0
} while (1);
void timer1() interrupt 3 //wait until interrupted
{ }
cnt++; //increment counter
P0=cnt; //display value on
pins
}