Thursday 23 October 2014

Multiprocessor Communication Using 8051 Microcontroller

   
        8051 Has Serial -Universal Asynchronous Transiever(UART) i.e it works in Full Duplex Mode

          The register SBUF is used to hold the data. The special function register SBUF is physically two registers. One is, write-only and is used to hold data to be transmitted out of the 8051 via TXD. The other is, read-only and holds the received data from external sources via RXD. Both mutually exclusive registers have the same address 099H.

SCON REGISER:


SM0
SM1
SM2
REN
TB8
RB8
TI
RI



       SM0 SM1

MODE 0  0    0    SHIFT REGISTER(BAUDRATE IS 1/12 OF OSC FREQ)

MODE 1  0    1    10-BIT UART(DETERMINED BY TIMER 1) 

MODE 3  1    0    11-BIT UART(1/32,1/64) 

MODE 3  1    1    11-BIT UART(DETERMINED BY TIMER 1)


SM2-MULTIPROCESSOR COMMUNICATION ENABLE BIT



Mode-3 - Multi processor mode with variable baud rate :

In this mode 11 bits are transmitted through TXD or received through RXD. The various bits are: a start bit (usually ‘0'), 8 data bits (LSB first), a programmable 9 th bit and a stop bit (usually ‘1').
Mode-3 is same as mode-2, except the fact that the baud rate in mode-3 is variable (i.e., just as in mode-1).
baud = (2 SMOD /32) * ( fosc / 12 (256-TH1)) .
This baudrate  holds when Timer-1 is programmed in Mode-2.

Operation in Multiprocessor mode :

8051 operates in multiprocessor mode for serial communication Mode-2 and Mode-3. In multiprocessor mode, a Master processor can communicate with more than one slave processors. The connection diagram of processors communicating in Multiprocessor mode is given in fig 12.1.
The Master communicates with one slave at a time. 11 bits are transmitted by the Master, viz, One start bit (usually ‘0'), 8 data bits (LSB first), TB8 and a stop bit (usually ‘1'). TB8 is ‘1' for an address byte and ‘0' for a data byte.
If the Master wants to communicate with certain slave, it first sends the address of the slave with TB8=1. This address is received by all the slaves. Slaves initially have their SM2 bit set to ‘1'. All slaves check this address and the slave who is being addressed, responds by clearing its SM2 bit to ‘0' so that the data bytes can be received.It should be noted that in Mode 2&3, receive interrupt flag RI is set if REN=1, RI=0 and the following condition is true.
  1. SM2=1 and RB8=1 and a valid stop bit is received. Or
  2. SM2=0 and a valid stop bit is received.
 8051  in Multiprocessor Communication
After the communication between the Master and a slave has been established, the data bytes are sent by the Master with TB8=0. Hence other slaves do not respond /get interrupted by this data as their SM2 is pulled high (1).


SOURCE CODE FOR MULTIPROCESSOR COMMUNICATION MASTER MODE


#include<lcd.h>
void tx_delay(int);
void transmit_string(char *);
void transmit_addr(unsigned char);
void main()
{
char *r1="MASTER:TX TO";
char *r2="SLAVE ONE RCVING...";
char *r3="SLAVE TWO RCVING...";
TMOD=0X21;
SCON=0XF0;
TH1=0XFD;
TR1=1;
init_8bit();
hide_cursor;
string_8bit(r1);
 while(1)
 {
 xy_8bit(1,0);
 string_8bit("SLAVE2");
 transmit_addr(0x32);
 tx_delay(100);
 transmit_string(r2);
 tx_delay(100);
 xy_8bit(1,0);
 string_8bit("SLAVE1");
 transmit_addr(0x31);
 tx_delay(100);
 transmit_string(r3);
 tx_delay(100);
 }
}

void transmit_string(char *s)
{
TB8=0;
while(*s!='\0')
{
SBUF=*s;
while(TI==0);
TI=0;
s++;
tx_delay(50);
}
SBUF=0x01;
while(TI==0);
TI=0;
tx_delay(50);
}

void transmit_addr(unsigned char adr)
{
TB8=1;
SBUF=adr;
while(TI==0);
TI=0;
tx_delay(50);
}

void tx_delay(int val)
{
int i,j;
for(i=0;i<val;i++)
{
for(j=0;j<500;j++)
{;}
}
}



SOURCE CODE FOR MULTIPROCESSOR COMMUNICATION SLAVE 1


#include<lcd.h>
const unsigned char my_addr=0x31;
char slave1;
sbit comp=P1^7;
void tx_delay(int);
int i;
void main()
{
char *r1="SLAVE 1";
TMOD=0X21;
SCON=0XF0;
TH1=0XFD;
TR1=1;
init_8bit();
hide_cursor;
string_8bit(r1);
xy_8bit(1,0);
IE=0x90;
 while(1)
 {
 comp=1;
tx_delay(100);
comp=0;
 }
}

