Edusatmaterial - 8051 Programming in C
Edusatmaterial - 8051 Programming in C
8051 Programming in C
Objectives:
At the end of this chapter we will be able to:
List and define the C data types for 8051
Comprehend and write 8051 C programs for
- Time Delay and I/O Operations
- I/O Bit Manipulation
- Logic and Arithmetic Operations
- ASCII & BCD Data Conversions
- Binary (hex) to Decimal Conversion
- To use the 8051 Code Space
- Data Serialization
Note: All the C programs can be simulated using keil software.
Compilers produce hex file that is downloaded to ROM of microcontroller. The size of hex
file generated by the compiler is the main concern, for two reasons:
Microcontrollers have limited on-chip ROM
Code space for 8051 is limited to 64K bytes
The language produces a hex file that is much smaller than C. But when both are compared,
programming in assembly is tedious and time consuming while C programming is less time
consuming, but has larger hex file size.
The reasons for writing programs in C instead of assembly are:
It is easier and less time consuming to write in C than Assembly
C is easier to modify and update
You can use code available in function libraries
C code is portable to other microcontroller with little or no modification
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.
The first line in an 8051 C program is #include <reg51.h>. The library file reg51.h contains
the definition of all the special function registers and their bits. Let us write and examine the
usage of the unsigned char data type through some examples.
.
Example 1: Write an 8051 C program to send values 00H -0AAH to port P1
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
for (z=0; z<=170;z++)
P1=z; // values 00H-0FFH sent to port 1
}
Note: On executing the program the values 00H to 0AAH will be displayed on port 1
[Type a quote
Example 2: from
Writethe
andocument or the summary
8051 C program to send of anvalues
hex interesting point. You
for ASCII can position
characters of 0,the text
1, 2, 3,
4, anywhere
box 5, A, B, C,in and D to port P1.
the document. Use the Text Box Tools tab to change the formatting of the pull quote
Solution:
text box.]
#include <reg51.h>
void main(void)
{
unsigned char mynum[]=“012345ABCD”;
unsigned char z;
for (z=0;z<=10;z++)
P1=mynum[z];
}
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.
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 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.
The 8 bit keyword is a widely used 8051 C data types which is used to access single-bit
addressable register. It allows access to the single bits of the SFR registers. As we know and
have studied, some of the SFRs are bit addressable. Among the SFRs that are widely used are
also bit addressable ports P0-P3.
Example 5: Write an 8051 C program to toggle bit D0 of the port P1 (P1.0) 50,000 times.
Solution:
#include <reg51.h>
sbit MYBIT=P1^0;
void main(void)
{
unsigned int z;
for (z=0;z<=50000;z++) sbit keyword allows access to the
Prof. Roopa Kulkarni,
{ GIT, Belgaum single bits of the SFR registers Page 3
MYBIT=0;
MYBIT=1;
}
8051 Programming in C Microcontroller
The bit data type allows access to single bits of bit-addressable memory spaces 20 – 2FH. To
access the byte-size SFR registers, we use the sfr data type. Table 1 summaries the different
data types used for 8051 programming in C.
Time Delays
There are two ways to create a time delay in 8051 C:
1. Using the 8051 timer
2. Using a simple for loop
In either case, the delays can be observed either on the oscilloscope or using a simulator. Here
only the discussion of time delay using simple for loop is carried out. In creating a time delay
using for loop three factors need to be considered that can affect the accuracy of the delay.
1.Example
Number 7:of
Write an 8051
machine C program
cycles and numberto toggle bits period
of clocks of P1 ports continuously
per machine cycle.with a
2.250ms.
Crystal frequency connected between XTAL1 and XTAL2. Duration of the clock
Solution:
period for the machine cycle is the function of crystal frequency.
3.#include
Compiler <reg51.h>
choice. The third factor that affects the accuracy of the time delay is the
void MSDelay(unsigned
compiler used to compile int);the C program. In assembly language programming, we can
void main(void)
Example
know 6: Write
and an 8051
control C program
the delay to toggle
generated, bitsnumber
as, the of P1 continuously forever
of instructions with
and the cycles
{some
per delay.
instruction is known to us. In case of C program, the C compiler will convert the
Solution:while (1) and functions to assembly
C statements //repeat forever
language instructions. Hence, different
//Toggle { P1 forever
compilers producewith some code.
different delay in between “on” and “off”
#include <reg51.h>P1=0x55;
void main(void) MSDelay(250);
{ P1=0xAA;
MSDelay(250);
unsigned int x;
}for (;;) //repeat forever
} {
void MSDelay(unsigned
P1=0x55; int itime)
{ for (x=0;x<40000;x++); //delay size unknown
Prof. Roopa Kulkarni,
unsigned
P1=0xAA;GIT,
intBelgaum
i,j; Page 4
forfor
(i=0;i<itime;i++)
(x=0;x<40000;x++);
for
} (j=0;j<1275;j++);
}
8051 Programming in C Microcontroller
Byte size I/O: Ports P0-P3 is used which are byte accessible. Below are few examples that
elaborate on this programming.
Example 8: 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>
Example 9: Write an 8051 C program to get a byte of data form P1, wait ½
second, and then send it to P2.
Solution:
#include <reg51.h>
void MSDelay(unsigned int);
void main(void)
{
unsigned char mybyte;
P1=0xFF; //make P1 input port
while (1)
{
mybyte=P1; //get a byte from P1
MSDelay(500);
P2=mybyte; //send it to P2
}
}
Example 10: 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
Example 11: 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 Ports P0 – P3 are bit addressable and
#include <reg51.h> we use sbit data type to access a single
sbit mybit=P2^4; bit of P0 - P3
void main(void)
{ Use the Px^y format, where x is
while (1) the port 0, 2, or 3 and y is the
{ bit 0 – 7 of that port
mybit=1; //turn on P2.4
mybit=0; //turn off P2.4
}
}
Example 12: 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)
Example 13: A door sensor is connected to the P1.1 pin, and a buzzer is connected
{
to P1.7. Write an 8051 C program to monitor the door sensor, and when it opens,
mybit=1;
sound the //make
buzzer. You can sound themybit
buzzeran by
input
sending a square wave of a few
while (1)
hundred Hz. (Note: MSDelay is the same as written for previous examples).
{
Algorithm if (mybit==1)
1. Make P0=0x55;
P1.1 as input.
elsethe status of P1.1: as long as it is high repeat step3 to 6 to generate a
2. Check
P2=0xAA;
square wave.
} 3. Send a low on P1.7.
} 4. Produce a small delay say of 200ms.
5. Send high on P1.7.
6. Produce the same delay as on time and
7. Repeat from step 2.
Solution:
#include <reg51.h>
void MSDelay(unsigned int);
sbit Dsensor=P1^1;
sbit Buzzer=P1^7;
void main(void)
{
Dsensor=1; //make P1.1 an input
while (1)
{
while (Dsensor == 1) //while it opens
{
Buzzer=0;
MSDelay(200);
Buzzer=1;
MSDelay(200);
} Belgaum
Prof. Roopa Kulkarni, GIT, Page 7
}
}
8051 Programming in C Microcontroller
Example 14: Write an 8051 C program to toggle all the bits of P0 and P2 continuously
with a 250 ms delay. Use the sfr keyword to declare the port addresses.
Solution:
Another way to access the SFR RAM
//Accessing Ports as SFRs using sfr data type
space 80 – FFH is to use the sfr data type
sfr P0=0x80;
sfr P1=0x90;
sfr P2=0xA0;
void MSDelay(unsigned int);
void main(void)
{
while (1)
{
P0=0x55;
P2=0x55;
MSDelay(250);
P0=0xAA;
P2=0xAA;
MSDelay(250);
}
}
Note: MSDelay function is the same as discussed in above examples.
Example 15:Write an 8051 C program to turn bit P1.5 on and off 50,000 times.
Solution:
sbit MYBIT=0x95;
We can access a single bit of any
SFR if we specify the bit address
void main(void)
{
unsigned int z;
for (z=0;z<50000;z++)
{
Example 16: Write an 8051 C program to get the status of bit P1.0, save it, and send it to
MYBIT=1;
P2.7 continuously.
MYBIT=0;
Solution:
}
#include <reg51.h>
}
sbit inbit=P1^0;
sbit outbit=P2^7;
Notice that
bit membit; there is no #include <reg51.h>. This
//use bit to declare
allows us to access any byte of the SFR RAM
//bit addressable memory
space 80 – FFH. This is widely used for the new
generation of 8051 microcontrollers.
void main(void)
{ We use bit data type to access data in a
while (1) bit-addressable section of the data RAM
space 20 – 2FH
{
Prof. Roopa Kulkarni, GIT, Belgaum
membit=inbit; //get a bit from P1.0 Page 9
outbit=membit; //send it to P2.7
}
}
8051 Programming in C Microcontroller
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 5
below.
Below are some examples that illustrate the usage of these logic operators.
Example 17: The following program will explain the different logical operations .We
can run on simulator and examine the results.
Solution:
#include <reg51.h>
void main(void)
{
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
}
Example 18: 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);
}
}
Example 19: 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
}
Example
} 20: Write an 8051 C program to read the P1.0 and P1.1 bits and issue an
ASCII character to P0 that is if P1.1 and P1.0 is 00 send ‘0’ if 01 send ‘1’, if 10 send
‘2’ and if 11 send ‘3’.
Algorithm
1. Make P1 as input port.
2. Read P1 value.
3. Mask all bits except D0 & D1 of P1 ad put the masked value in x.
4. If x=0; send ‘0’ to P0, else if x=1; send ‘1’ to P0, else if x=2; send ‘2’ to P0,
else send ‘3’ to P0. (use switch statement).
5. Repeat from step 2.
Solution:
#include <reg51.h>
void main(void)
{
unsigned char z;
z=P1; //read P1
z=z&0x3; //mask the unused bits
switch (z) //make decision
{
case(0):
{
P0=‘0’; break; //send ASCII 0
}
case(1):
{
P0=‘1’; break; //send ASCII 1
}
case(2):
{
P0=‘2’; break; //send ASCII 2
}
case(3):
{
Prof. Roopa Kulkarni, GIT, Belgaum
P0=‘3’; break; //send ASCII 3 Page 12
}
}}
8051 Programming in C Microcontroller
Algorithm
1.
1. Get
Get the
the packed
1st ASCII BCD number.
number and mask the higher nibble.
2. Convert it to unpacked BCD by masking
2. Shift the number to get the higher theBCD
nibble of lower and upper digit.
3. Add 30H individually and send the ASCII number to P1 and P2
3. Get the 2nd ASCII number and mask the higher nibble.
Solution:
4. Add the result to the first number.
5. Display
#include the BCD number on P1.
<reg51.h>
void main(void)
Solution:
{
#includeunsigned
<reg51.h> char x,y,z;
void main(void)
unsigned char mybyte=0x45;
{ x=mybyte&0x0F;
unsigned
P1=x|0x30; char bcdbyte;
unsigned char w=‘4’;
y=mybyte&0xF0;
unsigned
y=y>>4; char z=‘7’;
w=w&0x0F;
P2=y|0x30;
} w=w<<4;
Prof. Roopa Kulkarni, GIT, Belgaum
z=z&0x0F; Page 13
bcdbyte=w|z;
P1=bcdbyte;
}
8051 Programming in C Microcontroller
Example 23: Write an 8051 C program to convert 11111101(FDH) to decimal and display
the digits on P0, P1 and P2.
Algorithm:
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;
Prof. Roopa Kulkarni, GIT, Belgaum
P1=d2; Page 14
P2=d3;
}
8051 Programming in C Microcontroller
The calculation of the checksum byte, checking of data integrity can be shown through the
examples below:
Example 24: Assume there are 4 bytes of hex data: 25h, 62h, 3Fh and 52h.
(a) Find the checksum byte
(b) Perform checksum operation for data integrity
(c) If 2nd byte 62h is changed to 22h, show how checksum detects error.
Solution:
(a) Addition of data is: 25h+62h+3Fh+52h = 118H, discarding the carry and taking
Example2’s25: Write an 8051
complement C program
the result is E8H to calculate the checksum byte for the data given
in example
(b) Add24.all the data along with the checksum byte. For data integrity the result must
Solution:be zero that is 25h+62h+3Fh+52h +E8H = 200H, discard the carry 2, hence result
#includeis<reg51.h>
zero.
void(c)main(void)
Now if 62H is changed to 22H we get: 25h+22h+3Fh+52h +E8H = 1C0H, the
{ result is non-zero hence the data is erroneous.
unsigned char mydata[]={0x25,0x62,0x3F,0X52};
unsigned char sum=0;
Theunsigned char x; can be done through the examples below:
above calculation
unsigned char chksumbyte;
for(x=0;x<4;x++)
{
P2=mydata[x];
sum=sum+mydata[x];
P1=sum; //send sum to port 1
}
chksumbyte=~sum+1; // take 2's complement
Prof. Roopa Kulkarni, GIT, Belgaum Page 15
P1=chksumbyte;
}
8051 Programming in C Microcontroller
Example 26: Write an 8051 C program to perform step (b) of example 24. If data is error
free send ASCII ‘G’ else send ASCII ‘B’.
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';
}
Example 27: Compile and single-step the following program on your 8051simulator.
Examine the contents of the 128-byte RAM space to locate the ASCII values.
Solution:
#include <reg51.h>
void main(void)
{
unsigned char mynum[]=“ABCDEF”; //RAM space
unsigned char z;
for (z=0;z<=6;z++)
P1=mynum[z];
}
Example 28: Write, compile and single-step the following program on your 8051simulator.
Examine the contents of the code space to locate the values.
Solution:
#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;
Prof. Roopa Kulkarni,
P1=z; GIT, Belgaum Page 17
}
}
8051 Programming in C Microcontroller
Example 29: Compile and single-step the following program on your 8051simulator.
Examine the contents of the code space to locate the ASCII values.
Solution: To make the C compiler use
#include <reg51.h> the code space instead of the
void main(void) RAM space, we need to put
{ the keyword code in front of
code unsigned char mynum[]=“ABCDEF”; the variable declaration
unsigned char z;
for (z=0;z<=6;z++)
P1=mynum[z];
}
Data Serialization
Serializing data is a way of sending a byte of data one bit at a time through a single pin of
microcontroller
Using the serial port
Transfer data one bit a time and control the sequence of data and spaces in between
them
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.
Example 30: 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;
for (x=0;x<8;x++)
{
ACC = conbyte;
P1b0 = regALSB;
ACC = ACC>>1;
conbyte = ACC;
}
}
Prof. Roopa Kulkarni, GIT, Belgaum Page 18
8051 Programming in C Microcontroller
Example 31: 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;}
Summary
This chapter dealt with 8051 C programming, especially I/O programming and time delays in
8051 C. We also showed some logical operations such as AND, OR, XOR and complement.
In addition, some applications for these were discussed. This chapter also described data
conversions such as BCD, ASCII and binary (HEX). We also compared and contrasted the
use of code space and RAM data space in 8051 C. The widely used technique of data
serialization was also discussed.