4 TH
4 TH
Cross compiler C -programming structure, Data types, memory models, infinite loops and
handling interrupts in C. Intel Hex file format. C - Programming for LED, LCD display,
temperature sensor with ADC, Measuring pulse width and frequency
,,
Compilers:
Compilers produce hex files that we download into the ROM of the
microcontroller. The size of the hex file produced by the compiler is
one of the main concerns of microcontroller programmers, for two
reasons:
Microcontrollers have limited on-chip ROM.
The code space for the 8051 is limited to 64K bytes.
How does the choice of programming language affect the
compiled pro- gram size? While Assembly language produces a
hex file that is much smaller than C, programming in Assembly
language is tedious and time consuming. C programming, on the
other hand, is less time consuming and much easier to write, but
the hex file size produced is much larger than if we used Assembly
language. The following are some of the major reasons for writing
programs inC instead of Assembly:
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 microcontrollers with little or no modification.
8051 PROGRAMMING IN
1
C data types for the 8051
Since one of the goals of 8051 C programmers is to create
smaller hex files, it is worthwhile to reexamine C data types for
the 8051. In other words, a good understanding of C data types for
the 8051 can help programmers to create smaller hex files. In this
section, we focus on the specific C data types that are most useful
and widely used for the 8051 microcontroller.
DATA TYPES
Unsigned char
Signed char
Unsigned int
Signed int
Sbit (single bit)
Bit and sfr
Unsigned char
Since the 8051 is an 8-bit microcontroller, the character data type
is themost natural choice for many applications.
The unsigned char is an 8-bit data type that takes a value in the
range of 0–255 (00–FFH).
It is one of the most widelyused 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
Example 1
Write an 8051 C program to send values 00–FF to port P1.
Solution:
#include <reg51.h> void main(void)
{
unsigned char z; for(z=0;z<=255;z++)
P1=z;
}
Run the above program on your simulator to see how P1 displays values 00–FFHin binary.
Example 2
Solution:
// Toggle P1 forever #include <reg51.h> void main(void)
8051 PROGRAMMING IN
1
Signed char
The signed char is an 8-bit data type that uses the most
significant bit(D7 of D7–D0) to represent the – or + value.
The magnitude of the signed number, giving us values from –
128 to +127.
If we do not use the keyword unsigned, the default is the signed
value. For that reason,we should stick with the unsigned char
unless the data needs to be represented as signed numbers. See
Example 4.
Example 4
Solution:
//sign numbers #include
<reg51.h>void main(void)
Example 3
Exa mple
Solution:
8051 PROGRAMMING IN
1
,,
Unsigned int
Takes a value in the range of 0 to 65535(0000 -FFFFH)
Define 16-bit variables such as memoryaddresses
Set counter values of more than 256
Since registers and memory accesses arein 8-bit chunks, the misuse of int variableswill
result in a larger hex file
Signed int
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,767.
Example 5
Solution:
#include <reg51.h> sbit MYBIT = P1^0;
//notice that sbit is
//declared outside of main
void main(void)
for (z=0;z<=50000; z++) MYBITMYBIT
= 0;
8051 PROGRAMMING IN
1
Bit and sfr
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. We will see the use of sbit, bit,
and sfr data types in the next section. See Table 1.
Time delay
There are two ways to create a time delay in 8051 C:
1. Using a simple for loop
2. Using the 8051 timers
8051 PROGRAMMING IN
1
,,
Solution:
Example 6
Solution:
// Toggle P1 forever with some delay in between “on” and “off”. #include <reg51.h>
Void main(void)
Unsigned int x;
{ P1=0x55;
For(x=0;x<40000;x++); //delay size unknown
P1=0xAA; For(x=0;x<40000;x++);
}
8051 PROGRAMMING IN
1
I/O PROGRAMMING IN 8051 C
In this section, we look at C programming of the I/O ports for the 8051.
We look at both byte and bit I/O programming.
In 8051, I/O operations are done using four Input/output ports P0, P1, P2, and P3,
each port is 8-bit port having 8 pins each. During RESET, all the ports are used as
input ports. When the port gets first 0, then it becomes an output port.
Example 9
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>
8051 PROGRAMMING IN
1
,,
Write an 8051 C program to toggle only bit P2.4 continuously without disturbing
The rest of the bits of P2.
Solution:
#include <reg51.h>
Void main(void)
While(1)
8051 PROGRAMMING IN
1
,,
Example 16
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.
Solution:
// Accessing Ports as SFRs using the sfr data type
sfr P0 = 0x80; //declaring P0 using sfr data
type sfr P1 = 0x90;
sfr P2 = 0xA0;
void MSDelay(unsigned int);
void main(void)
{
while(1) //do it forever
{
P0=0x55;
P1=0x55;
P2=0x55;
MSDelay(250); //250 ms delay
P0=0xAA;
P1=0xAA;
P2=0xAA;
MSDelay(250);
}
}
8051 PROGRAMMING IN
1
Using bit data type for bit-addressable RAM
The sbit data type is used for bit-addressable SFR registers
only. Sometimes we need to store some data in a bit- addressable
section of the data RAM space 20–2FH. To do that, we use the bit
data type.
The Intel HEX file format is a text-based file format used to represent
binary data, particularly in the context of programming microcontrollers and other
programmable devices. It is widely used in the embedded systems and
microcontroller programming communities. The format is designed to be human-
readable while encoding binary data in a compact, efficient, and checksum-verified
manner.
Here's a brief overview of the structure and common features of an Intel HEX
file
Data Record (Type 00): Contains data bytes and the starting address
for that data. The data is encoded in hexadecimal form.
End of File Record (Type 01): Marks the end of the HEX file.
Length Byte: The first byte following the colon (':') specifies the number
of bytes (n) in the record.
Address Field: The next two to four bytes (depending on the HEX file
variant) represent the memory address where the data should be stored.
This field is used to specify where in the memory the data should be
loaded.
Record Type: The next two bytes indicate the record type. The most
common types are 00 (Data Record) and 01 (End of File Record).
Data Bytes: Following the record type, the next 2n bytes contain the
binary data. These bytes are typically represented in hexadecimal format
(two characters per byte).
EXAMPLE:
10 0100 00 214601360121470136007EFE09D21901 40
The 10 following the colon represents the length of the data (16 bytes).
Each line of the hex file consists of six parts. In Figure 9, we have
separated the parts to make it easier to analyze.
INTERRUPT PROGRAMMING IN C
So far all the programs in this chapter have been written in Assembly.
In this section, we show how to program the 8051/52’s interrupts in 8051 C
language. In reading this section, it is assumed that you already know the
material in the first two sections of this chapter.
Example 14
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 in 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 main()
{
SW = 1; //make switch input
TMOD = 0x02;
TH0 = 0xA4; //TH0 = -92
IE = 0x82; //enable interrupts for timer 0
while(1)
{
IND = SW; //send switch to LED
}
}
200 µs / 2 = 100 µs
100 µs / 1.085 µs = 92
8051
Switch
Example 17
Write a C program using interrupts to do the following:
(a) Generate a 10000 Hz 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()
{
cnt = 0; //set counter to zero
TMOD = 0x42;
TH0 = 0x-46; //10000 Hz
IE = 0x86; //enable interrupts
TR0 = 1; //start timer 0
TR1 = 1; //start timer 1
while(1); //wait until interrupted
}
1/10000 Hz = 100 µs
100 µs/2 = 50 µs
50 µs/1.085 µs = 46
//
/
from
LCD INTERFACING
LCD operation
In recent years, the LCD is finding widespread use replacing LEDs (seven-
segment LEDs or other multisegment LEDs). This is due to the follow- ing reasons:
1. The declining prices of LCDs.
2. The ability to display numbers, characters, and graphics. This is in
contrast to LEDs, which are limited to numbers and a few characters.
3. Incorporation of a refreshing controller into the LCD, thereby relieving
the CPU of the task of refreshing the LCD. By contrast, the LED must be
refreshed by the CPU (or in some other
way) to keep displaying the data. Table 1. Pin Descriptions for LCD
4. Ease of programming for characters and Pin Symbol I/O Description
graphics.
1 Vss -- Ground
LCD pin descriptions 2 Vcc -- +5 V power supply
3
The LCD discussed in this section has Vee -- Power supply
14 pins. The function of each pin is given in to control contrast
4
Table 1. Figure 1 shows the pin positions for RS I RS = 0 to select
various LCDs. command register,
RS = 1 to select
VCC, VSS, and VEE data register
While VCC and VSS provide +5 V and 5
R/W I R/W = 0 for write,
ground, respectively, VEE is used for control- ling R/W = 1 for read
LCD contrast. 6
E I Enable
7
RS, register select DB0 I/O The 8-bit data bus
8
There are two very important registers DB1 I/O The 8-bit data bus
9
inside the LCD. The RS pin is used for their DB2 I/O The 8-bit data bus
selection as follows. 10
DB3 I/O The 8-bit data bus
11
If RS = 0,code register is selected, DB4 I/O The 8-bit data bus
allowing the user to clear display. 12
DB5 I/O The 8-bit data bus
13
If RS = 1, the data register is DB6 I/O The 8-bit data bus
selected, allowing the user to send data. 14
DB7 I/O The 8-bit data bus
R/W, read/write
Table 2. LCD Command Codes Code R/W input allows the user to
Command to LCD Instruction (Hex) Register write information to the LCD or read
1 Clear display screen information from it. R/W = 1 when
reading; R/W = 0 when writing.
2
Return home E, enable
The enable pin is used by the
4 Decrement cursor (shift cursor to left) LCD to latch information presented to its
6 Increment cursor (shift cursor to right) data pins. When data is supplied to data
pins, a high-to-low pulse must be applied
5 Shift display right
to this pin in order for the LCD to latch
7 in the data present at the data pins. This
Shift display left pulse must be a minimum of 450 ns
wide.
8 Display off, cursor off D0–D7
A Display off, cursor on
The 8-bit data pins, D0–D7, are
C Display on, cursor off used to send information to the LCD or
E Display on, cursor blinking off read the contents of the LCD’s internal
F Display on, cursor blinking registers. To display letters and
10 Shift cursor position to left numbers,
we send ASCII codes for the letters A–Z,
14 Shift cursor position to right a–z, and numbers 0–9 to these pins while
18 Shift the entire display to the left making RS = 1.
1C Shift the entire display to the right
80 Force cursor to beginning of 1st line
C0 Force cursor to beginning of 2nd line
38 2 lines and 5x7 matrix
LCD
8051 +5 V
P1.0 D0 Vcc
Vee 10 K POT
P1.7 D7
RS R/W E Vss
3
L
LCD AND KEYBOARD
3
,,
Keyboards and LCDs are the most widely used input/output devices of the
8051, and a basic understanding of them is essential. In this section, we first
discuss keyboard fundamentals, along with key press and key detection
mechanisms. Then we show how a keyboard is interfaced to an 8051.
The sensors of the LM34 series are precision integrated-circuit temper-ature sensors
whose output voltage is linearly proportional to the Fahrenheit temperature.
LC
D0 D7
RS R/W E
Vcc 10
+5 Vss
V P2.0 P2.1 P2.2 Vcc
+5 V
10
P1.7 D7
P1.7
;Program 1
;Assembly code to read temperature, convert it,
;and put it on P0 with some delay
RD BIT P2.5 ; RD
WR BIT P2.6 ; WR (start conversion)
INTR BIT P2.7; end-of-conversion
MYDATA EQU P1 ;P1.0-P1.7=D0-D7 of the ADC0848
MOV P1,#0FFH ;make P1 = input
SETB INTR
BACK: CLR WR ;WR=0
SETB WR ;WR=1 L-to-H to start conversion
HERE: JB INTR,HERE ;wait for end of conversion
CLR RD ;conversion finished,enable RD
MOV A,MYDATA ;read the data from ADC0848
ACALL CONVERSION ;hex-to-ASCII conversion
ACALL DATA_DISPLAY ;display the data
SETB RD ;make RD=1 for next round
SJMP BACK
CONVERSION:
MOV B,#10
DIV AB
MOV R7,B ;least significant byte
MOV B,#10
DIV AB
MOV R6,B
MOV R5,A ;most significant byte
RET
DATA_DISPLAY
MOV P0,R7
ACALL DELAY
MOV P0,R6
ACALL DELAY
MOV P0,R5
ACALL DELAY
RET
//Program 2
//C code to read temp from ADC0848, convert it to
//decimal, and put it on P0 with some delay
#include <reg51.h>
sbit RD = P2^5;