Unit 3 - 8051 Programming in C
Unit 3 - 8051 Programming in C
UNIT -3
8051 PROGRAMMING IN C
3.1 Introduction
Pin 1 to Pin 8 (Port – 1) – Pin 1 to Pin 8 is assigned to Port 1 for simple I/O
operations. These ports are work as a bidirectional port. It means all the pins
of port 1 work as a input pin or output pins. If Logic 1 (one) is applied to the
I/O port it will act as a input pin and if logic 0 (zero) is applied to the I/O
port it will act as a output pin.
Pin 9 (RST) – It is a reset input Pin, which is used to reset the 8051
microcontrollers to its initial values when logic 1 is applied to this pin. It is
active high pin.
Pin 10 to Pin 17 (Port-3) – Pin 10 to Pin 17 are assigned to Port 3. This port
is also a bidirectional I/O port like port 1. This port performs some special
functions like interrupts, control signals, timer input, serial communication
etc.
Dr.T.Senthilkumar, AP/EEE EE3071-EMBEDDED C PROGRAMMING
P 10 (RXD) – Pin 10 is used as a RXD (serial data receive pin) which is for
serial input pin. By using this input signal microcontroller receives data for
serial communication.
P 11 (TXD) – Pin 11 is used as a TXD (serial data transmit pin) which is
serial output pin. By using this output signal microcontroller transmits data
for serial communication.
P 12 and P 13 (INT0′, INT1′ ) – Pins12 and 13 are used for External
Hardware Interrupt 0 and Interrupt 1 respectively. When this interrupt is
activated (i.e. when it is low), 8051 gets interrupted means it stopped
whatever it is doing and jumps to the vector table where ISR’s (Interrupt
Service Routine) are stored and starts performing Interrupt Service Routine
(ISR) from that vector location.
P 14 and P 15 (T0 and T1) – Pin 14 and 15 are used for Timer 0 and Timer
1 external input. They can be connected with 16-bit timer/counter.
P 16 (WR’) – Pin 16 is used for external memory write i.e. writing data to
the external memory.
P 17 (RD’) – Pin 17 is used for external memory read i.e. reading data from
external memory.
Pin 18 and Pin 19 (XTAL2 and XTAL1) –Pins 18 and 19 i.e. XTAL 2 and
XTAL 1 are the pins for interfacing external oscillator. Mostly, a Quartz
Crystal Oscillator is connected here to get the system clock.
Pin 20 (GND) – Pin 20 is the Ground Pin. It is connected to the 0V
(negative terminal) of the Power Supply.
Pin 21 to Pin28 (Port 2) – Pin 21 to pin 28 are port 2 pins. Port 2 is also a
bidirectional Input /Output port i.e, all pins of port 2 work as a input pin or
as a output pins. But, this is only possible when we are not using any
external memory. If we use external memory, then these pins will work as
high order address bus (A8 to A15).
Pin 29 (PSEN) – The Pin 29 is the Program Store Enable Pin (PSEN). It is
used to enable external program memory and read a signal from the external
program memory.
Pin 30 (ALE) – Pin 30 is the Address Latch Enable Pin. This pin is used to
enable or disable the external memory interfacing.
Pin 31 (EA) – Pin 31 is the External Access Enable (EA) Pin. This pin
allows external Program Memory. It is an input pin and connected from
Dr.T.Senthilkumar, AP/EEE EE3071-EMBEDDED C PROGRAMMING
In this section we will first discuss the different data types used in C for
8051 programming and the provide codes for time delay function.
3.1.1 C data types for 8051:
Dr.T.Senthilkumar, AP/EEE EE3071-EMBEDDED C PROGRAMMING
unsigned char:
As 8051 is an 8-bit microcontroller, the character data type is the most natural
choice for many applications. The unsigned char is an 8-bit data type takes a value
in the range of 0 – 255 (00H – FFH) and the most widely used data type for 8051.
The unsigned char data type can be used in situations such as setting a counter
value and ASCII characters, instead of signed char. It is important to specify the
keyword unsigned infront of the char else compiler will use the signed char as the
default. As 8051 has a limited number of registers and data RAM locations, using
the int in place of char can lead to a larger size hex file. This is not a significant
issue in high level language.
Program:
#include <reg51.h> // contains all the port registers and internal
// RAM of 8051declared
void main (void)
{
unsigned char z; // z is allotted a space of 1 byte
Dr.T.Senthilkumar, AP/EEE EE3071-EMBEDDED C PROGRAMMING
Note:
On executing the program the values 00H to 0AAH will be displayed on port 1
signed char:
The signed char is an 8-bit data type that uses the MSB D7 to represent – or
+value. This implies there are only seven bits for the magnitude of a signed
number, giving us values from –128 to +127. We should stick with the unsigned
char unless the data needs to be represented as signed numbers. Example
temperature.
Solution:
#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];
}
Note: The negative values will be displayed in the 2’s complement for as 1, FFH,
2, FEH, 3, FDH, 4, FCH.
unsigned int:
The unsigned int is a 16-bit data type that takes a value in the range of 0 to 65535
(0000 – FFFFH). This is used to define 16-bit variables such as memory addresses,
set counter values of more than 256. Since registers and memory accesses are in 8-
bit chunks, the misuse of int variables will result in a larger hex file. However, for
8051 programming, do not use unsigned int in place where unsigned char will do
Dr.T.Senthilkumar, AP/EEE EE3071-EMBEDDED C PROGRAMMING
the job. Also in situations where there is no need for signed data we should use
unsigned int instead of signed int. Remember, C compiler uses signed int as default
if unsigned keyword is not used.
signed int:
Signed int is a 16-bit data type that uses the MSB D15 to represent – or +value. We
have 15 bits for the magnitude of the number from –32768 to +32767.
out. In creating a time delay using for loop three factors need to be considered that
can affect the accuracy of the delay.
1. Number of machine cycles and number of clocks period per machine cycle.
2. Crystal frequency connected between XTAL1 and XTAL2. Duration of the
clock period for the machine cycle is the function of crystal frequency.
3. Compiler choice. The third factor that affects the accuracy of the time delay
is the compiler used to compile the C program. In assembly language
programming, we can know and control the delay generated, as, the number
of instructions and the cycle per instruction is known to us. In case of C
program, the C compiler will convert the C statements and functions to
assembly language instructions. Hence, different compilers produce different
code.
Solution:
#include <reg51.h>
void MSDelay(unsigned int);
void main(void)
{
while(1)
{ //repeat forever
P1=0x55;
MSDelay(250); //time delay
P1=0xAA;
MSDelay(250)
}
}
Output pin
As shown in figure 3.3, logic zero (0) is applied to a bit of the P register. The
output FE transistor is turned on, thus connecting the appropriate pin to ground.
Input pin
As shown in figure 3.4, a logic one (1) is applied to a bit of the P register. The
output FE transistor is turned off and the appropriate pin remains connected to the
power supply voltage over a pull-up resistor of high resistance.
Input data (0 or 1)
As shown in figure 3.5, logic state (voltage) of any pin can be
changed or read at any moment. A logic zero (0) and logic one (1) are not equal. A
logic one (0) represents a short circuit to ground. Such a pin acts as an output. A
logic one (1) is “loosely” connected to the power supply voltage over a resistor of
high resistance. Since this voltage can be easily “reduced” by an external signal,
such a pin acts as an input.
Port 0
The P0 port is characterized by two functions. If external memory is used then the
lower address byte (addresses A0-A7) is applied on it. Otherwise, all bits of this
port are configured as inputs/outputs. The other function is expressed when it is
configured as an output. Unlike other ports consisting of pins with built-in pull-up
resistor connected by its end to 5 V power supply, pins of this port have this
resistor left out. This apparently small difference has its consequences: Input
Configuration If any pin of this port is configured as an input then it acts as if it
“floats”. Such an input has unlimited input resistance and in determined potential.
Solution:
//Accessing Ports as SFRs using sfr data type
sfr P0=0x80;
sfr P1=0x90;
sfr P2=0xA0;
void MSDelay(unsigned int);
Dr.T.Senthilkumar, AP/EEE EE3071-EMBEDDED C PROGRAMMING
void main(void)
{
while (1)
{
P0=0x55;
P2=0x55;
MSDelay(250);
P0=0xAA;
P2=0xAA;
MSDelay(250);
}
}
One of the most important and powerful features of the C language is its
ability to perform bit manipulation. This section describes the action of bitwise
logic operators and provides some examples of how they are used.
The bitwise operators used in C are AND (&), OR ( | ), EX-OR ( ^ ), inverter (~),
Shift right (>>) and Shift left (<<). These are widely used in software engineering
for embedded systems and control; consequently, understanding and mastery of
them are critical in microprocessor and microcontroller-based system design and
interfacing. The operations are shown in table below.
Solution:
#include <reg51.h>
void main(void)
Dr.T.Senthilkumar, AP/EEE EE3071-EMBEDDED C PROGRAMMING
{
P0=0x35 & 0x0F; //ANDing
P1=0x04 | 0x68; //ORing
P2=0x54 ^ 0x78; //XORing
P0=~0x55; //inversing
P1=0x9A >> 3; //shifting right 3
P2=0x77 >> 4; //shifting right 4
P0=0x6 << 4; //shifting left 4
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;
}
Solution:
#include <reg51.h>
void main(void)
{
unsigned char x,binbyte,d1,d2,d3;
binbyte=0xFD;
x=binbyte/10;
d1=binbyte%10;
d2=x%10;
d3=x/10;
P0=d1;
P1=d2;
P2=d3;
}
Dr.T.Senthilkumar, AP/EEE EE3071-EMBEDDED C PROGRAMMING
Using the code (program) space for predefined data is a widely used option
in 8051. We saw how to use the Assembly language instruction MOVC to access
the data stored in the 8051 code space. Here, we see the same concept with 8051 C.
In 8051, we have three spaces to store data:
1. Bank 0 – addresses 0 – 7
2. Individual variables – addresses 08 and beyond
3. Array elements – addresses right after variables
Array elements need contiguous RAM locations and that limits the size of
the array due to the fact that we have only 128 bytes of RAM for everything.
4. Stack – addresses right after array elements.
#include <reg51.h>
void main(void)
{
unsigned char mydata[100]; //RAM space
unsigned char x,z=0;
for (x=0;x<100;x++)
{
z--;
mydata[x]=z;
P1=z;
}
}
While running this program you can see how the data will be stored in an array and
displayed in a port.
One of the new features of the 8052 was an extra 128 bytes of RAM space.
The extra 128 bytes of RAM helps the 8051/52 C compiler to manage its
registers and resources much more effectively.
Dr.T.Senthilkumar, AP/EEE EE3071-EMBEDDED C PROGRAMMING
Based on 8052 architecture, you should use the reg52.h header file. Choose
the 8052 option when compiling the program.
To make C compiler use the code space (on-chip ROM) instead of RAM
space, we can put the keyword “code” in front of the variable declaration.
This is discussed in the following examples. Let us compare and contrast the
following programs and discuss the advantages and disadvantages of each one.
Example: 9
#include <reg51.h>
void main(void)
{
P1=“H”;
P1=“E”;
P1=“L”;
P1=“L”;
P1=“O”;
}
Example: 10
#include <reg51.h>
void main(void)
{
unsigned char mydata[]=“HELLO”;
unsigned char z;
for (z=0; z<5; z++)
P1 = mydata[z];
}
Example: 11
#include <reg51.h>
void main(void)
{
Code unsigned char mydata[]=“HELLO”;
unsigned char z;
for (z=0; z<5; z++)
P1 = mydata[z];
}
Serializing data is a way of sending a byte of data one bit at a time through a
single pin of microcontroller.
In many new generations of devices such as LCD, ADC, and ROM, the serial
versions are becoming popular since they take less space on a PCB.
The following are examples that demonstrate data serialization using embedded C.
Example 12: Write a C program to send out the value 44H serially one bit at a
time via P1.0. The LSB should go out first.
Solution:
#include <reg51.h>
sbit P1b0=P1^0;
sbit regALSB=ACC^0;
void main(void)
{
unsigned char conbyte=0x44;
unsigned char x;
ACC=conbyte;
for (x=0;x<8;x++)
{
P1b0=regALSB;
ACC=ACC>>1;
}
}
Dr.T.Senthilkumar, AP/EEE EE3071-EMBEDDED C PROGRAMMING
Example 12: Write a C program to bring in a byte of data serially one bit at a
time via P1.0. The MSB should come in first.
Solution:
#include <reg51.h>
sbit P1b0=P1^0;
sbit regALSB=ACC^0;
bit membit;
void main(void)
{
unsigned char x;
for (x=0;x<8;x++)
{
membit=P1b0;
ACC=ACC<<1;
regALSB=membit;
}
P2=ACC;
}