Sunteți pe pagina 1din 41

UNIT – 3

Logic Controller Interface Description:


Logic Controller Interface comprises of,
- 8 outputs, connected to LED’s. P0 (P0.0 to P0.7) is connected to LED’s through
current limiting resistors. Sending ‘1’ on port pin, LED – on, sending ‘0’ port pin,
LED – off
- 8 inputs, connected to toggle/sliding switches. P1 (P1.0 to P1.7) is connected to
toggle switches through pull up resistors. When switch is kept in On/Open position,
microcontroller receive ‘1’ as input, else ‘0’ is read.

Write an Embedded C Program to read the switches and output the same on LEDs, using
logic controller interface.

#include <reg51.h>
int main(void)
{
P1 = 0xFF ; P0 = 0x00; //Configure P1 & P0 as input and outputs
while(1)
{
P0 = P1;
}
}
Write an Embedded C program to implement Decimal UP / Decimal Down / Ring Counter
using Logic Controller Interface module.

Embedded C Program:
#include <reg51.h>
typedef unsigned char tByte; //8 bits
typedef unsigned int tWord; //16 bits
void delayMs(tWord); //Delay function
sbit key1 = P3^2;
sbit key2 = P3^3;
sbit key3 = P3^4;
int main(void)
{
tByte count=0,i,temp;
tWord delay = 1000; //Delay in milliseconds used for counting
P0 = 0x00; //Clear all LEDs
while(1)
{
/*Program while loop, code in this loop will run continuously. When one of the
keys is pressed, run the appropriate counter and exit back to this loop to check for
key press again. When a key is pressed, the input value to the microcontroller will
be 0.*/

if(key1 == 0)
{
/* Decimal Up counter loop, use a for loop to increment the counting variable
from 0 to 99, and output the number to P0, the output port used for the interface
module.To display as decimal in the leds, first take the first digit of the number,
next take the second digit and set it as the upper nibble by first left shifting it 4
times and then ORing it. */

for(count = 0 ; count <= 99 ; count++)


{
P0 = (count / 10) << 4 | count % 10;
delayMs(delay);
}
P0=0x00; //Turn all LEDs off
}
if(key2 == 0)
{ //Decimal Down counter loop, works similar to the up counting loop, but
//the for loop is used to decrement from 99 to 0
for(count = 99 ; count >= 0 ; count--)
{
P0 = (count / 10) << 4 | count % 10;
delayMs(delay);
}

P0=0x00; //Turn all LEDs off


}
Microcontroller and Embedded Systems Lab [16CS53]

if(key3 == 0)
{
while(1)
{
for(i = 0; i < 8; i++)
{
P0 = 0x01<<i; // 0x01 means 0000 0001 bit pattern
delayMs(delay);
}
}
}
}
}
void delayMs(tWord x)
{

tWord i;
while(x--)
for(i=0;i<120;i++);
}
Microcontroller and Embedded Systems Lab [16CS53]
Write an Embedded C program to read the status of 8 inputs bits from 8bit switch and display FF’
if it is even parity otherwise display 00. Also display number of 1’s in the input data on the LED
outputs, using Logic Controller interface module.

Embedded C Program:

#include<reg51.h>

typedef unsigned char tByte;


typedef unsigned int tWord;

sbit SEL = P1^4;

void delayMs(tWord); //Delay function


tByte readInput(void); //Read 8 bits from input port
tByte countOnes(tByte); //Returns number of 1s in the argument

int main(void)
{
tByte temp,count;
while(1)
{
temp = readInput(); // read the 8 bit data from logic controller
count = countOnes(temp); // count the number of 1's in the 8 bit data

if(count % 2 == 0) // logic to check EVEN or ODD parity


P0 = 0xFF; // display all 1's for EVEN parity
else
P0 = 0x00; // display all 0's for ODD parity

delayMs(1000);
P0 = count; // now display count of 1's for next 1 second
delayMs(1000);
}
}

tByte countOnes(tByte x)
{
tByte i,count = 0;
for(i = 0 ;i < 8 ;i++) // loop to check 8 different bits of a number
{
if(x & (0x01<<i))
count++; // keep incrementing whenever any bit is found as 1
}
return count; //return count of 1's in a given number
}
Microcontroller and Embedded Systems Lab [16CS53]

tByte readInput(void)
{
return P1; //assume P1 is connected to 8 switches

void delayMs(tWord x)
{
tByte i;
while(x--)
for(i=0;i<120;i++);
}
Microcontroller and Embedded Systems Lab [16CS53]
Write an Embedded C program to read the status of two 8-bit inputs (X and Y) and display the
result X*Y using the interface module.

Embedded C Program:

#include<reg51.h>

typedef unsigned char tByte; //8 bits


typedef unsigned int tWord; //16 bits

void delayMs(tWord); //Delay function


tByte readInput(void); //Read 8 bits from input port

sbit SEL = P1^4;


sbit key1 = P3^2;
sbit key2 = P3^3;
sbit key3 = P3^4;

int main(void)
{
tWord a = 0,b = 0,c = 0; //equation is c = a * b
P0 = 0x00; //Clear all LEDs
while(1)
{
if(!key1)
{
/* When key1 is pressed, the variable a is updated with the current value of the
input port. The updated value of a is displayed for half a second. */

a = readInput();
P0 = a;
delayMs(500);
P0 = 0x00;
delayMs(500);
}
if(!key2)
{
/* When key1 is pressed, the variable b is updated with the current value of the
input port. The updated value of b is displayed for half a second. */

b = readInput();
P0 = b;
delayMs(500);
P0 = 0x00;
delayMs(500);
}
Microcontroller and Embedded Systems Lab [16CS53]

if(!key3)
{
/* When key3 is pressed, the result of multiplication of the current values of a and
b is assigned to c. First the LSB of the result is displayed by ANDing the result
with 0xFF .Next the MSB is displayed by right shifting the result 8 times and
writing it to P0. */
c = a*b;
P0 = c & 0xFF;
delayMs(1000);
P0 = c >> 8;
delayMs(1000);
P0 = 0x00;
}
}
}

tByte readInput(void)
{

return P1; // assume P1 is connected to 8 switches

void delayMs(tWord x)
{
tByte i;
while(x--)
for(i=0;i<120;i++);
}
Microcontroller and Embedded Systems Lab [16CS53]

Seven Segment Display Module


Seven segment displays are commonly used, instead of normal LEDs to represent the
data in a more meaningful way. They are available in two types, a)common anode and b)
common cathode. Each digit comes with the 8 pins corresponding to segment LEDs
a,b,c,d,e,f,g,dp. For common anode type, making the corresponding segment pin ‘0’ makes the
segment glow, vice-versa for common cathode type. In the following figure, one seven segment
digit(common anode type) is connected to P0 of 8051.

