8051 IN C
PROGRAMMING
NMJ32404 Embedded System Design
Objectives
• Upon completion of this chapter, you will be able to:
• Examine the C data type for the 8051.
• Code 8051 C programs for time delay and I/O operations.
• Code 8051 C programs for I/O bit manipulation.
• Code 8051 C programs for logic and arithmetic operations.
• Code 8051 C programs for ASCII and BCD data conversion.
• Code 8051 C programs for binary (hex) to decimal conversion.
• Code 8051 C programs to use the 8051 code space.
• Code 8051 C programs for data serialization
❑ Compilers produce hex files that is
WHY
WHY
PROGRAM
downloaded to ROM of microcontroller
PROGRAM ➢ The size of hex file is the main concern
8051 IN C
8051 IN C ▪ Microcontrollers have limited on-chip ROM
▪ Code space for 8051 is limited to 64K bytes
❑ C programming is less time consuming,
but has larger hex file size
❑ The reasons for writing programs in C
➢ 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 of no modification
DATA TYPES ❑ A good understanding of C data types
DATA TYPES
for 8051 can help programmers to
create smaller hex files
➢ Unsigned char
➢ Signed char
➢ Unsigned int
➢ Signed int
➢ Sbit (single bit)
➢ Bit and sfr
❑ The character data type is the most
DATA TYPES
TYPES
DATA natural choice
Unsigned char
char ➢ 8051 is an 8-bit microcontroller
Unsigned
❑ Unsigned char is an 8-bit data type in
the range of 0 – 255 (00 – FFH)
➢ One of the most widely used data types
for the 8051
▪ Counter value
▪ ASCII characters
❑ C compilers use the signed char as the
default if we do not put the keyword
unsigned
Write an 8051 C program to send values 00 – FF to port P1.
Solution: 1. Pay careful attention to
DATA TYPES #include <reg51.h> the size of the data
void main(void) 2. Try to use unsigned char
{ instead of int if possible
Unsigned char unsigned char z;
(cont’) for (z=0;z<=255;z++)
P1=z;
}
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];
}
DATA TYPES Write an 8051 C program to toggle all the bits of P1 continuously.
Solution:
Unsigned char //Toggle P1 forever
(cont’) #include <reg51.h>
void main(void)
{
for (;;)
{
P1=0x55;
P1=0xAA;
}
}
P1=0x55; //define by default
p1=0x55; //error if not define
❑ The signed char is an 8-bit data type
DATA TYPES ➢ Use the MSB D7 to represent – or +
➢ Give us values from –128 to +127
Signed char ❑ We should stick with the unsigned char
unless the data needs to be
represented as signed numbers
➢ temperature
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];
}
❑ The unsigned int is a 16-bit data type
DATA TYPES
➢ Takes a value in the range of 0 to 65535
Unsigned and (0000 – FFFFH)
Signed int ➢ 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
❑ Signed int is a 16-bit data type
➢ Use the MSB D15 to represent – or +
➢ We have 15 bits for the magnitude of the
number from –32768 to +32767
DATA TYPES Write an 8051 C program to toggle bit D0 of the port P1 (P1.0)
50,000 times.
Single Bit Solution:
sbit keyword allows access to the
(cont’) #include <reg51.h> single bits of the SFR registers
sbit MYBIT=P1^0;
void main(void)
{
unsigned int z;
for (z=0;z<=50000;z++)
{
MYBIT=0;
MYBIT=1;
}
}
❑ The bit data type allows access to
DATA TYPES
single bits of bit-addressable memory
Bit and sfr spaces 20 – 2FH
❑ To access the byte-size SFR registers,
we use the sfr data type
Data Type Size in Bits Data Range/Usage
unsigned char 8-bit 0 to 255
(signed) char 8-bit -128 to +127
unsigned int 16-bit 0 to 65535
(signed) int 16-bit -32768 to +32767
sbit 1-bit SFR bit-addressable only
bit 1-bit RAM bit-addressable only
sfr 8-bit RAM addresses 80 – FFH only
❑ There are two ways to create a time
TIME DELAY delay in 8051 C
➢ Using the 8051 timer (Chap. 9)
➢ Using a simple for loop
be mindful of three factors that can affect
the accuracy of the delay
▪ The 8051 design
– The number of machine cycle
– The number of clock periods per machine
cycle
▪ The crystal frequency connected to the X1 – X2
input pins
▪ Compiler choice
– C compiler converts the C statements and
functions to Assembly language instructions
– Different compilers produce different code
TIME DELAY Write an 8051 C program to toggle bits of P1 continuously forever
(cont’) with some delay.
Solution:
//Toggle P1 forever with some delay in between
//“on” and “off”
#include <reg51.h> We must use the oscilloscope to
void main(void) measure the exact duration
{
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.
TIME DELAY
(cont’) 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++);
}
I/O LEDs are connected to bits P1 and P2. Write an 8051 C program that
PROGRAMMING shows the count from 0 to FFH (0000 0000 to 1111 1111 in binary)
on the LEDs.
Byte Size I/O Solution:
#include <reg51.h> Ports P0 – P3 are byte-accessable
#defind LED P2; and we use the P0 – P3 labels as
defined in the 8051/52 header file.
void main(void)
{
P1=00; //clear P1
LED=0; //clear P2
for (;;) //repeat forever
{
P1++; //increment P1
LED++; //increment P2
}
}
I/O Write an 8051 C program to get a byte of data form P1, wait 1/2
PROGRAMMING second, and then send it to P2.
Solution:
Byte Size I/O #include <reg51.h>
void MSDelay(unsigned int);
(cont’)
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
}
}
I/O Write an 8051 C program to get a byte of data form P0. If it is less
PROGRAMMING than 100, send it to P1; otherwise, send it to P2.
Solution:
Byte Size I/O #include <reg51.h>
(cont’)
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
}
}
I/O Write an 8051 C program to toggle only bit P2.4 continuously without
PROGRAMMING disturbing the rest of the bits of P2.
Ports P0 – P3 are bit-
Solution:
addressable and we use
Bit-addressable //Toggling an individual bit sbit data type to access
#include <reg51.h>
I/O sbit mybit=P2^4;
a single bit of P0 - P3
void main(void) Use the Px^y format, where
{ x is the port 0, 1, 2, or 3 and
while (1) y is the bit 0 – 7 of that port
{
mybit=1; //turn on P2.4
mybit=0; //turn off P2.4
}
}
I/O Write an 8051 C program to monitor bit P1.5. If it is high, send 55H
PROGRAMMING to P0; otherwise, send AAH to P2.
Solution:
Bit-addressable #include <reg51.h>
sbit mybit=P1^5;
I/O
(cont’) void main(void)
{
mybit=1; //make mybit an input
while (1)
{
if (mybit==1)
P0=0x55;
else
P2=0xAA;
}
}
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, sound the buzzer. You can sound the buzzer by
I/O sending a square wave of a few hundred Hz.
PROGRAMMING Solution:
#include <reg51.h>
Bit-addressable void MSDelay(unsigned int);
sbit Dsensor=P1^1;
I/O sbit Buzzer=P1^7;
(cont’) 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);
}
}
}
The data pins of an LCD are connected to P1. The information is
latched into the LCD whenever its Enable pin goes from high to low.
Write an 8051 C program to send “The Earth is but One Country” to
I/O this LCD.
PROGRAMMING
Solution:
#include <reg51.h>
Bit-addressable #define LCDData P1 //LCDData declaration
I/O sbit En=P2^0; //the enable pin
(cont’) void main(void)
{
unsigned char message[]
=“The Earth is but One Country”;
unsigned char z;
for (z=0;z<28;z++) //send 28 characters
{
LCDData=message[z];
En=1; //a high-
En=0; //-to-low pulse to latch data
}
}
Write an 8051 C program to toggle all the bits of P0, P1, and P2
continuously with a 250 ms delay. Use the sfr keyword to declare the
port addresses. Another way to access the SFR RAM
I/O Solution: space 80 – FFH is to use the sfr data type
PROGRAMMING //Accessing Ports as SFRs using sfr data type
sfr P0=0x80; sfr P0=0x80;
sfr P1=0x90; sfr P1=0x90;
sfr P2=0xA0;
Accessing SFR void MSDelay(unsigned int);
sfr P2=0xA0;
Addresses 80 void main(void) These already
- FFH { define in header
while (1)
{ file, so no need
P0=0x55; to do again. That
P1=0x55; mean you can
P2=0x55; directly use P0,
MSDelay(250);
P0=0xAA; P1, P2, P3.
P1=0xAA;
P2=0xAA;
MSDelay(250);
}
}
I/O Write an 8051 C program to turn bit P1.5 on and off 50,000 times.
PROGRAMMING Solution: We can access a single bit of any
sbit MYBIT=0x95; SFR if we specify the bit address
Accessing SFR
void main(void)
Addresses {
80 - FFH unsigned int z;
for (z=0;z<50000;z++)
{
MYBIT=1;
MYBIT=0;
}
}
Notice that there is no #include <reg51.h>.
This allows us to access any byte of the SFR RAM
space 80 – FFH. This is widely used for the new
generation of 8051 microcontrollers.
I/O Write an 8051 C program to get the status of bit P1.0, save it, and
PROGRAMMING send it to P2.7 continuously.
Solution:
Using bit Data #include <reg51.h>
Type for sbit inbit=P1^0;
sbit outbit=P2^7;
Bit-addressable bit membit; //use bit to declare
RAM //bit- addressable memory
void main(void) We use bit data type to access
{ data in a bit-addressable section
while (1) of the data RAM space 20 – 2FH
{
membit=inbit; //get a bit from P1.0
outbit=membit; //send it to P2.7
}
}
❑ Logical operators
LOGIC
OPERATIONS ➢ AND (&&), OR (||), and NOT (!)
❑ Bit-wise operators
Bit-wise ➢ AND (&), OR (|), EX-OR (^), Inverter (~),
Operators in C Shift Right (>>), and Shift Left (<<)
▪ These operators are widely used in software
engineering for embedded systems and control
Bit-wise Logic Operators for C
AND OR EX-OR Inverter
A B A&B A|B A^B ~B
0 0 0 0 0 1
0 1 0 1 1 0
1 0 0 1 1
1 1 1 1 0
LOGIC Run the following program on your simulator and examine the results.
OPERATIONS Solution:
#include <reg51.h>
Shifting is not
Bit-wise Rotate !
void main(void)
Operators in C {
(cont’) 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
}