04 8051 Programming in C - 2018

Download as ppsx, pdf, or txt
Download as ppsx, pdf, or txt
You are on page 1of 36

8051

Programming in
C
Introduction
• The C-compiler uses internal data RAM area to store
variables declared in program.
• The most general allocation of data RAM is as below
– Register Bank 0 – Addresses 00 to 07.
– Individual Variables – Address 08 and beyond.
– Array elements – Addresses right after the variables.
– Stack – Addresses right after the variables.
• The above allocation may change depending on the compiler.
• Advantage of using C is easy development, easy debugging of
application software and portability with little or no
modification.
• The hex code generated by the C-compilers are usually much
larger than the code obtained through assembly language
program.
8051 Programming in C – Manish Tiwari 2
Data Types
• Since limited amount of data RAM (128B) and Code space
(4KB) is available, efficient use of data types for variables
are essential.
• Following are the most common & preferred data types
– unsigned char – An 8-bit variable declaration in data RAM. Same
as using an 8-bit register or 8-bit memory location in 8051.
– bit – A single bit variable declaration in data RAM within the bit
addressable area (address 20H to 2FH).
– sbit – A single bit of bit addressable SFR may be defined.
– Use of int/long int etc are seldom observed. Even though they
may be used any time in program, but takes larger RAM area and
processing time. Hence these variables are used only and only
when our program must deal with the larger data length.

8051 Programming in C – Manish Tiwari 3


Program P1

Write a C Program to send values 00 to


FFH to Port P1.

8051 Programming in C – Manish Tiwari 4


P1: Sending Values to Port
# include <reg51.h>
void main (void)
{
unsigned char num;
for(num=0;num<=255;num++) P1=num;
}

* reg51.h is the header file where definition of all the 8051


registers are present. So, compiler understands that ACC
means Accumulator, P1 means Port P1 etc.
* variable “num” is assigned either to a register or to 8-bit
memory location in RAM, depending on the choice of
compiler.
8051 Programming in C – Manish Tiwari 5
P2: Sending Values to Port with delay
# include <reg51.h>
void unknown_delay (unsigned int count)
{
unsigned i, j; // Integer variables are used. WHY?
for(i=0;i<count;i++)
for(j=0;j<count;j++);
return;
}
void main (void)
{
unsigned char num;
for(num=0;num<=255;num++)
{
P1=num;
unknown_delay (500);
}
}
8051 Programming in C – Manish Tiwari 6
The Delay Routine
• Creating a time delay using for loop has certain issues
regarding accuracy, that we must consider.
– Consideration of crystal frequency. Various controllers runs with
different crystal frequency. So delay routine may need to be
changed if crystal frequency is changed.
– Consideration of cycle frequency. Different versions of controllers
have different cycle frequencies. Original 8051 is designed with
12 Pulses/cycle while DS5000 uses 4 pulses/cycle and DS89C420
uses only one pulse/cycle.
– Compiler choice. Different compilers produce different hex codes for
the same delay program which affects the net time delay offered by
the delay function.
• Generally, on-chip timers are the best solution if time
accuracy is required.

8051 Programming in C – Manish Tiwari 7


Program P3

Write a C Program to send ASCII codes


of hexadecimal integers (0 to 9 and A
to F) continuously to Port P1 with
delay.

8051 Programming in C – Manish Tiwari 8


P3: Sending ASCII continuously
# include <reg51.h>
void unknown_delay (unsigned int count)
{
unsigned i, j;
for(i=0;i<count;i++)
for(j=0;j<count;j++);
return;
}
void main (void)
{
unsigned char i, code_table[ ] = “0123456789ABCDEF”; // Store ASCII codes in array
while(1) // Send ASCII codes continuously
{
for(i=0;i<=15;i++) // better looping is i<16, WHY?
{
P1=code_table[i];
unknown_delay (500);
}
}
}

8051 Programming in C – Manish Tiwari 9


Program P4: Using “bit” data type

Write a C Program that continuously


reads the Port 1 and send it to Port 2, if
a bit named “direction” is 1. Send the
data of Port 1 to Port 3 if bit “direction”
is 0. Given that “direction” is bit that is
defined in bit addressable RAM area
and is modified by some other routines.

