Microprocessor Application, Organisation and Embedded
Systems (EEE5232)
Lecture – 3: More 8051 project examples (in C)
Examples:
• bit myflag; //declaring myflag as a bit variable
myflag=1; //set myflag to 1
• unsigned char var1, var2; //declare var1 and var2 as unsigned char
var1=0xAA; //assign hex value AA to var1
var2=var1; //assign value of var1 to var2
• unsigned short temp; //declare temp as an unsigned short variable
temp = 0x0C200 //assign hex value C200 to temp
• unsigned int n1, n2; //declare n1 and n2 as unsigned itegers
n1=10; n2=2*n1; //assign 10 to n1, multiply n1 by 2 and assign to n2
• unsigned long temp; //declare temp as a long integer variable
temp=250000; //assign 25000 to temp
• float t1, t2; //t1 and t2 are declared as floating point variables
t1=25.4; t2=sqrt(t1); //assign 25.4 to t1, find its square root and assign it to t2
• sbit switch=P1^3; //a variable switch is assigned to bit3 of port1
switch=0; //clears bit3 of port1
Some commonly used Conditional Statements (Flow control statements):
1. IF, THEN, ELSE, ENDIF Turn on LED
IF switch=1 THEN Read Port – 1
Turn on Buzzer END DO
Else ENDIF
Turn off Buzzer
Turn off LED DO FOREVER
ENDIF Read data from Port – 1
2. DO, ENDDO Display data
Turn On LED Delay a second
DO 5 times END DO
Set clock to 1
Set clock to 0 4. REPEAT UNTIL
ENDDO REPEAT
3. DO FOREVER, DO UNTIL Turn on buzzer
Turn off the buzzer Read the switch value
IF switch=1 THEN UNTIL switch = 1
DO UNTIL Port-1 = 2
Project – 1:
Keep flashing the LED on port 1 that corresponds to any pressed switch on port 0. (i.e., S1 flashes Led1 etc)
#include <reg51.h>
void MSDelay(unsigned int); //delay function prototype declaration
void main( )
{
unsigned char mybyte;
P0 = 0xFF; //make P1 input port
for(;;)
{
mybyte=P0;
P1 = mybyte;
MSDelay(20);
P1 = 0xFF;
MSDelay(20);
}
}
void MSDelay(unsigned int itime) //the delay function definition
{
unsigned int i, j;
for (i = 0; i < itime; i++)
for (j = 0; j< 1275; j++);
}
Project – 2:
(Using the same circuit setup as in Project1) Write a program that counts up in binary and displays the results
on the LEDs connected to Port – 1. Let there be few seconds display between the displays.
#include <reg51.h>
//the delay routine implementation comes up first, no function declaration needed
void MSDelay()
{
unsigned int i;
for (i = 0; i <= 33000; i++);
}
void main( )
{
int LED=1; //initialize count to 1
for(;;)
{
P1 = ~LED;
LED++; //increment the count
MSDelay();
}
}
Project – 3:
Write a program that receives an 8-bit data from Port – 1 and stores it in a variable named “first”. The state of
a switch (connected to bit 0 of port – 3) is then checked. If the switch is 1, then variable “first” is doubled by
calling a function named “double_it”. Otherwise, if the switch is 0, the variable “first” is incremented by 2 by
calling another function named “inc_by2”
#include <reg51.h>
#define ON 1
#define OFF 0
sbit swch = P3^0;
//function to double a value
unsigned char double_it(unsigned char x)
{
return(2*x);
}
//function to increment value by 2
unsigned char inc_by2(unsigned char x)
{
return(x+2);
}
//start main program
void main( )
{
unsigned char first, second;
first=P1; //get 8-bit data from port – 1
if (swch==1)
second=double_it(first);
else
second=inc_by2(first);
for(;;)
{
}
}
Project – 4 (A Seven – segment display):
Dice: When a push button is pressed, a random number between 0 and 6 is generated and displayed on the 7-
segment display. After about 2 seconds, the display is cleared, and the user can throw the dice again.
Note: We use a common – anode type display, connected to P3.7 to P3.1. Pay attention to the numbering on
the table.
a/7
a/7
b/6
c/5 f/2 b/6
d/4 g/1
e/3
e/3 c/5
f/2
d/4
g/1
7 6 5 4 3 2 1 0 Hex
0 0 0 0 0 0 0 1 1 03
1 1 0 0 1 1 1 1 1 9F
2 0 0 1 0 0 1 0 1 25
3 0 0 0 0 1 1 0 1 0D
4 1 0 0 1 1 0 0 1 99
5 0 1 0 0 1 0 0 1 49
6 0 1 0 0 0 0 0 1 41
7 0 0 0 1 1 1 1 1 1F
8 0 0 0 0 0 0 0 1 01
9 0 0 0 1 1 0 0 1 19
#include <reg51.h>
sbit btton=P0^7; //the button is connected to Port-0 Pin 7
//the delay routine implementation
void wait_a_second()
{
unsigned int i;
for (i = 0; i <= 33000; i++);
}
//start main program
void main( )
{
unsigned char num;
unsigned char Dice[10]={0x03,0x9F,0x25,0x0D,0x99,0x49,0x41,0x1F,0x01,0x19};
for(;;)
{
if (btton==0)
{
P3 =Dice[num];
wait_a_second();
wait_a_second();
P3 = 0xFF; //sending 11111111 turns off the display
}
else
{
num++;
if(num==7) num=1;
}
}
}
Exercise:
Implement the project using a common – cathode display.
Can you try generating random hexadecimal numbers (0, 1, 2, 3, 4 ,5, 6, 7, 8, 9, A, B, D, E, F)?
Project – 5 (4-digits display):
The 4-digit display counts from 0000 to 1000.
for(i=0;i<100;i++)
#include <reg51.h> {
#define SegOne 0xfe num=cnt;
#define SegTwo 0xfd temp=num/1000;
#define SegThree 0xfb num=num % 1000;
#define SegFour 0xf7 P3=SegOne;
P2=hexvalue[temp];
//the delay routine implementation DELAY_ms(1);
void DELAY_ms(unsigned int ms_Count)
{ temp=num/100;
unsigned int i,j; num=num % 100;
for (i = 0; i <= ms_Count; i++) P3=SegTwo;
{ P2=hexvalue[temp];
for(j=0;j<100;j++); DELAY_ms(1);
}
} temp=num/10;
P3=SegThree;
//start main program P2=hexvalue[temp];
void main( ) DELAY_ms(1);
{
char hexvalue[]={0x3F,0x06,0x5B,0x4F, temp=num % 10;
0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77, P3=SegFour;
0x7c,0x39,0X5e,0x79,0x71}; P2=hexvalue[temp];
int cnt,num,temp,i; DELAY_ms(1);
}
while(1) }
{ }
for(cnt=0x00;cnt<=9999;cnt++) //loop to display }
0-F
{
Project – 6 (Temperature sensor + ADC + LCD display):
The LM35 analog temperature sensor is used to measure temperature; its output (in voltage) is fed to the
analog input of the ADC0804 A/D converter. Temperatures from 0 to 100 degree centigrade are displayed on
the LCD screen.
This project is implemented in two parts.
- Part – A: Interfacing an LCD with the microcontroller
- Part – B interfacing the LM35 and AD0804
Part – A: The LCD
• LCD pins:
1. VSS = ground. VDD = +5V supply
2. VEE = contrast control (connected to potentiometer)
3. RS. When RS = 0, command register. When RS=1, Data register.
4. R/W. When R/W=0, write operation. When R/W=1, read operation.
5. E. Latches information presented to its data bus.
6. D0 – D7 are the 8 – bit data lines.
D7 D6 D5 D4 D3 D2 D1 D0 INSTRUCTION HEX CODE
0 0 0 0 0 0 0 1 CLEARS DISPLAY 01
0 0 0 0 0 0 1 --- Return home 02
0 0 0 0 0 1 I/D S Entry mode set 04 = shift cursor left
05= shift display right
06= shift cursor right
07=shift display left
0 0 0 0 1 D C B Display on/off control 08=display off, cursor off
0A=display off cursor on
0C=display on, cursor off
0E=display on, cursor on
0F=display on, cursor blinking
0 0 0 1 S/C R/L - - Cursor move or display 10=shift cursor position left
shift 14=shift cursor position right
18=shift entire display left
1C=shift entire display right
0 0 1 DL N F -- -- Fuction set 38=two lines, 8 bit mode and
5x7 matrix font
Also,
80H = force cursor to beginning of first line
C0H = force cursor to beginning of second line
LCD programming Procedure:
1. Initialize LCD by sending commands: 3. Send character to be displayed
RS = 0 RS=1
R/W=0 R/W=0
Make E=1 and then make E=0 Make E=1 and then make E=0
2. Apply delay
No Hex Command function No Hex Command function
1 0x01 Clear display screen 9 0x0C Display on, Cursor off
2 0x30 Function set: 8bit, 1 line, 5x7 dots 10 0X0F Display on, Cursor blinking
3 0x38 Function set: 8bit, 2 line, 5x7 dots 11 0X18 Shift entire display left
4 0x20 Function set: 4bit, 1 line, 5x7 dots 12 0X1C Shift entire display right
5 0x28 Function set: 4bit, 2 line, 5x7 dots 13 0X10 Move cursor left by one character
6 0x06 Entry mode 14 0X14 Move cursor right by one character
7 0x08 Display off, Cursor off 15 0X80 Force cursor to beginning of 1st row
8 0x0E Display on, Cursor on 16 0XC0 Force cursor to beginning of 2nd row
❖ Program to display “Embedded Systems” on the first line and “Code: EEE5232” on the second line of a
16x2 LCD screen.
#include <reg51.h>
sbit rs=P3^5;
sbit rw=P3^6;
sbit en=P3^7;
void lcdcmd(unsigned char);
void lcddat(unsigned char);
void delay();
void lcd_str(unsigned char *str);
void main()
{
P2=0x00; //output declaration for data lines d0 to D7 connected to P2
lcdcmd(0x38); //command for 5X7 matrix
lcdcmd(0x01); //command to clear screen
lcdcmd(0x10); //cursor blinking
lcdcmd(0x0C); //display ON
lcdcmd(0x81); //force cursor to first line
while(1)
{
lcd_str("Embedded Systems");
lcdcmd(0xC0);
lcd_str(" Code: EEE5302 ");
}
}
void lcd_str(unsigned char *str)
{
unsigned int loop=0;
for(loop=0; str[loop]!='\0';loop++)
{
lcddat(str[loop]);
}
}
void lcdcmd(unsigned char val)
{
P2=val;
rs=0;
rw=0;
en=1;
delay();
en=0;
}
void lcddat(unsigned char val)
{
P2=val;
rs=1;
rw=0;
en=1;
delay();
en=0;
}
void delay()
{
unsigned int i;
for(i=0;i<12000;i++);
}
Part – B:
Nb:
• Sensors/transducers convert physical quantities like temperature, pressure, humidity, speed etc. to
electrical voltage/current (analog signal).
5𝑉
• ADC0804 has an 8bit resolution. Its output spans between 0v to 5v, thus the step size is 255 = 19.53𝑚𝑉
• ADC0804 pins:
1. CS: an active low pin, used to activate the chip
2. RD: also active low input signal. Used to read the converted signal from ADC
3. WR: also active low input signal. Used to inform adc to start conversion
4. INTR: also active low output signal. It is normally high. When data conversion is complete, it goes low.
5. Vin+ is connected to the output pin of the temperature sensor. Vin- is grounded.
• To use AD0804:
1. Configurethe port pins on the 8051 for WR, RD and INTR.
2. Make CS=0
3. Send a L-H pulse to the WR pin to start conversion
4. Keep monitoring INTR, if INTR=1, wait for it to go LOW (the result is stored in the ADC’s register).
5. When INTR=0,send a H-L pulse on RD to get data into 8051.