void ser_int()interrupt 4
{

if(RI==1)
{
if(SBUF==my_addr)
{
slave1=my_addr;
SM2=0;
clear_8bit(2,1);
cmd_8bit(0xc0);
}
else if(SBUF==0x01)
{
for(i=1;i<=16;i++)
{
clear_8bit(2,i);
}
cmd_8bit(0xc0);
SM2=1;
}
else if(slave1==my_addr){
 disp_8bit(SBUF);
}
RI=0;
}


void tx_delay(int val)
{
int i,j;
for(i=0;i<val;i++)
{
for(j=0;j<500;j++)
{;}
}
}


SOURCE CODE FOR MULTIPROCESSOR COMMUNICATION SLAVE 2



#include<lcd.h>
const unsigned char my_addr=0x32;
char slave2;
sbit comp=P1^7;
void tx_delay(int);
int i;
void main()
{
char *r1="SLAVE 2";
TMOD=0X21;
SCON=0XF0;
TH1=0XFD;
TR1=1;
init_8bit();
hide_cursor;
string_8bit(r1);
xy_8bit(1,0);
IE=0x90;
 while(1)
 {
 comp=1;
tx_delay(100);
comp=0;
 }
}

void ser_int()interrupt 4
{
if(RI==1)
{
if(SBUF==my_addr)
{
slave2=my_addr;
SM2=0;
clear_8bit(2,1);
cmd_8bit(0xc0);
}
else if(SBUF==0x01)
{
for(i=1;i<=16;i++)
{
clear_8bit(2,i);
}
cmd_8bit(0xc0);
SM2=1;
}
else if(slave2==my_addr){
 disp_8bit(SBUF);
}
RI=0;
}


void tx_delay(int val)
{
int i,j;
for(i=0;i<val;i++)
{
for(j=0;j<500;j++)
{;}
}
}




Scrolling Any one Row of a 16X2 LCD Display



        Since there is no predefined libraries to rotate a single row of an LCD we need to do it with our own functions. 

        I have written such function using this function u can

  • Rotate any of the two row
  • Rotate left or right


A sample program and its header file is given below 

 #include<lcd.h>
void main()
{
char *r1="LCD ROW ONE";
char *r2="LCD ROW TWO";
init_8bit();
hide_cursor;
string_8bit(r1);
xy_8bit(1,1);
string_8bit(r2);
clear_8bit(0,0);                //clear_8bit(row,column)
delay(100);
 while(1)
 {
  rotate(r2,1,'r'); //rotate("string",which row(0,1),which dir('r' ||'l'))
 }
}

The Source code requires  <lcd.h>  header file  which is defined below


#include<reg51.h>
#include<string.h>
#define hide_cursor cmd_8bit(0x0c)
#define interface_8bit
sbit RS=P3^3;
sbit RW=P3^4;
sbit EN=P3^5;
sfr lcdport=0x90;
void cmd_8bit(unsigned char);
void disp_8bit(unsigned char);
void xy_8bit(unsigned char,unsigned char);
void clear_8bit(unsigned char,unsigned char);
void rotate(char *,unsigned char ,unsigned char );
void rotate_right(char *,unsigned char);
void rotate_left(char *,unsigned char);
void cmd_4bit(unsigned char);
void disp_4bit(unsigned char);
void xy_4bit(unsigned char,unsigned char);
void delay(unsigned char);
void init_8bit();
void init_4bit();
void string_8bit(char *);
#ifdef interface_8bit
void cmd_8bit(unsigned char c)
{
lcdport=c;
RS=0;
RW=0;
EN=1;
delay(1);
EN=0;
}

void disp_8bit(unsigned char d)
{
lcdport=d;
RS=1;
RW=0;
EN=1;
delay(1);
EN=0;
}

void string_8bit(char *s)
{
while(*s!='\0')
{
disp_8bit(*s);
s++;
}
}


void init_8bit()
{
cmd_8bit(0x38);
cmd_8bit(0x0e);
cmd_8bit(0x80);
cmd_8bit(0x06);
cmd_8bit(0x01);
}
void xy_8bit(unsigned char r,unsigned char c)
{
if(r==0)
cmd_8bit(0x80+r);
else
cmd_8bit(0xc0+c);
}
 void clear_8bit(unsigned char r,unsigned char c)
 {
   if(r)
   {
   cmd_8bit(0x80+(r-1));
   disp_8bit(' ');
   }
   if(c)
   {
   cmd_8bit(0xc0+(c-1));
   disp_8bit(' ');
   }
 }

  void rotate(char *s,unsigned char r,unsigned char dir)
  {
  unsigned char row;
  char *space="                ";
  char result_string[50];
  strcpy(result_string,space);
  strcat(result_string,s);
  strcat(result_string,space);
  if(r==0)
  row=0x80;
  else
  row=0xc0;
  if(dir=='r')
  rotate_right(result_string,row);
  else
  rotate_left(result_string,row);
  }

  void rotate_right(char *s,unsigned char row)
  {
  int i;
   for(i=0;i<(strlen(s)+1);i++)
 {
  cmd_8bit(row);
  string_8bit(s+i);
  delay(1);
  }
  }

  void rotate_left(char *s,unsigned char row)
  {
  int i;
   for(i=0;i<(strlen(s)+1);i++)
 {
  cmd_8bit(row);
  string_8bit(s+strlen(s)-i);
  delay(1);
  }
  }
 #else
void init_4bit()
{
cmd_4bit(0x02);
cmd_4bit(0x28);
cmd_4bit(0x0E);
cmd_4bit(0x80);
cmd_4bit(0x06);
}

void cmd_4bit(unsigned char c)
{
RS=0;
lcdport=(c&0xf0);
EN=1;
delay(100);
EN=0;
lcdport=(c&0x0f)<<4;
EN=1;
delay(100);
EN=0;

}

void disp_4bit(unsigned char d)
{
RS=1;

lcdport=d&0xF0;
EN=1;
delay(100);
EN=0;
lcdport=(d&0x0F)<<4;
EN=1;
delay(100);
EN=0;

}

void string_4bit(char *s)
{
RS=1;
while(*s!='\0')
{
disp_4bit(*s);
s++;
}
}

void xy_4bit(unsigned char r,unsigned char c)
{
if(r==0)
cmd_4bit(0x80+c);
else
cmd_4bit(0xc0+c);
}

#endif
void delay(unsigned char d)
{
int i;
TMOD=0x01;
for(i=0;i<d;i++)
{
TH0=0xee;
TL0=0x00;
TR0=1;
while(TF0==0);
TR0=0;
TF0=0;
 }
}


     If there is any updation with my code please let me know
through your comments