8051 Programming in C – Manish Tiwari 10


P4: Using “bit” data type
# include <reg51.h>
bit direction; // define the required bit.
void main (void)
{
unsigned char mybyte;
P1=0xFF; // P1 is input port.
for( ; ; ) // Repeat forever
{
mybyte=P1; // Read P1.
if(direction==1) P2=mybyte;
else P3=mybyte;
}
}

8051 Programming in C – Manish Tiwari 11


Alternate P4: Using “bit” data type
# include <reg51.h>
bit direction; // define the required bit.
void main (void)
{
P1=0xFF; // P1 is input port.
for( ; ; ) // Repeat forever
{
if(direction==1) P2=P1;
else P3=P1;
}
}
# Recall the uses of direct addressing mode.
# Such kind of practices i.e. using ports directly, should be done
with extreme care.

8051 Programming in C – Manish Tiwari 12


Program P5

Interface 8 serial switches and 8 LEDs


to 8051 and write a program that
displays the status of the switches
continuously on the LEDs.

8051 Programming in C – Manish Tiwari 13


Figure P5: Interfacing Diagram

8051 Programming in C – Manish Tiwari 14


P5: Switches & LEDs
# include <reg51.h>
void main (void)
{
unsigned char mybyte;
P1=0xFF; // P1 is input port.
for( ; ; ) // Repeat forever
{
mybyte=P1; // Read Switches.
P2=mybyte; // Display on LEDs.
}
}

8051 Programming in C – Manish Tiwari 15


Alternate P5 (1): Switches & LEDs
# include <reg51.h>
# define SWITCH P1 // P1 is assigned a meaningful symbolic name.
# define LED P2 // P2 is assigned a symbolic name.
void main (void)
{
unsigned char mybyte;
SWITCH=0xFF; // SWITCH port is input.
for( ; ; ) // Repeat forever
{
mybyte=SWITCH; // Read Switches.
LED=mybyte; // Display on LEDs.
}
}

8051 Programming in C – Manish Tiwari 16


Alternate P5 (2): Switches & LEDs
# include <reg51.h>
# define SWITCH P1 // P1 is assigned a meaningful symbolic
name.
# define LED P2 // P2 is assigned a symbolic name.
void main (void)
{
SWITCH=0xFF; // SWITCH port is input.
for( ; ; ) // Repeat forever
LED=SWITCH; // Display switch status on LED.
}
* Exercise extreme care while using Ports in this way. Most
preferred Program is “Alternate P5 (1)”.

8051 Programming in C – Manish Tiwari 17


Program P6

Consider Figure P5 at Slide 13.


Write a program that displays the
numbers 00 to FFH continuously
through LEDs.

8051 Programming in C – Manish Tiwari 18


P6: LED Display
# include <reg51.h>
# define LED P2 // P2 is assigned a meaningful symbolic name.

void main (void)


{
unsigned char num;
while(1) // Do it continuously.
{
for(num=0;num<=255;num++ )
LED=num; // Display on LED.
}
} // Why not using num<256?

8051 Programming in C – Manish Tiwari 19


Alternate P6 (1): LED Display
# include <reg51.h>
# define LED P2 // P2 is assigned a meaningful symbolic
name.

void main (void)


{
LED=0; // Display 00 on LEDs.
while(1) LED++; // Display numbers continuously.
}
* Again, exercise extreme care while using Ports in this way.
Most preferred Program is “P6”.

8051 Programming in C – Manish Tiwari 20


Program P7 : Using “sbit” data type

Consider Figure P5 at Slide 13.


Write a program that displays the
numbers 00 to FFH continuously
through LEDs if switch S0 is pressed.

8051 Programming in C – Manish Tiwari 21


P7: Using “sbit” data type
# include <reg51.h>
# define LED P2 // P2 is assigned a symbolic name.
sbit S0 = P1^0; // define sfr bit P1.0 as S0.
void main (void)
{
unsigned char num;
S0=1; // Define switch S0 as input.
while(1) // Do it continuously.
{
if(S0==0) // Check S0 is pressed or not?
for(num=0;num<=255;num++ ) // YES,
LED=num; // Display on LED.
}
}

