You are on page 1of 42

INDEX

S.No Experiment Name Date Sign.

1. Introduction to microcontroller and interfacing modules

WAP to show Interfacing Seven Segment Display with


2.
microcontroller

WAP to create a series of moving lights on LEDs using


3.
8051

4. WAP to Interface Stepper Motor with microcontroller

WAP to display Digital Output of ADC on LCD


5.
Module

6. WAP to display character 'A' on 8*8 LED Matrix

7. WAP to display Date and Time on LCD Module

8. WAP to Interface DC motor using H-Bridge

9. WAP to Interface Keypad with Microcontroller


EXPERIMENT NO. 1

Introduction to Microcontroller and Interfacing Modules

INTORDUCTION to MICROCONTOLLERS
A microcontroller is a small computer on a single integrated circuit containing a
processor core, memory, and programmable input/output peripherals. Program memory is
in the form of NOR flash or OTP ROM is also often included on chip, as well as a
typically small amount of RAM. Microcontrollers are designed for embedded
applications, in contrast to the microprocessors used in personal computers or other
general purpose applications.
Microcontrollers are used in automatically controlled products and devices, such as
automobile engine control systems, implantable medical devices, remote controls, office
machines, appliances, power tools, and toys. By reducing the size and cost compared to a
design that uses a separate microprocessor, memory, and input/output devices,
microcontrollers make it economical to digitally control even more devices and
processes. Mixed signal microcontrollers are common, integrating analog components
needed to control non-digital electronic systems.
Some microcontrollers may use Four-bit words and operate at clock rate frequencies as
low as 4 kHz, for low power consumption (mill watts or microwatts). They will generally
have the ability to retain functionality while waiting for an event such as a button press or
other interrupt; power consumption while sleeping (CPU clock and most peripherals off)
may be just nanowatts, making many of them well suited for long lasting battery
applications. Other microcontrollers may serve performance-critical roles, where they
may need to act more like a digital signal processor (DSP), with higher clock speeds and
power consumption.

EMBEDDED DESIGN

A microcontroller can be considered a self-contained system with a processor, memory


and peripherals and can be used as an embedded system.[1] The majority of
microcontrollers in use today are embedded in other machinery, such as automobiles,
telephones, appliances, and peripherals for computer systems. These are called embedded
systems. While some embedded systems are very sophisticated, many have minimal
requirements for memory and program length, with no operating system, and low
software complexity. Typical input and output devices include
switches, relays, solenoids, LEDs, small or custom LCD displays, radio frequency
devices, and sensors for data such as temperature, humidity, light level etc. Embedded
systems usually have no keyboard, screen, disks, printers, or other recognizable I/O
devices of a personal computer, and may lack human interaction devices of any kind.
INTEL 8051

The Intel MCS-51 is a Harvard architecture, single chip microcontroller (µC) series
which was developed by Intel in 1980 for use in embedded systems.[1][2] Intel's original
versions were popular in the 1980s and early 1990s, but has today largely been
superseded by a vast range of faster and/or functionally enhanced 8051-compatible
devices manufactured by more than 20 independent manufacturers
including Atmel,Infineon Technologies (formerly Siemens AG), Maxim Integrated
Products (via its Dallas
Semiconductor subsidiary), NXP (formerly PhilipsSemiconductor), Nuvoton
(formerly Winbond), ST Microelectronics, Silicon Laboratories (formerly Cygnal), Texas
Instruments, Ramtron International, Silicon Storage Technology, and Cypress
Semiconductor.
Intel's original MCS-51 family was developed using NMOS technology, but later
versions, identified by a letter C in their name (e.g., 80C51) used CMOS technology and
were less power-hungry than their NMOS predecessors. This made them more suitable
for battery-powered devices.

Pin Diagram of 8051 Microcontroller


INTORDUCTION to INTERFACING

Interfacing refers to the ability or capacity of two objects or items to be brought together
to form a function together or a surface forming a common boundary between two
adjacent regions, forms, bodies, etc.

In the computer science and technology fields, interfacing refers to the point of
interaction or communication between two devices or a user and a device.

INTERFACING THE KEYBOARD TO 8051

The key board here we are interfacing is a matrix keyboard.


This key board is designed with a particular rows and columns.
These rows and columns are connected to the microcontroller through its ports of the
micro controller 8051. We normally use 8*8 matrix key boards. So only two ports of
8051 can be easily connected to the rows and columns of the key board.

Whenever a key is pressed, a row and a column gets shorted through that pressed key and
all the other keys are left open. When a key is pressed only a bit in the port goes high
which indicates microcontroller that the key is pressed. By this high on the bit key in the
corresponding column is identified.

Once we are sure that one of key in the key board is pressed next our aim is to identify
that key. To do this we first check for a particular row and then we check the
corresponding column the key board.

To check the row of the pressed key in the keyboard, one of the rows is made high by
making one of bit in the output port of 8051 high. This is done until the row is found
out. Once we get the row next job is to find out the column of the pressed key. The
column is detected by contents in the input ports with the help of a counter. The content
of the input port is rotated with carry until the carry bit is set.