To display 3, we have to send following bit pattern on P0,


P0 = 0xB0;
DP G F e D c b a
1 0 1 1 0 0 0 0

Program to implement the single digit decimal counter 0-9, using look up table
segment_codes[ ] = {0xC0,0xFA……}; //Store the segment code of 0 to 9 in the look up table
int i;
while (1)
{
for(i=0 ; i<=9 ; i++)
{
P0 = segment_codes[i]; // send the next decimal digit
delay(1000); // delay of 1 second
}
}
Microcontroller and Embedded Systems Lab [16CS53]
When number of seven segment digits is more, using this method requires many ports. Following
circuit solves this problem using set of shift registers. Serial In Parallel Out mode of Shift
Register (74164) is used to send 8 bits of data to seven segment display. Seven segment display
used is of common anode type i.e. we have to send 0 to make corresponding segment ON and 1
to make it OFF.

High

Low
Microcontroller and Embedded Systems Lab [16CS53]

To display 3, we have to send following bit pattern,


DP G f e d c b a
1 0 1 1 0 0 0 0

This is B0 in hexadecimal. To send B0H we have to start sending the bits from MSB onwards i.e
D7 first, D6 next and so on with D0 being the last.

Clock pulses are required to clock in the data, 8 clock pulses for one byte of data. As shift
registers are cascaded, 8*4=32 clocks are required to clock in 4 bytes of data. To send “1234”, first we
have to send ‘1’, then ‘2’,‘3’ and lastly ‘4’. All the shift registers are cascaded, the data is fed to the shift
register using serial in parallel out method. The Data and Clock pins are connected to D0 and D1 of the
output port respectively.
Microcontroller and Embedded Systems Lab [16CS53]
Write an Embedded C program to display messages “FIRE” & “HELP” on 4 digit seven segment
display alternately with a suitable delay.

Embedded C Program:

#include <reg52.h>

typedef unsigned char tByte; //8 bits


typedef unsigned int tWord; //16 bits

sbit DAT = P0^0;


sbit CLK = P0^1;

void delayMs(tWord); //Delay function


void writeSeg(tByte); //Write the 8bit seven segment code to 7segment display

int main(void)
{
int i = 0;
tByte help[4] = {0x89,0x86,0xC7,0x8C};
tByte fire[4] = {0x8E,0xCF,0xAF,0x86};

P0 = 0x00;
while(1)
{
for(i=0;i<4;i++)
writeSeg(help[i]);
delayMs(1000);
for(i=0;i<4;i++)
writeSeg(fire[i]);
delayMs(1000);
}
}
void writeSeg(tByte x)
{
tByte i;
for(i = 0; i < 8; i++)
{
if(x & (0x80>>i)) // extracting and sending the bits one by one
DAT = 1; // from MSB to LSB
else
DAT = 0;
CLK = 0; //generate one clock pulse to push the data to the shift register
CLK = 1;
}
}
Microcontroller and Embedded Systems Lab [16CS53]

Stepper Motor Interface

Stepper motors move in steps unlike dc motors, under the digital control. The term stepper motor resolution
refers the angular movement, in degree per step. Also stepper motors direction of movement can be digitally
controlled.Stepper motors finds application – in disk drives, printers, plotters, CNC machines, robotics etc.

Stepper motors – has two parts a) rotor made up permanent magnet or soft iron b) stator – surrounding the
rotor. Stator is constructed with the number of coils / windings, which on energising (supplying current) acts
like a electromagnet.

As shown in the above diagram rotor (magnet) aligns to a particular position based on the energised coil
(acting as electromagnet) as S & N poles gets attracted. When we change energisation sequence, rotor aligns
to new position, that is how the stepper motors movement is realised. In actual stepper motors – the stator
and rotor poles are teethed to achieve higher resolution (more steps per revolution)

Stepper motors are of three types, based on the principle of construction


a) Permanent magnet SH (rotors are built using permanent magnets)
b) Variable reluctance SH (rotors are built using soft iron and are teethed, each time coils are energised rotor moves to
less reluctance position)
c) Hybrid motors (combination of permanent magnet and variable reluctance types)

Stepping Modes: Stepper motors movement is achieved by employing one of the following coil energising sequences.
a) Full drive (2 coils are energised at a time, more torque) – 4 step sequence
b) Wave drive (one coil only energised at a time, less torque) – 4 step
c) Half drive (here step angle reduces by half, if 1.8” is step angle, here it becomes 0.9”. it is a combination of the
above two types, hence 8 step sequence and torque is in between above types)

Excitation sequence for windings


Clock wise Anticlockwise (wave drive) clock wise (Full drive)
𝐴𝐵𝐶𝐷 𝐴𝐵𝐶𝐷 𝐴𝐵𝐶𝐷
1000 0001 1001
0100 0010 1100
0010 0100 0110
0001 1000 0011
Microcontroller and Embedded Systems Lab [16CS53]

Interfacing with 8051 Microcontroller

 Total number of steps for one revolution = 200 steps (200 teeth shaft) 
Step angle = 360°/200 = 1.8° ; 
𝑎𝑛𝑔𝑙𝑒
𝑠𝑡𝑒𝑝𝑠 =
𝑠𝑡𝑒𝑝 𝑎𝑛𝑔𝑙𝑒
Example1: to rotate stepper motor by 90 degree, requires 90/1.8 = 50 steps.
Example2: rotating 20 steps will result in 25 X 1.8 = 45 degree rotation)

 Speeds: Use appropriate delay in between consequent steps, to achieve different speeds