8051 Programming in C – Manish Tiwari 22


Program P8 : Using “sfr” directive

Consider Figure P5 at Slide 13.


Write a program that continuously
toggles the LEDs if switch S0 is
pressed.

8051 Programming in C – Manish Tiwari 23


P8: Using “sfr” directive
sfr P2=0xA0 // declare Port 2 using sfr directive.
sbit S0 = 0x90; // declare the bit P1.0 as S0.
void main (void)
{
S0=1; // Define switch S0 as input.
while(1) // Do it continuously.
{
if(S0==0) // Check S0 is pressed or not?
P2=~P2; // YES, Toggle the LEDs.
}
}
• Observe, that there is no #include<reg51.h>. This method is
widely used for new versions of microcontrollers.

8051 Programming in C – Manish Tiwari 24


Data Conversions
Many microcontrollers uses real time clocks (RTC) to keep
time & date even when power is off. Most often, RTCs
provide information in “packed BCD” which must be
converted to ASCII for displays.

Packed BCD Unpacked BCDs


0 1 0 1 0 1 0 1 U U U U 0 1 0 1
6 5 UUUU 6
U U U U 0 1 0 1
UUUU 5

Equivalent ASCII
0 0 1 1 0 1 0 1
3 6
0 0 1 1 0 1 0 1
3 5

8051 Programming in C – Manish Tiwari 25


P9: Packed to Unpacked
# include <reg51.h>
void main (void)
{
unsigned char packed=0x65; // Packed BCD.
unsigned char unpack1, unpack2;

unpack1=packed & 0xF0; // Mask lower nibble i.e. unpack1=60.


unpack1=unpack1 >>4; // Shift to lower 4-bits i.e. unpack1=06.
unpack1=unpack1 | 0x30; // Make it ASCII i.e. unpack1=36.

unpack2=packed & 0x0F; // Mask upper nibble i.e. unpack2=05.


unpack2=unpack2 | 0x30; // Make it ASCII i.e. unpack2=35.

P1=unpack1; // Send ASCII of unpack1 to Port 1.


P2=unpack2; // Send ASCII of unpack2 to Port 2.
}
8051 Programming in C – Manish Tiwari 26
P10: Unpacked to Packed
# include <reg51.h>
void main (void)
{
unsigned char packed;
unsigned char unpack1=0x36, unpack2=0x35; // Unpacked BCD.

unpack1=unpack1 & 0x0F; // Mask upper nibble i.e. unpack1=06.


unpack1=unpack1 <<4; // Shift to upper 4-bits i.e. unpack1=60.
unpack2=unpack2 & 0x0F; // Mask upper nibble i.e. unpack1=05.
packed=unpack1 | unpack2; // Pack the bytes i.e. packed=65.

P1=packed; // Send Packed BCD to Port 1.


P2=packed^0xFF; // Send complement of Packed BCD to Port 2.
}

8051 Programming in C – Manish Tiwari 27


Checksum byte in ROM
Data stored in ROM may be corrupted due to current surge.
It is, therefore, important to ensure integrity of ROM
contents. One such method is to introduce a checksum byte
at the end of data series. Following steps may be followed
to obtain checksum byte
• Add all the bytes and drop the final carry.
• Find out 2’s complement of sum. This is checksum byte.
DATA 1 35H
Example: DATA 2 65H
Obtain the checksum byte DATA 3 A0H
DATA 4 F1H
22BH
Sum after dropping carry 2BH
checksum byte = D5H 1’s complement D4H
2’s complement the checksum byte D5H
8051 Programming in C – Manish Tiwari 28
P11: Obtaining checksum byte
# include <reg51.h>
unsigned char mydata[5]={0x35,0x65,0xA0,0xF1,00} // 4 datas and
last entry is for checksum byte initially 00.
void get_checksum (void)
{
unsigned char i, sum=0, checksumbyte;

for(i=0; i<4; i++) // Add all the datas.


sum = sum+mydata[i];

checksumbyte = ~sum+1; // Obtain checksum.


mydata[5] = checksumbyte; // Tag checksum byte at the
end of data series.
return; // Back to caller
}
8051 Programming in C – Manish Tiwari 29
Checksum Operation to check Data Integrity
Example: Perform checksum operation
• Add all the bytes along with checksum byte and drop the
final carry.
• If the final sum is 00 data is not corrupted.