The contents of the counter is then compared and displayed in the display. This display is
designed using a seven segment display and a BCD to seven segment decoder IC
7447.The BCD equivalent number of counter is sent through output part of 8051 displays
the number of pressed key.

MICRO
KEYPAD DISPLAY
CONTROLLER

Block diagram of INTERFACING KEY BOARD TO 8051.


Circuit diagram of INTERFACING KEY BOARD TO 8051.

1. The 8051 has 4 I/O ports P0 to P3 each with 8 I/O pins, P0.0 to P0.7,P1.0 to P1.7,
P2.0 to P2.7, P3.0 to P3.7. The one of the port P1 (it understood that P1 means
P1.0 to P1.7) as an I/P port for microcontroller 8051, port P0 as an O/P port of
microcontroller 8051 and port P2 is used for displaying the number of pressed
key.
2. Make all rows of port P0 high so that it gives high signal when key is pressed.
3. See if any key is pressed by scanning the port P1 by checking all columns for non
zero condition.
4. If any key is pressed, to identify which key is pressed make one row high at a
time.
5. Initiate a counter to hold the count so that each key is counted.
6. Check port P1 for nonzero condition. If any nonzero number is there in
[accumulator], start column scanning by following step 9.
7. Otherwise make next row high in port P1.
8. Add a count of 08h to the counter to move to the next row by repeating steps
from step 6.
9. If any key pressed is found, the [accumulator] content is rotated right through the
carry until carry bit sets, while doing this increment the count in the counter till
carry is found.
10. Move the content in the counter to display in data field or to memory location
11. To repeat the procedures go to step 2.
INTERFACING THE LCD TO 8051

PINOUT

• 8 data pins D7:D0


Bi-directional data/command pins.
Alphanumeric characters are sent in ASCII format.

• RS: Register Select


RS = 0 -> Command Register is selected
RS = 1 -> Data Register is selected

• R/W: Read or Write


0 -> Write, 1 -> Read

• E: Enable (Latch data)


Used to latch the data present on the data pins.
A high-to-low edge is needed to latch the data.

Display Data RAM (DDRAM)

Display data RAM (DDRAM) is where you send the characters (ASCII code) you want
to see on the LCD screen. It stores display data represented in 8-bit character codes. Its
capacity is 80 characters (bytes). Below you see DD RAM address layout of a 2*16
LCD.

In the above memory map, the area shaded in black is the visible display (For 16x2
display) .
For first line addresses for first 15 characters is from 00h to 0Fh. But for second line
address of first character is 40h and so on up to 4Fh for the 16th character.

So if you want to display the text at specific positions of LCD , we require to manipulate
address and then to set cursor position accordingly .

Character Generator RAM (CGRAM)-User defined character RAM

In the character generator RAM, we can define our own character patterns by program.
CG RAM is 64 bytes, allowing for eight 5*8 pixel, character patterns to be defined.
However how to define this and use it is out of scope of this tutorial. So I will not talk
any more about CGRAM
Registers

The HD44780 has two 8-bit registers, an instruction register (IR) and a data register
(DR). The IR stores instruction codes. The DR temporarily stores data to be written into
DDRAM or CGRAM and temporarily stores data to be read from DDRAM or CGRAM.
Data written into the DR is automatically written into DDRAM or CGRAM by an
internal operation. . These two registers can be selected by the register selector (RS)
signal. See the table below:

Register Selection
RS R/WOperation
0 0 IR write as an internal operation (display clear, etc.)
0 1 Read busy flag (DB7) and address counter (DB0 to DB6)
1 0 DR write as an internal operation (DR to DDRAM or CGRAM)
1 1 DR read as an internal operation (DDRAM or CGRAM to DR)

Busy Flag (BF)

When the busy flag is 1, the LCD is in the internal operation mode, and the next
instruction will not be accepted. When RS = 0 and R/W = 1 (see the table above), the
busy flag is output to DB7 (MSB of LCD data bus). The next instruction must be written
after ensuring that the busy flag is 0.

LCD Commands

The LCD’s internal controller accepts several commands and modifies the display
accordingly. These commands would be things like:
– Clear screen
– Return home
– Shift display right/left

Instruction Decimal HEX


Scroll display one character right (all lines) 28 1E
Scroll display one character left (all lines) 24 18
Home (move cursor to top/left character position) 2 2
Move cursor one character left 16 10
Move cursor one character right 20 14
Turn on visible underline cursor 14 0E
Turn on visible blinking-block cursor 15 0F
Make cursor invisible 12 0C
Blank the display (without clearing) 8 08
Restore the display (with cursor hidden) 12 0C
Clear Screen 1 01
Set cursor position (DDRAM address) 128 + addr 80+ addr
Set pointer in character-generator RAM (CG RAM address) 64 + addr 40+ addr

The 44780 standard requires 3 control lines as well as either 4 or 8 I/O lines for the data
bus. The user may select whether the LCD is to operate with a 4-bit data bus or an 8-bit
data bus.

If a 4-bit data bus is used, the LCD will require a total of 7 data lines.
If an 8-bit data bus is used, the LCD will require a total of 11 data lines.

The three control lines are EN, RS, and RW.

Note that the EN line must be raised/lowered before/after each instruction sent to the
LCD regardless of whether that instruction is read or write text or instruction. In short,
you must always manipulate EN when communicating with the LCD. EN is the LCD's
way of knowing that you are talking to it. If you don't raise/lower EN, the LCD doesn't
know you're talking to it on the other lines.

Interfacing LCD to 8051


ADC - DAC INTERFACING IN 8051

Analog signals are very common inputs to embedded systems .Most transducers and
sensors such as temperature ,pressure ,velocity ,humidity are analog. Therefore we need
to convert these analog signals in to digital so that 8051 can read it.

ANALOG DIGITAL TO CONVERTER - ADC

Commonly used ADC device – ADC804

ABOUT IC

PinOut
• CS – Chip Select , active low
• RD – Read Digital data from ADC, H-L edge triggered
• WR -- Start conversion, L-H pulse edge triggered
• INTR -- end of conversion, Goes low to indicate conversion done
• Data bits -- D0-D7
• CLK IN & CLK R
– CLK IN is an input pin connected to an external clock source when an external clock is
used for timing. However, ADC804 has an internal clock
generator.
To use the internal clock generator of the ADC804, the CLK IN and CLK R pins are
connected to a capacitor and a resistor. In that case, the
clock frequency is determined by the equation.

f = 1/1.1RC
R=10K and C=150pF f=606Hz
the conversion time is 110us. Vref/2 Vin
Step size (mV)
Input Voltage range (Volts) (Volts)
• Default 0-5V. Can be changed by setting Open (2.5) 0 to 5 5/256 = 19.53
different value for Vref/2 pin. 2.56 0 to 5.12 5.12/256 =20
Vin=Vin(+) – Vin (-) 1.28 0 to 2.56 2.56/256 = 10
0.5 0 to 1 1/256=3.90
• Range = 0 to 2x Vref/2.
for Vin = 2x Vref/2. we get 256 as a digital output on D0-D7. (Refer Table)

•Step Size a Smallest change


– (2 x Vref/2)/ 256 for ADC804
for eg for step size 10mv ,digital output on D0-D7 changes by one count for every 10mv
change of the input analog voltage.
Data Out
Dout = Vin / Step Size

for input vtg. of 2.56 volts (Vref=1.28 volts) and stepsize of 10mv Dout =2560/10 =256
or FF that is full scale output.

Conversion Time
Greater than 110us for ADC804

Resolution
8 bits for ADC804

INTERFACING ADC804 TO 8051

Signals to be interfaced (on the ADC804)


– D0-D7, RD, WR, INTR, CS
Can do both Memory mapping and IO
mapping

Memory Mapping (timing is critical)


– Connect D0-D7 of ADC804 to the data
bus of the 8051 system
– Connect RD, WR of the ADC804 to the
8051 system (ensure polarity)
– Connect CS of ADC804 to an
appropriate address decoder output
– Connect INTR of ADC804 to an
external interrupt Pin on the 8051 (INT0 or INT1)

IO Mapping (easiest - I prefer)


– Connect D0-D7, RD, WR, CS, INTR to some port bits on the 8051 (12 in all).

Algorithm
• Make CS=0 and send a low-to-high to pin WR to start the conversion.
• Keep monitoring INTR
– If INTR =0, the conversion is finished and we can go to the next step.
– If INTR=1, keep polling until it goes low.
• After INTR=0, we make CS=0 and send a high-to-low pulse to RD to get the data out of
the ADC804 chip.
ASSEMBLY LANGUEGE (A51)

ADC_IO:
mov P1, #0xff ; To configure as input

AGAIN
clr p3.7 ;Chip select
setb P3.6 ;RD=1
clr P3.5 ;WR=0
setb P3.5 ;WR=1- low to high transition

WAIT:
jb P3.4, WAIT ;wait for INTR
clr p3.7 ;generate cs to ADC
clr P3.6 ;RD=0 -High to low transition
mov A, P1 ;read digital o/p
sjmp AGAIN

INTERFACING ADC804 TO 8051

ADC808/809 Chip with 8 analog channel. This means this kind of chip allows to monitor
8 different transducers.
• ADC804 has only ONE analog input: Vin(+).
• ALE: Latch in the address
• Start : Start of conversion (same as WR in
804)
• OE: output enable (same as RD in 804)
• EOC: End of Conversion (same as INTR in
804)

Channel CBA
IN0 000
IN1 001
IN2 010
IN3 011
IN4 100
IN5 101
IN6 110
IN7 111
Algorithm

Notice that the ADC808/809 that there is no self-clocking and the clock must be provided
from an external source to the CLK pin. (you can use programmable clock oscillator to
enable or disable clock by programmable bit. )

• Select an analog channel by provide bits to A, B, C.


• Enable clock

• Activate ALE with a low-to-high pulse.


• Activate SC with a high-to-low pulse (start conversion) The conversion is begun on the
falling edge of the start conversion pulse. you can use circuit like
• Monitor EOC Pin .After conversion this pin goes high.
• Activate OE with a high-to-low pulse to read data out of the ADC chip.

DIGITAL TO ANALOG CONVERTER - DAC

Commonly used DAC808 (MC1408)


– R/2R ladder
– Iout = Iref (D7/2 + D6/4 + D5/8 + …… + D0/256)
– Iout converted to voltage by a resistive load or op-amp based isolator (Rf from Vout to
V- and V+ to GND)

PinOut
– D0-D7 à Connected to the Processor’s IO port
– Vref+, Vref-, Vee

Usage:
– Just write a byte to the IO port and the DAC converts it to an
analog value
Some 8051 clones have ADCs and DACs in built
EXPERIMENT NO. 2

AIM: WAP to show Interfacing Seven Segment Display with


microcontroller

#include <Philips\8xC31-51-80C51Fx-80C51Rx+.h>
#include <stdio.h>
#include <standard.h>

/*----------------------Defining SFR bits here------------------------------*/


BIT sl1 P2.0 //Selects Display1/Row1

BIT sl2 P2.1 //Selects Display2/Row2

BIT sl3 P2.2 //Selects Display3/Row3

BIT sl4 P2.3 //Selects Display4/Row4

/*----------------------Defining user bytes here-----------------------------*/


unsigned char ds1; //stores ASCII data for display1
unsigned char ds2; //stores ASCII data for display2
unsigned char ds3; //stores ASCII data for display3
unsigned char ds4; //stores ASCII data for display4

void main ()
{

while(1) //infinite loop


{

sl1=0; //select display1


sl2=1;
sl3=1;
sl4=1;

ds1=0x60; //0110 0000b pattern for 1


P0=ds1;

delay_ms(5);

sl1=1;
sl2=0; //select display2
sl3=1;
sl4=1;
ds2=0xda; //1101 1010b pattern for 2
P0=ds2;

delay_ms(5);

sl1=1;
sl2=1;
sl3=0; //select display3
sl4=1;

ds3=0xf2; //1111 0010b pattern for 3


P0=ds3;

delay_ms(5);

sl1=1;
sl2=1;
sl3=1;
sl4=0; //select display4

ds4=0x66; //0110 0110b pattern for 4


P0=ds4;

delay_ms(5);

}
EXPERIMENT NO. 3

AIM: WAP to create a series of moving lights on LEDs using 8051

#include <REG51F.H>
unsigned int k;
void MSDelay(unsigned int);

void main(void)
{
P0=0X00;

while(1)
{
P0=0X01;
MSDelay(50000);
P0=0X02;
MSDelay(50000);
P0=0X04;
MSDelay(50000);
P0=0X08;
MSDelay(50000);
P0=0X10;
MSDelay(50000);
P0=0X20;
MSDelay(50000);
P0=0X40;
MSDelay(50000);
P0=0X80;
MSDelay(50000);
}// end of while
}//end of main
void MSDelay(unsigned int itime)
{
unsigned int i,j;
for(i=0;i<itime;i++)
{
j++;
}
// for(j=0;j<1275;j++);
}
EXPERIMENT NO. 4

AIM: WAP to Interface Stepper Motor with microcontroller

#include <Philips\8xC31-51-80C51Fx-80C51Rx+.h>
#include <stdio.h>
#include <standard.h>
unsigned int scount;

/*----------------------Defining SFR bits here------------------------------*/


BIT stm1 P3.4;
BIT stm2 P3.5;
BIT stm3 P3.6;
BIT stm4 P3.7;

void main()
{
scount=25;
while(1)
{ stm1=1;
stm2=0;
stm3=0;
stm4=0;
delay_ms(scount);
stm1=0;
stm2=1;
stm3=0;
stm4=0;
delay_ms(scount);
stm1=0;
stm2=0;
stm3=1;
stm4=0;
delay_ms(scount);
stm1=0;
stm2=0;
stm3=0;
stm4=1;
delay_ms(scount);
}}
EXPERIMENT NO. 5

AIM: WAP to display Digital Output of ADC on LCD Module.

#include <p18xxxx.h>
#include <delays.h>
#include "lcd.h"
#include <string.h>

#define LCD_RS PORTAbits.RA3


#define LCD_EN PORTAbits.RA1
#define LCD_WR PORTAbits.RA2

#define set_dd_line1_pos1 0x80


#define set_dd_line2_pos1 0x80

char value1 [ ] = "0V";


char value2 [ ] = "5V";

void lcd_write_cmd(unsigned char cmd)


{
unsigned char temp2;
LCD_RS = 0;
Delay10TCYx(4);

temp2 = cmd;
temp2 = temp2 >> 4;
PORTD = temp2 & 0x0F;

Delay1KTCYx(1);
lcd_strobe();
Delay1KTCYx(1);

temp2 = cmd;
PORTD = temp2 & 0x0F;

Delay1KTCYx(1);
lcd_strobe();
Delay1KTCYx(1);

void lcd_clear(void)
{
lcd_write_cmd(0x01);
Delay1KTCYx(2);

void lcd_write_data(char data)


{
char temp1;

LCD_RS = 1;
Delay10TCYx(4);

temp1 = data;
temp1 = temp1 >> 4;
PORTD = temp1 & 0x0F;

Delay1KTCYx(1);
lcd_strobe();
Delay1KTCYx(1);

temp1 = data;
PORTD = temp1 & 0x0F;

Delay1KTCYx(1);
lcd_strobe();
Delay1KTCYx(1);

void lcd_goto(unsigned char LCD_POS)


{
lcd_write_cmd(LCD_POS);
Delay1KTCYx(2);
}

void lcd_strobe(void)
{
LCD_EN = 1;
Delay10TCYx(4);
LCD_EN = 0;
Delay10TCYx(4);
}

void lcd_init(void)
{
LCD_RS = 0;
LCD_WR = 0;

Delay1KTCYx(250);
Delay1KTCYx(250);
Delay1KTCYx(250);
Delay1KTCYx(250);
PORTD = 0x03;

lcd_strobe();
Delay1KTCYx(250);

PORTD = 0x03;
lcd_strobe();
Delay1KTCYx(250);

PORTD = 0x03;
lcd_strobe();
Delay1KTCYx(250);

PORTD = 0x02;
lcd_strobe();
Delay1KTCYx(250);
Delay1KTCYx(250);
lcd_write_cmd(0x2);

lcd_write_cmd(0x01);
Delay1KTCYx(20);
Delay1KTCYx(20);
lcd_write_cmd(0x0F);

Delay1KTCYx(20);

lcd_write_cmd(0x06);

Delay1KTCYx(20);
}

main(void)
{
char outchar;
unsigned char Sizevalue1, Sizevalue2, Sizevalue3;
unsigned char index;
#define constant 0x01
#define constant2 0x05

TRISA = 0x00;
TRISD = 0x00;
PORTD = 0x00;

ADCON0 = 0b11000001;

ADCON1 = 0b00001110;

for(;;)
{
ADCON0bits.GO = 1;
(PIR1bits.ADIF == 0);
PORTD = ADRESH;

if(ADRESH < constant)


{
Sizevalue1 = strlen(value1); // get size of array
LCD_EN = 0;
LCD_RS = 0;
LCD_WR = 0;
lcd_init();
LCD_RS = 1;

lcd_goto(set_dd_line1_pos1);
for (index = 0; index < Sizevalue1; index++)
{
outchar = value1[index];
lcd_write_data(outchar);
}
Delay1KTCYx(250);
Delay1KTCYx(250);
Delay1KTCYx(250);
lcd_goto(set_dd_line1_pos1);
PIR1bits.ADIF = 0;
lcd_clear();
}

if(ADRESH > constant2)


{
Sizevalue2 = strlen(value2);
LCD_EN = 0;
LCD_RS = 0;
LCD_WR = 0;
lcd_init();
LCD_RS = 1;

lcd_goto(set_dd_line1_pos1);
for (index = 0; index < Sizevalue1; index++)
{
outchar = value2[index];
lcd_write_data(outchar);
}
Delay1KTCYx(250);
Delay1KTCYx(250);
Delay1KTCYx(250);
lcd_goto(set_dd_line1_pos1);
PIR1bits.ADIF = 0;
lcd_clear();
}
}
}
EXPERIMENT NO. 6

AIM: WAP to display character 'A' on 8*8 LED Matrix

#include <Philips\8xC31-51-80C51Fx-80C51Rx+.h>
Sfr ldata= 0x90; // P1= LCD data pins
Sbit rs – P2.0;
Sbit rw = P2.1;
Sbit en=P2.2;
void main ()
{
Lcdcmd(0x38);
MSDelay(250);
Lcdcmd(0x0E);
MSDelay(250);
Lcdcmd(0x01);
MSDelay(250);
Lcdcmd(0x06);
MSDelay(250);
Lcdcmd(0x86);
MSDelay(250);
Lcddata(‘A’);
}

Void lcdcmd(unsigned char value)


{
Ldata= value;
Rs =0;
Rw=0;
En=1;
MSDelay(1);
En=0;
Return;
}
Void lcddata(unsigned char value)
{
Ldata= value;
Rs =1;
Rw=0;
En=1;
MSDelay(1);
En=0;
Return;
}
Void MSDelay(unsigned char itime)
{
Unsigned int I, j;
For(i=0;i<itime;i++)
{
For(j=0;j<1275;j++);
}
}
EXPERIMENT NO. 7

AIM: WAP to display Date and Time on LCD Module

#include <dos.h>
#include <string.h>
#include <conio.h>
#include <time.h>

#define PORTADDRESS 0x378 /* Enter Your Port Address Here */

#define DATA PORTADDRESS+0


#define STATUS PORTADDRESS+1
#define CONTROL PORTADDRESS+2

void lcd_init(void);
void lcd_write(char char2write);
void lcd_putch(char char2write);
void lcd_puts(char * str2write);
void lcd_goto(int row, int column);
void lcd_clear(void);
void lcd_home(void);
void lcd_cursor(int cursor);
void lcd_entry_mode(int mode);

void main(void)
{

struct time t;
struct date d;
char strtime[17];

textbackground(0);
clrscr();
textcolor(0);
textbackground(10);
gotoxy(8,5);
cputs(" ");
gotoxy(8,4);
cputs(" ");

lcd_init();
lcd_cursor(0);
while(!kbhit())
{

gettime(&t);
getdate(&d);
lcd_goto(0,4);
sprintf(strtime,"%02d:%02d:%02d", t.ti_hour%12, t.ti_min, t.ti_sec);
lcd_puts(strtime);
gotoxy(12,4);
cputs(strtime);

lcd_goto(1,3);
sprintf(strtime,"%02d:%02d:%4d", d.da_day, d.da_mon, d.da_year);
lcd_puts(strtime);
gotoxy(11,5);
cputs(strtime);
delay(200);

}
textbackground(0);
textcolor(7);

void lcd_init()
{

outportb(CONTROL, inportb(CONTROL) & 0xDF);


//config data pins as output

outportb(CONTROL, inportb(CONTROL) | 0x08);


//RS is made high: control (register select)

lcd_write(0x0f);
delay(20);
lcd_write( 0x01);
delay(20);
lcd_write( 0x38);
delay(20);

void lcd_write(char char2write)


{

outportb(DATA, char2write);
outportb(CONTROL,inportb(CONTROL) | 0x01); /* Set Strobe */
delay(2);
outportb(CONTROL,inportb(CONTROL) & 0xFE); /* Reset Strobe */
delay(2);

void lcd_putch(char char2write)


{

outportb(CONTROL, inportb(CONTROL) & 0xF7);


//RS=low: data
lcd_write(char2write);

void lcd_puts(char *str2write)


{

outportb(CONTROL, inportb(CONTROL) & 0xF7);


//RS=low: data
while(*str2write)
lcd_write(*(str2write++));

void lcd_goto(int row, int column)


{

outportb(CONTROL, inportb(CONTROL) | 0x08);


if(row==2) column+=0x40;
/* Add these if you are using LCD module with 4 columns
if(row==2) column+=0x14;
if(row==3) column+=0x54;
*/
lcd_write(0x80 | column);

void lcd_clear()
{

outportb(CONTROL, inportb(CONTROL) | 0x08);


lcd_write(0x01);

void lcd_home()
{
outportb(CONTROL, inportb(CONTROL) | 0x08);
lcd_write(0x02);

void lcd_entry_mode(int mode)


{

/*
if you dont call this function, entry mode sets to 2 by default.
mode: 0 - cursor left shift, no text shift
1 - no cursor shift, text right shift
2 - cursor right shift, no text shift
3 - no cursor shift, text left shift
*/
outportb(CONTROL, inportb(CONTROL) | 0x08);
lcd_write(0x04 + (mode%4));

void lcd_cursor(int cursor)


{

/*
set cursor: 0 - no cursor, no blink
1 - only blink, no cursor
2 - only cursor, no blink
3 - both cursor and blink
*/

outportb( CONTROL, inportb(CONTROL) | 0x08 );


lcd_write( 0x0c + (cursor%4));

}
EXPERIMENT NO. 8

AIM: WAP to Interface DC motor using H-Bridge

#include <Philips\8xC31-51-80C51Fx-80C51Rx+.h>
#include <stdio.h>
#include <standard.h>
#include <macros31.h>
#include <stdlib.h>

/*----------------------Defining SFR bits here------------------------------*/


BIT l_en P1.0;
BIT ldc1 P1.1;
BIT ldc2 P1.2;
BIT rdc1 P1.3;
BIT rdc2 P1.4;
BIT r_en P1.5;

/*----------------------Defining user defined bits here-----------------------*/


bit left_speed;
bit right_speed;
/*----------------------Defining user bytes here-----------------------------*/
unsigned char count1=100;
unsigned char count2=100;
unsigned char count3=200;

unsigned char job=00;


unsigned char job_old=00;

/*----------------------Function declaration---------------------------------*/

void init_timer0();
void init_ex0();
void init_ex1();
void motor_drive();

/* ISR for Timer0--------------------*/


interrupt(INT_TMR0) isr_t0() using 1
{

init_timer0(); //initalise timer0 for 1ms


motor_drive();
}
/* ISR for ex0--------------------*/
interrupt(INT_EXT0) isr_ex0() using 2
{
job=0x03; //left

}
/* ISR for ex0--------------------*/
interrupt(INT_EXT1) isr_ex1() using 2
{
job=0x04; //right
}

void main()
{
init_timer0();
enable_t0(); //enable timer0 int

init_ex0();
init_ex1();

while(1) //infinite loop


{
}
}

void init_timer0()
{
TMOD|=0x01; //Timer0 in mode 1

TH0=0x0d8; //count for 10msec


TL0=0x0ef;
set_hi_t0()
start_timer0();

}
void init_ex0()
{
ex0_edge();
enable_ex0()
count1=50;
count2=50;
}
void init_ex1()
{
ex1_edge();
enable_ex1()
count1=50;
count2=50;
}

void motor_drive()
{ if(job!=job_old)
{
count1=50;
count2=50;
count3=200;
}
job_old=job;

switch(job)
{
case 00: //forward
left_speed=1; //full speed
right_speed=1; //full speed

ldc1=1; //left forward


ldc2=0;
rdc1=1; //right forward
rdc2=0;
break;

case 01: //reverse and forward right


if(count1!=0)
{
left_speed=1; //full speed
right_speed=1; //full speed

ldc1=0; //left reverse


ldc2=1;
rdc1=0; //right reverse
rdc2=1;

count1--;
break;
}

if(count2!=0)
{
l_en=1; //
r_en=1;

ldc1=1; //left forward


ldc2=0;
rdc1=0; //right stoped
rdc2=0;

count2--;
break;
}

job=00;
count1=50;
count2=50;
break;

case 02: //reverse and forward left


if(count1!=0)
{
left_speed=1; //full speed
right_speed=1; //full speed

ldc1=0; //left reverse


ldc2=1;
rdc1=0; //right reverse
rdc2=1;

count1--;
break;
}

if(count2!=0)
{
l_en=1; //
r_en=1;

ldc1=0; //left stoped


ldc2=0;
rdc1=1; //right forward
rdc2=0;

count2--;
break;
}
job=00;
count1=50;
count2=50;
break;

case 03: //reverse and backward left


if(count1!=0)
{

left_speed=1; //full speed


right_speed=1; //full speed

ldc1=0; //left reverse


ldc2=1;
rdc1=0; //right reverse
rdc2=1;

count1--;
break;
}
if(count2!=0)
{
l_en=1; //
r_en=1;

ldc1=0; //left stoped


ldc2=0;
rdc1=0; //right reversed
rdc2=1;

count2--;
break;
}
job=00;
count1=50;
count2=50;
break;

case 04: //reverse and backward left


if(count1!=0)
{

left_speed=1; //full speed


right_speed=1; //full speed

ldc1=0; //left reverse


ldc2=1;
rdc1=0; //right reverse
rdc2=1;

count1--;
break;
}

if(count2!=0)
{
l_en=1; //
r_en=1;

ldc1=0; //left reversed


ldc2=1;
rdc1=0; //right stoped
rdc2=0;

count2--;
break;
}
job=00;
count1=50;
count2=50;
break;

case 05: //backwrd left


if(count3!=0)
{
left_speed=0; //half speed
right_speed=1; //full speed

ldc1=0; //left reversed


ldc2=1;
rdc1=0; //right reversd
rdc2=1;

count3--;
break;
}
job=00;
count3=200;
break;

case 06: //backwrd right


if(count3!=0)
{
left_speed=1; //full speed
right_speed=0; //half speed

ldc1=0; //left reversed


ldc2=1;
rdc1=0; //right reversd
rdc2=1;

count3--;
break;
}
job=00;
count3=200;
break;
default:
l_en=1; //default action
r_en=1;

ldc1=1; //left forward


ldc2=0;
rdc1=1; //right forward
rdc2=0;
break;
}
if(left_speed)
{
l_en=1;
}
else
{
l_en=!l_en;
}

if(right_speed)
{
r_en=1;
}
else
{
r_en=!r_en;
}

}
EXPERIMENT NO. 9

AIM: WAP to Interface Keypad with Microcontroller


#include <Philips\8xC31-51-80C51Fx-80C51Rx+.h>
#include <stdio.h>
#include <standard.h>
#include <macros31.h>
/*----------------------Defining SFR bits here------------------------------*/
BIT sl1 P2.0 //Selects Display1/Row1

BIT sl2 P2.1 //Selects Display2/Row2

BIT sl3 P2.2 //Selects Display3/Row3

BIT sl4 P2.3 //Selects Display4/Row4

BIT krl1 p2.4; //detects key press of Column1

BIT krl2 p2.5; //detects key press of Column2


BIT krl3 p2.6; //detects key press of Column3
BIT krl4 p2.7; //detects key press of Column4

/*----------------------Defining user bits here------------------------------*/


bit key_ready=0; //indicates confirm key press if key_ready=1
bit nkp=0; //indicates confirm key release if nkp=1
bit krl=1; //parameter use to pass return line status
bit start_buzzer=0; //if set buzzer is on

/*----------------------Defining user bytes here-----------------------------*/


unsigned char ds1; //stores ASCII data for display1
unsigned char ds2; //stores ASCII data for display2
unsigned char ds3; //stores ASCII data for display3
unsigned char ds4; //stores ASCII data for display4

unsigned char scan_no=0; //stores Interrupt number


unsigned char key_code; //stores ASCII value of key pressed
unsigned char dcount=32; //Debounce count
unsigned char krcount=31; //key_release count

/*----------------------Defining look up tables here-------------------------*/


unsigned char disp_lut[23]={0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xE6,
0x00,0xff,0x02,0x01,0x0A,0xff,0xff,
0xEE,0x3E,0x9C,0x7A,0x9E,0x8E};
unsigned char key_lut[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
/*----------------------Function declaration---------------------------------*/

void init_timer0();
void init_keypad();
void test_display();
void scanner();
void k();
void get_key();
void key_process();
void key_release();
void buzzer();

/* ISR for Timer0--------------------*/


interrupt(INT_TMR0) isr_t0() using 1
{

init_timer0(); //initalise timer0 for 1ms


buzzer();
scanner(); //I/O driver

void main()
{

init_timer0(); //initialise timer0 for interrupt


init_keypad();
enable_t0(); //enable timer0 interrupt
IP = 0x00 ; //asigns low priority

test_display(); //to glow all segments for 1sec

ds1=ds2=ds3=ds4='9'+3;

while(1)
{
get_key();
key_process();
}

}
void init_timer0()
{
TMOD|=0x01; //Timer0 in mode 1

TH0=0xfc; //count for 1msec


TL0=0x66;

start_timer0();

}
void init_keypad()
{
sl1=sl2=sl3=sl4=1;
krl1=krl2=krl3=krl4=1;
}

void test_display()
{

ds1=ds2=ds3=ds4='9'+1; //clears all segments of ssd

delay_ms(1000);

ds1=ds2=ds3=ds4='9'+2; //glows all segments of ssd

delay_ms(1000);

ds1=ds2=ds3=ds4='9'+1; //clears all segments of ssd

delay_ms(1000);
}

void scanner()
{
switch(scan_no)
{
case 0:

sl1=0; //select display1/Row1


sl2=1;
sl3=1;
sl4=1;

P0=disp_lut[(ds1-'0')]; //gets the pattern by correcting the offset

krl=krl1;
k();

scan_no=1;
break;

case 1:

krl=krl2;
k();

scan_no=2;
break;
case 2:

krl=krl3;
k();

scan_no=3;
break;

case 3:

krl=krl4;
k();

scan_no=4;
P0=0x00; //clears the display
break;

case 4:

sl1=1;
sl2=0; //select display2/Row2
sl3=1;
sl4=1;

P0=disp_lut[(ds2-'0')]; //gets the pattern by correcting the offset

krl=krl1;
k();

scan_no=5;
break;

case 5:

krl=krl2;
k();

scan_no=6;
break;

case 6:

krl=krl3;
k();
scan_no=7;
break;

case 7:

krl=krl4;
k();

scan_no=8;
P0=0x00; //clears the display
break;

case 8:

sl1=1;
sl2=1;
sl3=0; //select display3/Row3
sl4=1;

P0=disp_lut[(ds3-'0')]; //gets the pattern by correcting the offset

krl=krl1;
k();

scan_no=9;
break;

case 9:

krl=krl2;
k();

scan_no=10;
break;

case 10:

krl=krl3;
k();

scan_no=11;
break;

case 11:

krl=krl4;
k();

scan_no=12;
P0=0x00; //clears the display
break;

case 12:

sl1=1;
sl2=1;
sl3=1;
sl4=0; //select display4/Row4

P0=disp_lut[(ds4-'0')]; //gets the pattern by correcting the offset

krl=krl1;
k();

scan_no=13;
break;

case 13:

krl=krl2;
k();

scan_no=14;
break;

case 14:

krl=krl3;
k();

scan_no=15;
break;

case 15:

krl=krl4;
k();

scan_no=0;
P0=0x00; //clears the display
break;

default:
scan_no=0;
break;
}

//detects debounces and checks for key release


//makes key_ready=1,if key press is confirmed
//stores the hex value of key pressed in key_code
//makes nkp=1.if key release is confirmed
void k()
{
if(!key_ready)
//key_ready=0(check for detect and debounce)

//key_ready=1(check for key release)


{

if(dcount==32)
{
if(krl) //checks for
first time key press
goto out_k;
key_code=scan_no;
dcount--;
goto out_k;
}

else
{
if(dcount!=0)
{
dcount--;
goto out_k;
//debounces for 32ms
}

else
{
if(krl)
//checks for key press after debounce
{
dcount=32;
goto out_k;
//spurious key
}
else
{
key_ready=1; //
indicates confirms key press
start_buzzer=1; //puts
buzzer on
dcount=32;
goto out_k;
}
}
}
}
else //key
release part
{

if(krl)
//checks for key release
{
krcount--;
if(krcount!=0)
{
goto out_k;
}
else
{
nkp=1;
//indicates confirm key release
start_buzzer=0; //puts buzzer
off
krcount=31;
goto out_k;
}
}
else
{
krcount=31;
goto out_k;
}
}
out_k:
}

void get_key()
{

while(!key_ready) //waits for key press


{
}
key_code=key_lut[key_code]; //Converts hex key_code into
ASCII

void key_process()
{
ds1=key_code;
key_release();
}

void key_release()
{
while(!nkp) //waits for all key release
{
}
key_ready=0; //starts scanning key pad again by clearing flags
nkp=0;
}

void buzzer()
{
if(start_buzzer) //buzzer starts if flag set
{
P1^=0x20; //generates square wave on P1.5
}
}

You might also like