𝑟𝑝𝑚 𝑥 𝑠𝑡𝑒𝑝𝑠 𝑝𝑒𝑟 𝑟𝑒𝑣
𝑠𝑡𝑒𝑝𝑠 𝑝𝑒𝑟 𝑠𝑒𝑐𝑜𝑛𝑑 =
60
rpm – revolutions per minute

 Driver Circuits: 2Phase, 4winding stepper motor is used and 12v power is required to
drive the stepper motor. Digital input generated by the microcontroller, is used to
drive and control the direction and rotation of stepper motors. As microcontroller ports
do not drive the current required for motor windings, transistors (like SL100) are used to
derive the required current. If it is required to drive bigger/higher torque stepper
motors only change is- use MOSFETS or stepper driver ICs to drive motors instead of
normal transistors.
Microcontroller and Embedded Systems Lab [16CS53]
Write an Embedded C program to rotate stepper motor in clock wise and in anti-clock
wise direction for “N” steps (Number of steps or angle to rotate to be specified)
Embedded C Program:

#include <reg52.h>

typedef unsigned char tByte;


typedef unsigned int tWord;

//name the windings, assume P0 bits 7,6,5,4 are connected to stepper windings
sbit W3 = P0^7;
sbit W2 = P0^6;
sbit W1 = P0^5;
sbit W0 = P0^4;

tByte no_of_steps_clk = 100 ; //number of steps to move in clockwise direction


tByte no_of_steps_anticlk = 100 ;//number of steps to move in anti-clockwise
direction void delayMs(tByte);

main()
{

while(1)
{ W3=1; W2=0; W1=0; W0=0; delayMs(5); if(--no_of_steps_clk==0) break;
W3=0; W2=1; W1=0; W0=0; delayMs(5); if(--no_of_steps_clk==0) break;
W3=0; W2=0; W1=1; W0=0; delayMs(5); if(--no_of_steps_clk==0) break;
W3=0; W2=0; W1=0; W0=1; delayMs(5); if(--no_of_steps_clk==0) break;
}
while(1)
{ W3=0; W2=0; W1=0; W0=1; delayMs(5); if(--no_of_steps_anticlk==0) break;
W3=0; W2=0; W1=1; W0=0; delayMs(5); if(--no_of_steps_anticlk==0) break;
W3=0; W2=1; W1=0; W0=0; delayMs(5); if(--no_of_steps_anticlk==0) break;
W3=1; W2=0; W1=0; W0=0; delayMs(5); if(--no_of_steps_anticlk==0) break;
}
while(1); //end of program, stay here
}

void delayMs(tByte x) //delay in terms of milliseconds(approximate)


{ // delay(1000) will produce 1 sec delay
tWord i;
while(x--)
for(i=0;i<300;i++);
}
Microcontroller and Embedded Systems Lab [16CS53]

DAC INTERFACE

DAC refers to Digital to Analog Converter, used to convert digital values to corresponding analog values.
DAC 0800 – an 8 bit DAC from National semiconductors, with the settling time around 100 n sec. P0 of
8051 is connected to DAC to generated 8 bit digital data,00-FF (refer fig below). Since DAC 08
generates corresponding current output, operation amplifier 741 is used to convert current to analog
voltage, 0-5Volts.
Digital I/P : 00 to FF , corresponding Analog O/P : 0V to 5V
Resolution = (5/256) ≈ 20mV ,An 8 bit DAC has 28 = 256 possible output voltage / current levels, so its resolution is 1
part in 256. IF digital input is 00 to FF is mapped to 0 to 5V o/p, then 20mv is the resolution. (more the number of
bits, better is the resolution)

{ Note:
- Supply voltage +5V at Vcc, V- is connected to – 12 V
- Iout(+) and Iout(–) gives current output corresponding to digital i/p, so op-amp is used to convert the
current o/p to voltage o/p – Vout
- For 8 bit DAC, the o/p current I0 is a function of the binary nos at the data i/p pins D0 – D7
𝐷0 𝐷1 𝐷7
𝐼0 = 𝐼𝑛𝑓 × ( + + − − − ∓ )
256 258 2
Inf – is the ref i/p current, depends on Vref + and vref – Voltages
}

𝟐𝟓𝟔
Calculate digital i/p corresponding to 3V Anlalog o/p – × 𝟑 = 𝟏𝟓𝟑 = (𝟗𝟐)𝑯
𝟓
=1001 0010B
Microcontroller and Embedded Systems Lab [16CS53]
Programs to generate different waveforms using DAC-08:

Two techniques are generally used, one without the look up table and other calculate at run time in the
program. Both the types are discussed below. (c program is used for look up table and assembly for other
type)

Program to generate saw tooth, staircase and triangular waveforms

// saw tooth waveform


unsigned char i;
while(1)
{
for(i=0;i<256;i=i++)
P0 = i ; // output 00-FF and repeat for sawtooth wave form
}
// staircase waveform
unsigned char i;
while(1)
{
for(i=0;i<5;i=i+51)
P0 = i ; // add 51 to get next step 256/5=51
}
// triangular waveform
unsigned char i;
while(1)
{
for(i=0;i<256;i=i++)
P0 = i ; // rising of trinagle

for(i=0;i<256;i=i++)
P0 = 255- i ; // falling of trinagle
}

(Note : by calling delay in between outputing datas to DAC, the frequency / time period of wave forms can be altered)
Microcontroller and Embedded Systems Lab [16CS53]

Generation of sine waveform, using look up table method

In look up table technique, is used when lot of computation is involved in getting the next value to be
outputted to DAC. In the previous programs, it was just addition or subtraction. In case of sine wave form,
sin(angle) is to computed for different angles. Sine function computation by the microcontroller (unlike
normal PCs) may take more and varying times. Hence, what we do is, compute digital values corresponding to
different sine angles and store in the table. At runtime, just take the values from the table and throw these
values to DAC to get accurate waveforms.

Formula for calculation of the sine table entries:


128 + 127 x Sin Ѳ
(128 Corresponds to 80h, i.e. 2.5V, 127 x SIN 90 gives 127, so 128+127 = 255 (for 5v)
Calculate the digital values to be outputted to DAC for angles in the steps of 6o,
127 x sin 0 = 0 127 x sin 48 = 94
127 x sin 6 = 13 127 x sin 54 = 102
127 x sin 12 = 26 127 x sin 60 = 109
127 x sin 18 = 39 127 x sin 66 = 116
127 x sin 24 = 51 127 x sin 72 = 120
127 x sin 30 = 63 127 x sin 80 = 124
127 x sin 36 = 74 127 x sin 86 = 126
127 x sin 42 = 84 127 x sin 90 = 127

Output the above values in the reverse order to get other portion of the top half cycle,
(add 128 for top half cycle, and subtract from 128 for the lower half cycle, refer the table
declaration)
Microcontroller and Embedded Systems Lab [16CS53]
Write an Embedded C program to generate sine waveform/ half rectified sine waveform/
full rectified sine waveform using DAC module.
Program:
#include <reg52.h>

typedef unsigned char tByte;


typedef unsigned int tWord;

//name the keys located on the RV-USBbased8051 Board

sbit key1 = P3^2;


sbit key2 = P3^3;
sbit key3 = P3^4;

// store the following sine tables in code memory

tByte code dac_datas_sine_fullrectified[ ] =


{128+0, 128+13, 128+26, 128+39, 128+51, 128+63, 128+74, 128+84, 128+94, 128+102,
128+109, 128+116, 128+120, 128+124, 128+126, 128+127, 128+126, 128+124, 128+120,
128+116, 128+109, 128+102, 128+94, 128+84, 128+74, 128+63, 128+51, 128+39, 128+26,
128+13};

// total 30 values

tByte code dac_datas_sine_full[ ] =


{128+0, 128+13, 128+26, 128+39, 128+51, 128+63, 128+74, 128+84, 128+94, 128+102,
128+109, 128+116, 128+120, 128+124, 128+126, 128+127, 128+126, 128+124, 128+120,
128+116, 128+109, 128+102, 128+94, 128+84, 128+74, 128+63, 128+51, 128+39, 128+26,
128+13, 128-0, 128-13, 128-26, 128-39, 128-51, 128-63, 128-74, 128-84, 128-94, 128-102,
128-109, 128-116, 128-120, 128-124, 128-126, 128-127, 128-126, 128-124, 128-120, 128- 116,
128-109, 128-102, 128-94, 128-84, 128-74, 128-63, 128-51, 128-39, 128-26,128-13};

// total 60 values

tByte code dac_datas_sine_halfrectified [ ] =


{128+0, 128+13, 128+26, 128+39, 128+51, 128+63, 128+74, 128+84, 128+94, 128+102,
128+109, 128+116, 128+120, 128+124, 128+126, 128+127, 128+126, 128+124, 128+120,
128+116, 128+109, 128+102, 128+94, 128+84, 128+74, 128+63, 128+51, 128+39, 128+26,
128+13, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128};
// total 60 values
Microcontroller and Embedded Systems Lab [16CS53]
main()
{

tByte i=0,j=0,k=0;
key1=key2=key3=1; //configure as inputs

while(1)
{
//full rectified sine waveform

if(key1==0)
while(1) //continuously output the data in the table to the DAC connected to P0
{
P0 = dac_datas_sine_fullrectified[i++];
if(i==30) i=0; // total of 30 digital values are stored in the table to
// produce full rectified sine wave
if(key1==0 || key2==0 || key3==0)break; //check for the key press
};

//full sine waveform

if(key2==0)
while(1)
{
P0 = dac_datas_sine_full[j++];
if(j==60) j=0; // total of 30 digital values are stored in the table to
// produce full sine wave
if(key1==0 || key2==0 || key3==0)break;
}

//half rectified sine waveform

if(key3==0)
while(1)
{ P0 = dac_datas_sine_halfrectified[k++];
if(k==60) k=0; // total of 30 digital values are stored in the table to
// produce half rectified sine wave
if(key1==0 || key2==0 || key3==0)break;
};
}
}
Microcontroller and Embedded Systems Lab [16CS53]
MATRIX KEYBOARD INTERFACE
- One port line is required to interface one key

- [when key is not pressed, port line carries logic 1, ∵it is pulled upto 5V, when
key is pressed, port line gets grounded, hence logic ∅ is applied] . When number of keys increases,
requirement of no. of port. Lines increases, hence concept of matrix arrangement of keys (matrix
keyboard) are used.
Interfacing….
Let us interface 4x4 matrix keyboard to 8051, using P0 and P1 ports, as shown below. Here keys are
place at the intersection of rows and columns, when key is pressed – corresponding row and column
gets shorted and the voltage (logic 0 or 1) of row is transferred to corresponding column.

Working of keyboard and Algorithm to read the keyboard


 If no key is pressed, we will have on columns 0-3, ‘1111’ on P1.3 to P1.0, as all the inputs
are pulled up by pull up resistors.
 If we press any key, let ‘0’ key be pressed, it will short row0 and col0 lines (P0.0 & P1.3),
so whatever data (0 or 1) available at row0 (P0.0) is available at col0 (P1.3). Since
already columns are pulled high, it is required to apply logic ‘0’ to see change in col0
when the key is pressed.
 To identify which key is pressed,
 Step1: Check for a key press in first row by out putting – ‘0111’on row’s, check
which column data is changed, if no key press go for next row
 Step2: Check for a key press in second row by out putting – ‘1011’on row’s, check
which column data is changed, if no key press go for next row
 Step3: Check for a key press in third row by out putting – ‘1101’on row’s, check
which column data is changed, if no key press go for next row
 Step4: Check for a key press in last row by out putting – ‘1110’on row’s, if no key is
pressed go for the first row again (step1) else step5
 Step5: Once the key press is found, use the row number and column number and look
up table to convert the key position corresponding to ascii code. Use appropriate delay
for debouncing. 
 Step6: Wait for the release of the previous key
 Step6: display the key code on leds / send to serial port / return the key code

Microcontroller and Embedded Systems Lab [16CS53]
Key debouncing : In majority of cases, keys used are of mechanical type and it generates / produces
bouncing at its contacts, So by calling delay of 20 msec and rechecking the key value is referred as
debouncing.

Debouncing ( ≃ 20 ms delay) overcomes two things – false / wrong key press identification and single
key press treated as multiple key presses.


Write an Embedded C program to interface 4 X 4 matrix keyboard using lookup table and
display the key pressed on the Monitor.
Program:
#include <reg52.h>

typedef unsigned char tByte;


typedef unsigned int tWord;

// name the rows and columns of 4 x 4 keyboard


sbit row0 = P0^0;
sbit row1 = P0^1;
sbit row2 = P0^2;
sbit row3 = P0^3;
sbit col0 = P1^3;
sbit col1 = P1^2;
sbit col2 = P1^1;
sbit col3 = P1^0;

// key look up table, containing key codes


tByte code keys[4][4] = { {'0','1','2','3'},
{'4','5','6','7'},
{'8','9','a','b'},
{'c','d','e','f'} };

void delayMs(tByte x);

main()
{
tByte row_pos, col_pos;

row0=row1=row2=row3=0; //as outputs


col0=col1=col2=col3=1; //as inputs

//configure the serial port & the timer1 used for 9600 baud generation
SCON = 0x50; TMOD = 0X20; TH1 = -3; TR1 = 1; TI = 1;
Microcontroller and Embedded Systems Lab [16CS53]

while(1)
{ while(1)
{ //select the first row & check for key press in row0
row0=0; row1=1; row2=1; row3=1; row_pos=0;
if(col0==0){col_pos=0;break;}
if(col1==0){col_pos=1;break;}
if(col2==0){col_pos=2;break;}
if(col3==0){col_pos=3;break;}

//select the second row & check for key press in row1
row0=1;row1=0;row2=1;row3=1;
row_pos=1; if(col0==0){col_pos=0;break;}
if(col1==0){col_pos=1;break;}
if(col2==0){col_pos=2;break;}
if(col3==0){col_pos=3;break;}

//select the third row & check for key press in row2
row0=1;row1=1;row2=0;row3=1; row_pos=2;
if(col0==0){col_pos=0;break;}
if(col1==0){col_pos=1;break;}
if(col2==0){col_pos=2;break;}
if(col3==0){col_pos=3;break;}

//select the fourth row & check for key press in row3
row0=1;row1=1;row2=1;row3=0; row_pos=3;
if(col0==0){col_pos=0;break;}
if(col1==0){col_pos=1;break;}
if(col2==0){col_pos=2;break;}
if(col3==0){col_pos=3;break;}
}
delayMs(20); //debounce

/* use the following lines if you want to output the key code on P0 for a second
P0 = keys[row_pos][col_pos]; // output the keycode on P0 for 1sec
delayMs(1000); */

SBUF = keys[row_pos][col_pos]; // output the keycode on serial port, (terminal)

while(col0==0 || col1==0 || col2==0 || col3==0); //wait for the key release


delayMs(20); //debounce
}
}
void delayMs(tWord x) //delay in terms of milliseconds(approximate)
{ // delay(1000) will produce 1 sec delay
tWord i;
while(x--)
for(i=0;i<300;i++);
}
Microcontroller and Embedded Systems Lab [16CS53]

LCD INTERFACE

LCD’s are preferred to seven segment displays because of their versatility and capability
to house more information. 2 line (16x2) is the most popular, low cost character oriented LCD,
suitable for understanding the working and programming of LCD. You have seen LCD modules
used in many of the electronics devices like coin phone, billing machine and weighing machines.
It is a powerful display options for stand-alone systems. Because of low power dissipation, high
readability, flexibility for programmers, LCD modules are becoming popular.

LCD consists of DDRAM, CGROM, Shift registers, bit/pixel drivers, refreshing logics
and lcd controller. The data to be displayed on lcd, is to be written on to the DDRAM-display
data Ram using the ascii format. CGROM-Character generator rom, contains dot/pixel patterns
for every character to be displayed (pre programmed). Shift registers are used to convert
CGROM parallel data to serial data(serializing), drivers are required to drive (ON/OFF) the bits,
refreshing logics are required to hold the display data, as the dots are displayed row by row basis
continuously, like in CRT.
Microcontroller and Embedded Systems Lab [16CS53]

LCD Pins and Interfacing to Microcontroller

LCD provides many control pins, to enable the microcontroller or microprocessor to


communicate, whatever the data we write to LCD is of two types, either it is a command to the
LCD(to configure) or ASCII code of character to be displayed on LCD (to DDRAM). RS signal
is used for this,
RS - 0, writing command byte into command register of LCD
1, writing data (ASCII code) into Data register of LCD
R/W - 0, Write to LCD (Data/Command)
1, Read from the LCD
E - Enable is required to perform the writing/reading to LCD,
E – ‘1’ (for 450nsec) & then ‘0’ (High to Low Pulse)
D0-D7 - It is a bidirectional data bus, used to write data/command to LCD or reading status.
( Let us take following connections, between 8051 and LCD to develop program)
Microcontroller and Embedded Systems Lab [16CS53]

Instruction D7 D6 D5 D4 D3 D2 D1 D0 Description

Clear Clears Display and returns cursor to home


0 0 0 0 0 0 0 1
display position.
Returns cursor to home position. Also
Cursor
0 0 0 0 0 0 1 X returns display being shifted to the original
home
position.

I/D = 0  cursor is in decrement position.


Entry I/D = 1  cursor is in increment position.
0 0 0 0 0 1 I/D S
mode set S = 0  Shift is invisible.
S = 1  Shift is visible

Display D- Display, C- Cursor, B-Blinking cursor


ON- OFF 0 0 0 0 1 D C B 0  OFF
Control 1  ON

S/C = 0  Move cursor.


Cursor/
S/C = 1  Shift display.
Display 0 0 0 1 S/C R/L X X
R/L = 0  Shift left.
Shift
R/L = 1 Shift right.
DL = 0  4 bit
interface. DL = 1  8
Function bit interface.
0 0 1 DL N F X X
Set N = 0  1/8 or 1/11 Duty (1 line).
N = 1  1/16 Duty (2 lines).
F = 0  5x7 dots.
F = 1  5x10 dots.

Programming LCD

Two steps are involved,

1. Configure the LCD (i.e initialization) for different parameters/settings, by writing series of
commands (command bytes) like (refer above table for preparing the commands)
 Function set command(0x38)
 Display On command(0x0C)
 Clear display (0x01)

2. Writing actual string data to LCD, character by character, (by default characters are displayed
from line1 first column position, we can issue DDRAM address command - 0x80 + char pos, for
first line, 0xc0 + char pos, for second line).
Microcontroller and Embedded Systems Lab [16CS53]
Steps to write command to LCD
* Place command byte on data bus
* make RS = 0
* make En = 1 (450 ns) (min) then make En=0 (high to low pulse)

Steps to write data to LCD


* Place data byte(i.e ASCII code) on data bus
* make RS = 1
* make En = 1 (450 ns) (min) then make En=0 (high to low pulse)

Extra Information :
Note: The data to be displayed on LCD, is to be written to the display data RAM using ASCII format,
i.e. if ‘A’ is to be displayed, ASCII code of A. i.e. 65 to be written.
The first 40 bytes (00 – 39 decimal) of RAM allocated for 1st Line,
another 40 bytes (40H – 40Hto 79 decimal) of RAM to 2nd line.

Also first 16 locations are allocated to corresponding 16 display digits of 1st line.
If we want to write to the 4th digit, we have to write to the 4th location in DDRAM.
Even though display shows 16 digits at a time, memory holds 40 characters for each line,
so using shift command we can rotate the display to make all the 40 characters visible.
Microcontroller and Embedded Systems Lab [16CS53]

Write an Embedded C program to display the strings, on 2x16 character LCD.


#include <reg52.h>
#include <intrins.h>

typedef unsigned char tByte;


typedef unsigned int tWord;

//name the LCD pins


sbit RS = P1^4; // 0 - command 1 - data
sbit RW = P1^5; // 0 - write 1 - read
sbit E = P1^6; // 1 to 0, performs writing of command/data

#define LCDData P0

// function prototypes
void LCD_DispStr(tByte line_no,char* str);
void LCD_Init(void);
void LCD_Command(tByte command);
void LCD_Data(tByte databyte);
void enpulse(void);
void delay(tByte val);

main()
{
tByte str1[] = "Hello..RVCE..";
tByte str2[] = ".....CSE. ... ";
//configure the pins
RS=RW=E = 0; // as output
LCDData = 0; // as output
LCD_Init();
LCD_DispStr(1,str1);
LCD_DispStr(2,str2);
while(1); // stay here indefinitely
}
void LCD_DispStr(tByte line_no,char* str)
{
tByte i=0;
if(line_no==1)
LCD_Command(0x80); // command to set the memory ptr to first line
else
LCD_Command(0xc0); // cmd to set the mem ptr to first char of second line
while(str[i]!='\0')
{
LCD_Data(str[i]);i++;
if(i==16)break; // as max of 16 chars per line
}
}
Microcontroller and Embedded Systems Lab [16CS53]
void LCD_Init(void)
{
LCD_Command(0x38); //function set- 2 line display,byte
mode LCD_Command(0x0c); //display on
LCD_Command(0x01); //clear the display
}
void LCD_Command(tByte command) //to send command to the lcd
{
RS=0;
RW=0;
LCDData = command;
enpulse(); // generate enable pulse
delay(50);
}
void LCD_Data(tByte databyte) //to send data to the lcd
{
RS=1; //data is written
RW=0;
LCDData = databyte;
enpulse();
delay(50);
}
void enpulse(void) // to generate enable pulse 1 to 0, on Enable pin
{
E=1;
delay(2);
E=0;
delay(2);
}
void delay(tByte val)
{
tByte i;
for(i=0 ; i<val ; i++)
{ _nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
}
Microcontroller and Embedded Systems Lab [16CS53]
Microcontroller and Embedded Systems Lab [16CS53]

Analog to digital converter (ADC – 0808/9) Interfacing

ADC’s find applications in weight measurement, temp measurement, speed measurement etc.
In general different physical quantities like temp, humidity are converted by sensors into
electrical domain i.e. voltage or current, which in turn fed to ADC for conversion to digital
domain, for doing different types of processing by microcontrollers/microprocessors. ADC’s
are built using different techniques like dual shape conversion, successive approximation type
etc. (since 8051 don’t have internal ADC, external ADC chips are used).

A typical ADC has analog input/s, digital outputs and two handshaking signals.
SOC (Start of conversion): used to start the conversion. (o/p from microcontroller).
EOC (End of Conversion), ADCs take some time to convert from analog to digital. EOC
signal generated by ADC has to polled by microcontrollers to check for completion of
conversion.(i/p to microcontroller).

Interfacing to 8051

Here, ADC0809, a popular unipolar 8 bit successive approximation type ADC, is used to
interface to 8051. This ADC provides 8 analog inputs/channels. One of the 8 inputs, is
selected and used for conversion using channel selection inputs ABC and ALE signal of
ADC.

P0 is connected to digital outputs of ADC, P1.0 & P1.1 connected to SOC and EOC. They
are active high signals. P2.0-P2.2 are connected to channel selection inputs, P1.2 is connected
to ALE.
Microcontroller and Embedded Systems Lab [16CS53]

Timing diagram of signals and Program to read ADC input

Sbit SOC = P1^0;


Sbit EOC = P1^1;
Sbit ALE = P1^2;
Sbit A = P2^0; // CBA – analog channel selection (only one of eight channel to be
selected)
Sbit B = P2^1; // 000 – channel 0, 001 – channel 1, ….,111 – channel 7
Sbit C = P2^2;
Void main( )
{
unsigned char dig_value;
//step1: configure the ports to act as inputs and outpus
SOC=ALE=A=B=C=0; // O/P to Microcontroller
EOC=1; // I/P to Microcontroller

//step2: select the channel , say channel 2 (CBA – 010)


C=0,B=1,A=0;
ALE=0;ALE=1;ALE=0; //send address latch enable signal

//step3: send SOC pulse to start conversion


SOC=0;SOC=1;SOC=0;

//step4: wait for the completion of conversion


while(EOC = = 0); // wait until EOC becomes high

//step5: read ADC output


dig_value = P0; // used for further processing and for display
whiel(1);
}

Resolution of 8 bit ADC: 5V / 28 = 20mv (min of 20mv is required to make one bit change)
For a given analog input, digital value = (256 / 5) * input
Example: calculate the digital output, if input is 2.5V: 256/5 * 2.5 = 128
Microcontroller and Embedded Systems Lab [16CS53]

DC Motor Control

DC motor, unlike stepper motor rotates continuously,


not in steps (measured in rpm – revolutions per minute
ex: 100 rpm). By changing polarity of input voltage
the direction of rotation can be changed. By changing
the input dc voltage (within the range specified by the
manufacturer) the speed of the motor can be changed
(ex: Fan used in CPU cooling, uses dc motor).

Controlling DC motor direction using H-Bridge:

Here 4 switches are used (H – bridge configuration) for direction control

For clockwise rotation:


SW1 & SW4 - ON , SW2 & SW3 - OFF
For anticlockwise rotation:
SW1 & SW4 - OFF , SW2 & SW3 - ON
Microcontroller and Embedded Systems Lab [16CS53]

Write a program to control the direction, if control switch is OFF motor rotates in
clockwise, else rotates in anticlockwise.

sbit key = P3^2;


sbit switch1 = P0^0;
sbit switch2 = P0^1;
sbit switch3 = P0^2;
sbit switch4 = P0^3;
void main( )
{
while(1)
{
if(key== 0) // if key is pressed, it produces 0 on port pin
{ // anti clock wise rotation
switch1=switch4 = 0;
switch2=switch3 = 1;
}
else
{ // clock wise rotation
switch1=switch4 = 1;
switch2=switch3 = 0;
}
}
}

DC Motor speed control: Achieved using PWM (pulse width modulation) by changing
width of the pulse, we can increase / decrease the power to the motor for a given load.

𝑇𝑂𝑁
Effective dc voltage applied to DC motor = × 𝑠𝑢𝑝𝑙𝑙𝑦 𝑣𝑜𝑙𝑡𝑎𝑔𝑒 (𝑠𝑎𝑦 12𝑉)
𝑇

𝑇 1
(if 𝑇𝑂𝑁 = 𝑇, 𝐹𝑢𝑙𝑙 𝑝𝑜𝑤𝑒𝑟 𝑖. 𝑒. 12𝑉, 𝐼𝑓 𝑇𝑂𝑁 = 2 , 50% 𝐷𝐶 (2 𝑝𝑜𝑤𝑒𝑟)

By controlling 𝑇𝑂𝑁 time, effective DC voltage applied to motor is changed, hence the speed.
Microcontroller and Embedded Systems Lab [16CS53]

In the below circuit, 8051 drives the 12V DC motor at different speeds, in one direction.

[Note: Diode across motor (refer above figure)acts as freewheeling diode to achieve faster
switching. Capacitor is used to reduce EMI- electro-magnetic interference. Opto-isolator is
used to isolate EMI produced by motor on controller, so power supply to motor and controller
has to be different.]

Write embedded c program to drive the motor to run in different speeds using PWM.
#include <reg52.h>
#include <intrins.h>
sbit motor = P0^0; // 1- motor on, 0 – motor - off
void main( )
{
unsigned int count1=100,count2=50; // 50 % duty cycle
while(1)
{
motor = 1;
delay(count1);
motor = 0;
delay(count2);
}
}
void delay(tByte val)
{
tByte i;
for(i=0 ; i<val ; i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
}
Note:
count1 = 33, count2 = 67- 33% duty cycle
count1= 70, count2 =30 - 70% duty cycle
Microcontroller and Embedded Systems Lab [16CS53]

Serial port interface to PC

8051 supports full duplex serial asynchronous communication. Serial port i.e UART
(universal asynchronous receiver and transmitter) is built in to the 8051 chip.

(Note: full duplex - both transmission, reception happens simultaneously. Asynchronous -


Clock is not transmitted, generated by transmitter and receiver. Byte wise transmission)

Working of Serial Port – Serial port/UART has two sections, transmitter section and
receiver section. UART transmitter section has parallel in serial out shift register, which
converts parallel 8 bit data to serial data, add start and stop bits (optional parity bit) and send
them out on T X D line at specified baud rate ( programmable) as shown in the below figure.
Adding of start and stop bits are referred as framing of data. Baud rate refers to the rate at
which serial data is transmitted.

UART receiver section has serial in parallel out shift register, which collects serial data
through R X D line, de-frames it by removing START and STOP bits and gives parallel 8 bit
data.

8051 serial port supports many modes of serial communication, but the above shown 10bit is
most popular mode. Generally, data represents ASCII code of the character to be transmitted.
Provision is there to add parity bit (odd/even) for error checking in transmission.

RS 232 : is a popular industry accepted standard for asynchronous serial communication,


among multiple devices, like between microcontroller and PC. RS 232 follows negative
logic and different voltage levels i.e logic ‘1’ means -3 to -25V, logic ‘0’ means- +3 to
+25V unlike TTL (0/5V) supported by the 8051 microcontroller . IBM compatible Personal
Computers provides RS-232 compatible serial ports, referred as COM1 , COM2 etc. Most of
Microcontroller and Embedded Systems Lab [16CS53]

the device/peripherals manufacturers provide RS 232 serial ports. So, to connect 8051 TTL
compatible serial port to RS 232 compatible serial ports, one needs translation device. 8051
can be connected to Rs. 232 ports like PC’s COM port by using RS-232 converters /
translators (TTL to RS-232, vice versa). MAX232 IC is a popular RS-232 converter used in
the industry and their connections are shown below.

Serial port programming :

Step1: Configure the mode and other configurations of serial port using SCON Register.

The SCON is an 8bit SFR register, used to set,


1. Serial mode (Mode 0/1/2)
2. Enable receiver section. (REN – 1 enable, 0 – disable)
3. TI & RI flags (Transmit & Receiver Interrupt flags) : are provided to establish
synchronisation between transmitter and receiver. These flags are set by serial port hardware
automatically. While sending the data, programmer has to check the status of TI flag. When
TI is 0, transmitter is busy transmitting previous character.
TI is 1, transmitter is successfully transmitted previous character and we can transmit
next character. Make TI equal to 0, after writing new character.
While receiving the data, programmer has to look at the RI flag, to check the arrival of data.
If RI is 1, receiver has received the data. After reading the data, make RI equal to 0.
If serial port interrupt is enabled, interrupt is generated whenever TI or RI is set.

Mode1 (10 bit mode- 1start,8 data, 1stop, with programmable baud rate), is very commonly
used to communicate with the PC. To configure in Mode1 and enable receiver section, write
MOV SCON, # 50H (in Assembly)
Or
SCON = 0x50; (in C)
Microcontroller and Embedded Systems Lab [16CS53]

Step 2: Baud Rate - Generate Rx & Tx clock using timer1 (mode 2 – 8 bit auto reload)

In 8051, whenever serial port is used, tranmit/recive clock is generated internally to


send/receive the data serially. Timer 1 is used internally to generate this clock. Timer 1 is
programmed in Mode 2, to generate continuous clock without the programmer intervention.
Mode2 is called as 8 bit auto reload mode, only TL1 is used for counting. TH1 is used to hold
the initial value and this value is copied to TL1 as soon as TL1 overflows. When serial port is
used, the clock input to timer1 is further divided by %32. Crystal frequency has to be
11.059MHz to achieve, industry standard baud rates like 9600. After %12 and %32 clock
input to timer1 becomes 28,800Hz. Now this frequency can be further divided by loading
proper values in to timer1 , TH1, which is acting like a % by N counter.

Let us say, to produce 9600 baud ( bits per second), 28800 has to be divided by 3
28800 / 9600 = 3, hence the timer 1 should over flow after every 3 clock pulses.
Hence, TH1 is to be loaded with,
TH1 = 0x FD ; // FF – 3 = FC + 1 = FD ( 255 – 3 = 252+1 = 253 i.e 0xFD)
Or
TH1 = -3; (in C, -3 is automatically converted and stored as FD, 2’s compliment)

C Program to generate 9600 baud:


TMOD = 0x20 ; // Timer 1 in Mode 2
TH1 = -3; // or 0xFD
TR1 = 1; // start the timer to generate transmit/receive clock

Step 3: Send or Receive the data.

SBUF is used for both receiving and transmitting. (It is designed such that, when we write to
SBUF, it goes to Tx section, when we read from SBUF, it comes from Rx section.
TI indicates, Tx is ready for transmitting next character (in polling we have to make it zero
and then write next character, in interrupt method it is automatically cleared by RETI
Microcontroller and Embedded Systems Lab [16CS53]

instruction ). RI indicates, Rx is ready with the data, i.e. it has received an byte of (in polling
we have to make it zero and then wait for receiving the next character, in interrupt method it
is automatically cleared by RETI instruction).
Write a program to send a string to PC using serial port

#include <reg52.h>
void main( )
{
char str[20] = “rvce cse”;
unsigned char i=0;
SCON = 0X50; // 10 BIT MODE – 1START,8DATA,1STOP
TMOD = 0X20;TH1= -3;TR1=1; - SET TIMER1 FOR 9600 BAUD
TI=1;
while( str[i] != ’\0’ )
{
while(TI==0); // wait for transmitter to complete the previous operation
SBUF = str[i++]; // transmit the next character
TI = 0 ; // CLEAR MANUALLY TI TO ‘0’
}
}

Write a program to receive a string from PC

#include <reg52.h>
void main( )
{
char str[20]; // space to store the string, received from serial port
unsigned char i=0;
SCON = 0X50; // 10 BIT MODE – 1START,8DATA,1STOP
TMOD = 0X20;TH1= -3;TR1=1; - SET TIMER1 FOR 9600 BAUD

do
{
while(RI==0); // wait for receiver to receive the character
str[i] = SBUF; // read the received character
RI = 0 ; // CLEAR MANUALLY TI TO ‘0’
}
while(str[i++]!=’\0’); // terminate the loop if NULL character is received
while(1);
}
Microcontroller and Embedded Systems Lab [16CS53]

Interfacing High power devices using Relays

Microcontroller port pin cannot be directly used to switch ON/OFF (control) high power
ac or dc devices like bulb, fan, dc motor, solenoids etc. as the port pins don’t drive the
required high current or voltages required by high power devices.

Relays are used to interface high power devices to microcontrollers. There principle of
working is shown in the below figure. The microcontroller port pins drives the Relay
input section, where as its output section is connected to high power device. Hence,
relays provide isolation between microcontroller and high power source.

Relays are of two types


a) Electromechanical Relay – cheap, less reliable (not durable) movable ports, relay
driver required
b) Solid State Relay – costly, reliable (durable), no moving parts, no relay driver

Interface AC device (like bulb) to Microcontroller using relay

When P0.0 is logic ‘0’


- Relay Coil connected to +12V not energised (do not conduct) and hence no contact
between common terminal and NO and bulb is OFF.
When P0.0 is logic ’1’
- Coil is energised, connection establishes between common terminal and NO, and
bulb is ON.
Microcontroller and Embedded Systems Lab [16CS53]

Interfacing Industrial sensor using opto-isolator

Opto-isolator, as shown in the fig, has photodiode and


photo transistor, When diode conducts, it emits light and
the transistor conducts.

It provides complete isolation between diode and transistor. Hence, input circuit which
drives the diode do not get affected by the voltage/ current spikes produced in the o/p
circuit. Also opto-isolators can be sued to interface devices (like sensors) working at
different voltage levels to Microcontroller.

Use of Opto-isolator to interface Inductive proximity sensor: Capacitive / Inductive


proximity sensors are most commonly used in the industrial applications, these sensors
has inbuilt electronics and comes with 3 leads,( two for power supply, one for sensor
output)

When metal object comes to the proximity of the sensor, it detects and generates logic 1
output. For the sensor to work, it needs dc supply (+5 to +30V).

Write a program to read sensor connected to P0.1 and make ac device (bulb) ON/OFF
co connected to P0.0 through relay.

#include <reg52.h>
Sbit SENSOR = P0^1;
Sbit RELAY = P0^0;
Microcontroller and Embedded Systems Lab [16CS53]

void main( )
{
while(1)
{
if(SENSOR == 1)
RELAY = 1;
else
RELAY = 0;
}
}

S-ar putea să vă placă și