Example Data Not Corrupted Example Data Corrupted


DATA 1 35H DATA 1 35H
DATA 2 65H DATA 2 corrupted 64H
DATA 3 A0H DATA 3 A0H
DATA 4 F1H DATA 4 F1H
Checksum byte D5H Checksum byte D5H
Sum 300H Sum 2FFH
Sum after dropping carry 00 Sum after dropping carry FFH
Final Sum is 00, data is good. Final sum is non zero, data is bad.

8051 Programming in C – Manish Tiwari 30


P12: Checksum operation
# include <reg51.h>
unsigned char mydata[5]={0x35,0x65,0xA0,0xF1,0xD5} // 4 datas
and last entry is checksum byte.
void perform_checksum (void)
{
unsigned char i, checksum=0;

for(i=0; i<5; i++) // Add all the datas in array.


checksum = checksum+mydata[i];

if(checksum = 00) P1=‘G’; // Send Good to Port 1.


else P1=‘B’; // Send Bad to Port 1.
return; // Back to caller
}

8051 Programming in C – Manish Tiwari 31


Data Serialization
In many new generation devices such as LCDs, ADCs, ROM
etc the serial data transfer is preferred simply because they
occupy less space on a PCB due to less number data lines
and thereby decreasing the number of pins. Following may
be used for this purpose
– Using serial port of 8051- programmer has limited control on the
sequence of data bits being transferred. Advantage is that timing is
taken care automatically by UART port.
– Serializing of data under program control – programmer has to
take care of bit period. Advantage is full control over data sequence.

• Next is simple illustration of data serialization under the


program control.

8051 Programming in C – Manish Tiwari 32


P13:Transmit Serial Data
# include <reg51.h>
sbit TxB = P1^0; // Define transmitter line.
sbit ACCLSB = ACC^0; // Define LS bit of Accumulator.
// LS bit is transmitted first and Accumulator shifted for next higher bit.
void to_serial (unsigned char mybyte) // mybyte has to be transferred.
{
unsigned char i;
ACC = mybyte; // byte to be serialized in Acc.
for(i=0; i<8; i++) // Add all the datas in array.
{
TxB = ACCLSB; // Transmit LS bit.
ACC>>1; // Shift Acc to get new LS bit.
NOP; // Give some time between bits.
}
return; // Back to caller
}
8051 Programming in C – Manish Tiwari 33
P14:Receive Serial Data
# include <reg51.h>
sbit RxB = P1^1; // Define receiver line.
sbit ACCMSB = ACC^7; // Define MS bit of Accumulator.
// LS bit is received first and Accumulator shifted for next higher bit.
char to_parallel (void) // received byte will be returned.
{
unsigned char i;
ACC = 00; // Initialize Accumulator with 0.
for(i=0; i<8; i++) // Add all the datas in array.
{
ACCMSB = RxB; // Receive the bit MS bit position of Acc.
ACC>>1; // Shift Acc to get next bit.
NOP; // Give some time between bits.
}
return(ACC); // Back to caller
}
8051 Programming in C – Manish Tiwari 34
Program P9 : Using Code Space

Store a lookup table containing square


of hexadecimal digits (0 to 9 and A to
F) in code memory and Write a
program that reads hexadecimal digit
from P0 and send its square at P1,
continuously using the lookup table.

8051 Programming in C – Manish Tiwari 35


P9: Using Code space
# include <reg51.h>
# define INPUT P0 // P0 is input port.
# define OUTPUT P1 // P1 is output port.
code unsigned char SQR_LOOKUP[ ] = 0,1,4,9,16,25,36,49,64,81,100,121,
144,169,196,225 // Store the lookup table in code memory.
void main (void)
{
unsigned char num;
INPUT=0xFF; // Initialize port for input.
while(1) // Do it continuously.
{
num = INPUT; // Read the input.
OUTPUT = SQR_LOOKUP[num]; // Output the square.
}
}
8051 Programming in C – Manish Tiwari 36

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy