As 8051 Microcontroller is concerned, we all know that Its a Microcontroller in which we program our code and make it work. The 8051 microcontroller, I have used in this post is AT89C51. I have also designed this project on hardware and have tested code and it works fine. The crystal oscillator I have used in this project is of 16MHz. You can also download the Proteus Simulation along with programming code and hex file designed in keil uvision 3, at the end of this post. So, now let's get started with it. You may also wanna read the below projects on 8051 Microcontroller:
#include<reg51.h>
void cct_init(void);
void delay(int);
void DisplayOn7Segment(char);
int main(void)
{
   char ch = '0';	          // Character to be displayed on 7seg
   cct_init();   	          // Make all ports zero	
   while(1)           
   {
	DisplayOn7Segment(ch);	  // Display ch on 7seg
	delay(30000);			  // About 1 sec delay
	switch(ch)				  // Update ch with new value to be displayed
	{
		case '0':	ch = '1';  break;
		case '1':	ch = '2';  break;
		case '2':	ch = '3';  break;
		case '3':	ch = '4';  break;
		case '4':	ch = '5';  break;
		case '5':	ch = '6';  break;
		case '6':	ch = '7';  break;
		case '7':	ch = '8';  break;
		case '8':	ch = '9';  break;
		case '9':	ch = '0';  break;
	
	
		default: ch = '0';  break;
	}
   }
}
void cct_init(void)
{
	P0 = 0x00;   
	P1 = 0x00;   
	P2 = 0x00;   
	P3 = 0x00;  
}
void delay(int a)
{
   int i;
   for(i=0;i<a;i++);   //null statement
}
void DisplayOn7Segment(char ch)   // ch can have a value from '0' to 'F' only
{
	switch(ch)
	{
		case '0':	P2 = 0x3F;  break;
		case '1':	P2 = 0x06;  break;
		case '2':	P2 = 0x5B;  break;
		case '3':	P2 = 0x4F;  break;
		case '4':	P2 = 0x66;  break;
		case '5':	P2 = 0x6D;  break;
		case '6':	P2 = 0x7D;  break;
		case '7':	P2 = 0x07;  break;
		case '8':	P2 = 0x7F;  break;
		case '9':	P2 = 0x6F;  break;
	
		default: P2 = 0x3F;  break;
	}	
}
That's all for today, I hope now you can quite easily interface this seven segment display with 8051 Microcontroller. In the next post, we will have a look at some new project with 8051 Microcontroller. So, till then take care and have fun !!! :)
So, before going in details of this project, let me first tell you that its not free because we have done quite a lot of work in designing it so it will be of $20. We have placed quite a small amount as mostly it will be downloaded by the engineers students.You can download it by clicking the above button, but before buying it must read the details and also check the video posted at the end of this tutorial so that you know what you are buying. So, let's get started with the details of this project.
void writeline_lcd(char line[])
{
   		int i;
   		for(i=0;i<strlen(line);i++)
   		{ writedata(line[i]); } //write to lcd
   
}
void writeline_serial(char line1[])
{  
   int i;
   EA = 0; ES = 0;
   for(i=0;i<strlen(line1);i++)
   { SendByteSerially(line1[i]); } // SEND DATA TO PC 
   EA = 1; ES = 1;
}
void Ask_Question(void)
{
	int q = 13;
	writecmd(0x01);
	
	//randomize question
	while(!(q<7 & q>-1))
	{
		q = (TL1%6);
		if(q1==1 & q==1)  { q = 6; }
		if(q2==1 & q==2)  { q = 4; }
		if(q3==1 & q==3)  { q = 5; }
		if(q4==1 & q==4)  { q = 6; }
		if(q5==1 & q==5)  { q = 2; }
		if(q6==1 & q==6)  { q = 3; }
	}
	switch(q)
	{
	case 1:  q1=1; writeline_lcd("3,8,15,24,35..."); newline2(); writeline_lcd("51  48  46  42"); Return();
			 if(mode=='1') { writeline_serial("3,8,15,24,35...   options are (1)51  (2)48  (3)46  (4)42"); } break;
	case 2:  q2=1; writeline_lcd("6,14,18,28,30..."); newline2(); writeline_lcd("32  46  42  28"); Return();
			 if(mode=='1') { writeline_serial("6,14,18,28,30...   options are (1)32  (2)46  (3)42  (4)28"); } break;
	case 3:  q3=1; writeline_lcd("4, 1, 0, 1, 4..."); newline2(); writeline_lcd("1   3   9   0"); Return();
			 if(mode=='1') { writeline_serial("4, 1, 0, 1, 4...   options are (1)1  (2)3  (3)9  (4)0"); } break;
	case 4:  q4=1; writeline_lcd("-1, 4, 1, 6, 3..."); newline2(); writeline_lcd("8   10   5   7"); Return();
			 if(mode=='1') { writeline_serial("-1, 4, 1, 6, 3...   options are (1)8  (2)10  (3)5  (4)7"); } break;
	case 5:  q5=1; writeline_lcd("10,21,33,46,60..."); newline2(); writeline_lcd("88   73   65   75"); Return();
			 if(mode=='1') { writeline_serial("10,21,33,46,60...   options are (1)88  (2)73  (3)65  (4)75"); } break;
	case 6:  q6=1; writeline_lcd("1-1+1-1+...inf=?"); newline2(); writeline_lcd("0   1   1/2   -1"); Return();
			 if(mode=='1') { writeline_serial("1-1+1-1+...inf=?   options are (1)0  (2)1  (3)1/2  (4)-1"); } break;
	}
	
	q_no = q;
}
In the coming posts, I am gonna share more exciting libraries for Proteus as I have already started designing the Arduino Nano board in Proteus, which will be the talk of our next tutorial hopefully. We all know about Arduino Mega 2560 board which is quite bigger version of Arduino UNO board and uses Atmega2560 Microcontroller. In the below post, I have first given the link to download Arduino Mega Library and afterwards I have explained How to use Arduino Mega board in Proteus by designing a simple blinking LED circuit as we did for Arduino UNO simulation in Proteus. So, let's get started with it.
I have added all the Arduino boards in a single library. This library contains six Arduino boards which are Arduino UNO, Arduino Mega 2560, Arduino Mega 1280, Arduino Nano, Arduino Mini and Arduino Pro Mini. You can download this complete Arduino Library by checking Arduino Library for Proteus.
Actually we have already understood the working of both keypad and LCD so I thought to share this small project as it will give you the practical application of both keypad and LCD. And if you are new to 8051 Microcontroller then its always better to first design a small project and then move to pro one. The Simulation file along with hex file and complete code is given at the end for download. But my suggestion is to design it by yourself as it will help you in learning. You will do mistakes but obviously it will help you in learning so make mistakes and learn with it. So, let's get started with it.
while(1)
   { 
     //get numb1
     key = get_key();
     writecmd(0x01);            //clear display
	 writedata(key);            //Echo the key pressed to LCD
	 num1 = get_num(key);       //Get int number from char value, it checks for wrong input as well
     
	 if(num1!=Error)            //if correct input then proceed, num1==Error means wrong input
	 {
		 //get function
		 key = get_key();
		 writedata(key);                  //Echo the key pressed to LCD
		 func = get_func(key);            //it checks for wrong func
		 
		 if(func!='e')                    //if correct input then proceed, func=='e' means wrong input
		 {
			 //get numb2
			 key = get_key();
			 writedata(key);              //Echo the key pressed to LCD
			 num2 = get_num(key);         //Get int number from char value, it checks for wrong input as well
			 
			 if(num2!=Error)              //if correct input then proceed, num2==Error means wrong input
			 {
				 //get equal sign
				 key = get_key();
				 writedata(key);          //Echo the key pressed to LCD
				 
				 if(key == '=')           //if = is pressed then proceed
				 {
					 switch(func)         //switch on function
					 {
					 case '+': disp_num(num1+num2); break;
					 case '-': disp_num(num1-num2); break;
					 case 'x': disp_num(num1*num2); break;
					 case '/': disp_num(num1/num2); break;
					 }
				 }
				 else				      //key other then = here means error wrong input
				 { 
					 if(key == 'C')       //if clear screen is pressed then clear screen and reset
						writecmd(0x01);   //Clear Screen
					 else
						DispError(0); 	  //Display wrong input error
				 }                                 
			 }
		 }
     }
   }
#include<reg51.h>
#include<string.h>
//Define Macros
#define Error  13    // Any value other than 0 to 9 is good here
//Function declarations
void cct_init(void);
void delay(int);
void lcdinit(void);
void writecmd(int);
void writedata(char);
void writeline(char[]);
void ReturnHome(void);
char READ_SWITCHES(void);
char get_key(void);
int get_num(char);
char get_func(char);
void DispError(int);
void disp_num(int);
void WebsiteLogo();
//*******************
//Pin description
/*
P2 is data bus
P3.7 is RS
P3.6 is E
P1.0 to P1.3 are keypad row outputs
P1.4 to P1.7 are keypad column inputs
*/
//********************
// Define Pins
//********************
sbit RowA = P1^0;     //RowA
sbit RowB = P1^1;     //RowB
sbit RowC = P1^2;     //RowC
sbit RowD = P1^3;     //RowD
sbit C1   = P1^4;     //Column1
sbit C2   = P1^5;     //Column2
sbit C3   = P1^6;     //Column3
sbit C4   = P1^7;     //Column4
sbit E    = P3^6;     //E pin for LCD
sbit RS   = P3^7;     //RS pin for LCD
// ***********************************************************
// Main program
//
int main(void)
{
   char key;                     //key char for keeping record of pressed key
   int num1 = 0;                 //First number
   char func = '+';              //Function to be performed among two numbers
   int num2 = 0;                 //Second number
   
   cct_init();                   //Make input and output pins as required
   lcdinit();                    //Initilize LCD
   WebsiteLogo();
   while(1)
   { 
     WebsiteLogo();
     //get numb1
     key = get_key();
     writecmd(0x01);            //clear display
	 WebsiteLogo();
	 writedata(key);            //Echo the key pressed to LCD
	 num1 = get_num(key);       //Get int number from char value, it checks for wrong input as well
     
	 if(num1!=Error)            //if correct input then proceed, num1==Error means wrong input
	 {
		 //get function
		 key = get_key();
		 writedata(key);                  //Echo the key pressed to LCD
		 func = get_func(key);            //it checks for wrong func
		 
		 if(func!='e')                    //if correct input then proceed, func=='e' means wrong input
		 {
			 //get numb2
			 key = get_key();
			 writedata(key);              //Echo the key pressed to LCD
			 num2 = get_num(key);         //Get int number from char value, it checks for wrong input as well
			 
			 if(num2!=Error)              //if correct input then proceed, num2==Error means wrong input
			 {
				 //get equal sign
				 key = get_key();
				 writedata(key);          //Echo the key pressed to LCD
				 
				 if(key == '=')           //if = is pressed then proceed
				 {
					 switch(func)         //switch on function
					 {
					 case '+': disp_num(num1+num2); break;
					 case '-': disp_num(num1-num2); break;
					 case 'x': disp_num(num1*num2); break;
					 case '/': disp_num(num1/num2); break;
					 }
				 }
				 else				      //key other then = here means error wrong input
				 { 
					 if(key == 'C')       //if clear screen is pressed then clear screen and reset
					 {
					    writecmd(0x01);   //Clear Screen
						WebsiteLogo();
					 }
					 else
					 {
					 	DispError(0); 	  //Display wrong input error
						WebsiteLogo();
					 }
				 }                                 
			 }
		 }
     }
   }
}
void WebsiteLogo()
{
   writecmd(0x95);
   writedata('w');                                 //write
   writedata('w');                                 //write
   writedata('w');                                 //write
   writedata('.');                                 //write
   writedata('T');                                 //write
   writedata('h');                                 //write
   writedata('e');                                 //write
   writedata('E');                                 //write
   writedata('n');                                 //write
   writedata('g');                                 //write
   writedata('i');                                 //write
   writedata('n');                                 //write
   writedata('e');                                 //write
   writedata('e');                                 //write
   writedata('r');                                 //write
   writedata('i');                                 //write
   writedata('n');                                 //write
   writedata('g');                                 //write
 
   writecmd(0xd8);
 
   writedata('P');                                 //write
   writedata('r');                                 //write
   writedata('o');                                 //write
   writedata('j');                                 //write
   writedata('e');                                 //write
   writedata('c');                                 //write
   writedata('t');                                 //write
   writedata('s');                                 //write
   writedata('.');                                 //write
   writedata('c');                                 //write
   writedata('o');                                 //write
   writedata('m');                                 //write
   writecmd(0x80);
}
void cct_init(void)
{
	P0 = 0x00;   //not used
	P1 = 0xf0;   //used for generating outputs and taking inputs from Keypad
	P2 = 0x00;   //used as data port for LCD
	P3 = 0x00;   //used for RS and E   
}
void delay(int a)
{
   int i;
   for(i=0;i<a;i++);   //null statement
}
void writedata(char t)
{
   RS = 1;             // This is data
   P2 = t;             //Data transfer
   E  = 1;             // => E = 1
   delay(150);
   E  = 0;             // => E = 0
   delay(150);
}
void writecmd(int z)
{
   RS = 0;             // This is command
   P2 = z;             //Data transfer
   E  = 1;             // => E = 1
   delay(150);
   E  = 0;             // => E = 0
   delay(150);
}
void lcdinit(void)
{
  ///////////// Reset process from datasheet /////////
     delay(15000);
   writecmd(0x30);
     delay(4500);
   writecmd(0x30);
     delay(300);
   writecmd(0x30);
     delay(650);
  /////////////////////////////////////////////////////
   writecmd(0x38);    //function set
   writecmd(0x0c);    //display on,cursor off,blink off
   writecmd(0x01);    //clear display
   writecmd(0x06);    //entry mode, set increment
}
void ReturnHome(void)     /* Return to 0 cursor location */
{
   writecmd(0x02);
   delay(1500);
   WebsiteLogo();
}
void writeline(char Line[])
{
   int i;
   for(i=0;i<strlen(Line);i++)
   {
      writedata(Line[i]);     /* Write Character */
   }
   
   ReturnHome();          /* Return to 0 cursor position */
}
char READ_SWITCHES(void)	
{	
	RowA = 0; RowB = 1; RowC = 1; RowD = 1; 	//Test Row A
	if (C1 == 0) { delay(10000); while (C1==0); return '7'; }
	if (C2 == 0) { delay(10000); while (C2==0); return '8'; }
	if (C3 == 0) { delay(10000); while (C3==0); return '9'; }
	if (C4 == 0) { delay(10000); while (C4==0); return '/'; }
	RowA = 1; RowB = 0; RowC = 1; RowD = 1; 	//Test Row B
	if (C1 == 0) { delay(10000); while (C1==0); return '4'; }
	if (C2 == 0) { delay(10000); while (C2==0); return '5'; }
	if (C3 == 0) { delay(10000); while (C3==0); return '6'; }
	if (C4 == 0) { delay(10000); while (C4==0); return 'x'; }
	
	RowA = 1; RowB = 1; RowC = 0; RowD = 1; 	//Test Row C
	if (C1 == 0) { delay(10000); while (C1==0); return '1'; }
	if (C2 == 0) { delay(10000); while (C2==0); return '2'; }
	if (C3 == 0) { delay(10000); while (C3==0); return '3'; }
	if (C4 == 0) { delay(10000); while (C4==0); return '-'; }
	
	RowA = 1; RowB = 1; RowC = 1; RowD = 0; 	//Test Row D
	if (C1 == 0) { delay(10000); while (C1==0); return 'C'; }
	if (C2 == 0) { delay(10000); while (C2==0); return '0'; }
	if (C3 == 0) { delay(10000); while (C3==0); return '='; }
	if (C4 == 0) { delay(10000); while (C4==0); return '+'; }
	return 'n';           	// Means no key has been pressed
}
char get_key(void)           //get key from user
{
	char key = 'n';              //assume no key pressed
	while(key=='n')              //wait untill a key is pressed
		key = READ_SWITCHES();   //scan the keys again and again
	return key;                  //when key pressed then return its value
}
int get_num(char ch)         //convert char into int
{
	switch(ch)
	{
		case '0': return 0; break;
		case '1': return 1; break;
		case '2': return 2; break;
		case '3': return 3; break;
		case '4': return 4; break;
		case '5': return 5; break;
		case '6': return 6; break;
		case '7': return 7; break;
		case '8': return 8; break;
		case '9': return 9; break;
		case 'C': writecmd(0x01); return Error; break;  //this is used as a clear screen and then reset by setting error
		default: DispError(0); return Error; break;     //it means wrong input
	}
}
char get_func(char chf)            //detects the errors in inputted function
{
	if(chf=='C')                   //if clear screen then clear the LCD and reset
	{ 
		writecmd(0x01);            //clear display
		WebsiteLogo();
		return 'e'; 
	}
	
	if( chf!='+' && chf!='-' && chf!='x' && chf!='/' )  //if input is not from allowed funtions then show error
	{ 
		DispError(1); 
		WebsiteLogo();
		return 'e'; 
	}
	return chf;                        //function is correct so return the correct function
}
void DispError(int numb)           //displays differet error messages
{
	writecmd(0x01);                //clear display
	WebsiteLogo();
	switch(numb)
	{
	case 0: 	writeline("Wrong Input");      break;
	case 1: 	writeline("Wrong Function");   break;
	default:    writeline("Wrong Input");      break;
	}
}
void disp_num(int numb)            //displays number on LCD
{	
	unsigned char UnitDigit  = 0;  //It will contain unit digit of numb
	unsigned char TenthDigit = 0;  //It will contain 10th position digit of numb
	if(numb<0)
	{
		numb = -1*numb;  // Make number positive
		writedata('-');	 // Display a negative sign on LCD
	}
	TenthDigit = (numb/10);	          // Findout Tenth Digit
	if( TenthDigit != 0)	          // If it is zero, then don't display
		writedata(TenthDigit+0x30);	  // Make Char of TenthDigit and then display it on LCD
	UnitDigit = numb - TenthDigit*10;
	writedata(UnitDigit+0x30);	  // Make Char of UnitDigit and then display it on LCD
}
Anyways, let's come back to keypad, if you wanna read the keypad details then you should read Interfacing of keypad with Arduino in Proteus ISIS as I have mentioned all the basic details about keypad in that tutorial and I am not gonna repeat it. But as a simple recall, keypad works on matrix system like it has 4 columns and 4 rows so we will have total 8 pins through which we are gonna control these 16 buttons. So, let's get started with it.
char READ_SWITCHES(void)	
{	
	RowA = 0; RowB = 1; RowC = 1; RowD = 1; 	//Test Row A
	if (C1 == 0) { delay(10000); while (C1==0); return '7'; }
	if (C2 == 0) { delay(10000); while (C2==0); return '8'; }
	if (C3 == 0) { delay(10000); while (C3==0); return '9'; }
	if (C4 == 0) { delay(10000); while (C4==0); return '/'; }
	RowA = 1; RowB = 0; RowC = 1; RowD = 1; 	//Test Row B
	if (C1 == 0) { delay(10000); while (C1==0); return '4'; }
	if (C2 == 0) { delay(10000); while (C2==0); return '5'; }
	if (C3 == 0) { delay(10000); while (C3==0); return '6'; }
	if (C4 == 0) { delay(10000); while (C4==0); return 'x'; }
	
	RowA = 1; RowB = 1; RowC = 0; RowD = 1; 	//Test Row C
	if (C1 == 0) { delay(10000); while (C1==0); return '1'; }
	if (C2 == 0) { delay(10000); while (C2==0); return '2'; }
	if (C3 == 0) { delay(10000); while (C3==0); return '3'; }
	if (C4 == 0) { delay(10000); while (C4==0); return '-'; }
	
	RowA = 1; RowB = 1; RowC = 1; RowD = 0; 	//Test Row D
	if (C1 == 0) { delay(10000); while (C1==0); return 'C'; }
	if (C2 == 0) { delay(10000); while (C2==0); return '0'; }
	if (C3 == 0) { delay(10000); while (C3==0); return '='; }
	if (C4 == 0) { delay(10000); while (C4==0); return '+'; }
	return 'n';           	// Means no key has been pressed
}
#include<reg51.h>
//Function declarations
void cct_init(void);
void delay(int);
void lcdinit(void);
void writecmd(int);
void writedata(char);
void Return(void);
char READ_SWITCHES(void);
char get_key(void);
//*******************
//Pin description
/*
P2 is data bus
P3.7 is RS
P3.6 is E
P1.0 to P1.3 are keypad row outputs
P1.4 to P1.7 are keypad column inputs
*/
//********************
// Define Pins
//********************
sbit RowA = P1^0;     //RowA
sbit RowB = P1^1;     //RowB
sbit RowC = P1^2;     //RowC
sbit RowD = P1^3;     //RowD
sbit C1   = P1^4;     //Column1
sbit C2   = P1^5;     //Column2
sbit C3   = P1^6;     //Column3
sbit C4   = P1^7;     //Column4
sbit E    = P3^6;     //E pin for LCD
sbit RS   = P3^7;     //RS pin for LCD
// ***********************************************************
// Main program
//
int main(void)
{
   char key;                // key char for keeping record of pressed key
   cct_init();              // Make input and output pins as required
   lcdinit();               // Initilize LCD
   writecmd(0x95);
   writedata('w');                                 //write
   writedata('w');                                 //write
   writedata('w');                                 //write
   writedata('.');                                 //write
   writedata('T');                                 //write
   writedata('h');                                 //write
   writedata('e');                                 //write
   writedata('E');                                 //write
   writedata('n');                                 //write
   writedata('g');                                 //write
   writedata('i');                                 //write
   writedata('n');                                 //write
   writedata('e');                                 //write
   writedata('e');                                 //write
   writedata('r');                                 //write
   writedata('i');                                 //write
   writedata('n');                                 //write
   writedata('g');                                 //write
 
   writecmd(0xd8);
 
   writedata('P');                                 //write
   writedata('r');                                 //write
   writedata('o');                                 //write
   writedata('j');                                 //write
   writedata('e');                                 //write
   writedata('c');                                 //write
   writedata('t');                                 //write
   writedata('s');                                 //write
   writedata('.');                                 //write
   writedata('c');                                 //write
   writedata('o');                                 //write
   writedata('m');                                 //write
   writecmd(0x80);
   while(1)
   { 
     key = get_key();       // Get pressed key
	 //writecmd(0x01);        // Clear screen
	 writedata(key);        // Echo the key pressed to LCD
   }
}
void cct_init(void)
{
	P0 = 0x00;   //not used
	P1 = 0xf0;   //used for generating outputs and taking inputs from Keypad
	P2 = 0x00;   //used as data port for LCD
	P3 = 0x00;   //used for RS and E   
}
void delay(int a)
{
   int i;
   for(i=0;i<a;i++);   //null statement
}
void writedata(char t)
{
   RS = 1;             // This is data
   P2 = t;             //Data transfer
   E  = 1;             // => E = 1
   delay(150);
   E  = 0;             // => E = 0
   delay(150);
}
void writecmd(int z)
{
   RS = 0;             // This is command
   P2 = z;             //Data transfer
   E  = 1;             // => E = 1
   delay(150);
   E  = 0;             // => E = 0
   delay(150);
}
void lcdinit(void)
{
  ///////////// Reset process from datasheet /////////
     delay(15000);
   writecmd(0x30);
     delay(4500);
   writecmd(0x30);
     delay(300);
   writecmd(0x30);
     delay(650);
  /////////////////////////////////////////////////////
   writecmd(0x38);    //function set
   writecmd(0x0c);    //display on,cursor off,blink off
   writecmd(0x01);    //clear display
   writecmd(0x06);    //entry mode, set increment
}
void Return(void)     //Return to 0 location on LCD
{
  writecmd(0x02);
    delay(1500);
}
char READ_SWITCHES(void)	
{	
	RowA = 0; RowB = 1; RowC = 1; RowD = 1; 	//Test Row A
	if (C1 == 0) { delay(10000); while (C1==0); return '7'; }
	if (C2 == 0) { delay(10000); while (C2==0); return '8'; }
	if (C3 == 0) { delay(10000); while (C3==0); return '9'; }
	if (C4 == 0) { delay(10000); while (C4==0); return '/'; }
	RowA = 1; RowB = 0; RowC = 1; RowD = 1; 	//Test Row B
	if (C1 == 0) { delay(10000); while (C1==0); return '4'; }
	if (C2 == 0) { delay(10000); while (C2==0); return '5'; }
	if (C3 == 0) { delay(10000); while (C3==0); return '6'; }
	if (C4 == 0) { delay(10000); while (C4==0); return 'x'; }
	
	RowA = 1; RowB = 1; RowC = 0; RowD = 1; 	//Test Row C
	if (C1 == 0) { delay(10000); while (C1==0); return '1'; }
	if (C2 == 0) { delay(10000); while (C2==0); return '2'; }
	if (C3 == 0) { delay(10000); while (C3==0); return '3'; }
	if (C4 == 0) { delay(10000); while (C4==0); return '-'; }
	
	RowA = 1; RowB = 1; RowC = 1; RowD = 0; 	//Test Row D
	if (C1 == 0) { delay(10000); while (C1==0); return 'C'; }
	if (C2 == 0) { delay(10000); while (C2==0); return '0'; }
	if (C3 == 0) { delay(10000); while (C3==0); return '='; }
	if (C4 == 0) { delay(10000); while (C4==0); return '+'; }
	return 'n';           	// Means no key has been pressed
}
char get_key(void)           //get key from user
{
	char key = 'n';              //assume no key pressed
	while(key=='n')              //wait untill a key is pressed
		key = READ_SWITCHES();   //scan the keys again and again
	return key;                  //when key pressed then return its value
}
LCD is also used almost in every Engineering Project for displaying different values. For example, if you have used the ATM machine, which you must have, then you have seen an LCD there displaying the options to select. Obviously that's quite a big LCD but still LCD. Similarly, all mobile phones are also equipped with LCDs. The LCD we are gonna use in this project is quite small and basic. It is normally known as the 16x2 LCD as it has rows and 2 columns for writing purposes. So, we are gonna interface that LCD with 8051 Microcontroller. The proteus Simulation along with hex file and the programming code in keil uvision 3 is given at the end of this post for download. If you are working with Arduino, then you should have a look at Interfacing of LCD with Arduino. The next level from LCD is Graphical LCD also known as GLCD, so if you wanna know more about that then you should read Interfacing of Arduino with GLCD. So, let's get started with it.
void lcdinit(void)
{
    delay(15000);
   writecmd(0x30);
     delay(4500);
   writecmd(0x30);
     delay(300);
   writecmd(0x30);
     delay(650);
   writecmd(0x38);    //function set
   writecmd(0x0c);    //display on,cursor off,blink off
   writecmd(0x01);    //clear display
   writecmd(0x06);    //entry mode, set increment 
}
void writecmd(int z)
{
   RS = 0;             // => RS = 0
   P2 = z;             //Data transfer
   E  = 1;             // => E = 1
   delay(150);
   E  = 0;             // => E = 0
   delay(150);
}
void writedata(char t)
{
   RS = 1;             // => RS = 1
   P2 = t;             //Data transfer
   E  = 1;             // => E = 1
   delay(150);
   E  = 0;             // => E = 0
   delay(150);
}
#include<reg51.h>
//Function declarations
void cct_init(void);
void delay(int);
void lcdinit(void);
void writecmd(int);
void writedata(char);
void ReturnHome(void);
//*******************
//Pin description
/*
P2 is data bus
P1.0 is RS
P1.1 is E
*/
//********************
// Defines Pins
sbit RS = P1^0;
sbit E  = P1^1;
// ***********************************************************
// Main program
//
void main(void)
{
   cct_init();                                     //Make all ports zero
   lcdinit();                                      //Initilize LCD
   writecmd(0x81);
   writedata('w');                                 //write
   writedata('w');                                 //write
   writedata('w');                                 //write
   writedata('.');                                 //write
   writedata('T');                                 //write
   writedata('h');                                 //write
   writedata('e');                                 //write
   writedata('E');                                 //write
   writedata('n');                                 //write
   writedata('g');                                 //write
   writedata('i');                                 //write
   writedata('n');                                 //write
   writedata('e');                                 //write
   writedata('e');                                 //write
   writedata('r');                                 //write
   writedata('i');                                 //write
   writedata('n');                                 //write
   writedata('g');                                 //write
   writecmd(0xc4);
   writedata('P');                                 //write
   writedata('r');                                 //write
   writedata('o');                                 //write
   writedata('j');                                 //write
   writedata('e');                                 //write
   writedata('c');                                 //write
   writedata('t');                                 //write
   writedata('s');                                 //write
   writedata('.');                                 //write
   writedata('c');                                 //write
   writedata('o');                                 //write
   writedata('m');                                 //write
   ReturnHome();                                   //Return to 0 position
    while(1)
    {
    }
}
void cct_init(void)
{
P0 = 0x00;   //not used 
P1 = 0x00;   //not used 
P2 = 0x00;   //used as data port
P3 = 0x00;   //used for generating E and RS
}
void delay(int a)
{
   int i;
   for(i=0;i<a;i++);   //null statement
}
void writedata(char t)
{
   RS = 1;             // => RS = 1
   P2 = t;             //Data transfer
   E  = 1;             // => E = 1
   delay(150);
   E  = 0;             // => E = 0
   delay(150);
}
void writecmd(int z)
{
   RS = 0;             // => RS = 0
   P2 = z;             //Data transfer
   E  = 1;             // => E = 1
   delay(150);
   E  = 0;             // => E = 0
   delay(150);
}
void lcdinit(void)
{
    delay(15000);
   writecmd(0x30);
     delay(4500);
   writecmd(0x30);
     delay(300);
   writecmd(0x30);
     delay(650);
   writecmd(0x38);    //function set
   writecmd(0x0c);    //display on,cursor off,blink off
   writecmd(0x01);    //clear display
   writecmd(0x06);    //entry mode, set increment 
}
void ReturnHome(void)     //Return to 0 location
{
  writecmd(0x02);
    delay(1500);
}
Download Proteus Simulation & Code
That's all for today, in the next post I am gonna share how to display custom characters on LCD with 8051 Microcontroller, because till now you can just display the simple characters like alphabets and numbers on it but can't display the custom characters like arrowhead etc. You should have a look at LCD Interfacing with Microcontrollers, where I have combined all tutorials related to LCD. So stay tuned and have fun.Now, today we are gonna go a little further and will have a look at Serial Communication with 8051 Microcontroller and we will also design the simulation of this project in Proteus ISIS software. 8051 Microcontroller also supports Serial port similar to Arduino and PIC Microcontroller. And the communication protocol is exactly the same as its a Serial Port. But obviously the syntax is bit different as we are not working in Arduino software or MPLAB. So let's get started with it.
#include <reg52.h>
#define Baud_rate 0xFD  // BAUD RATE 9600                     
void SerialInitialize(void);
void SendByteSerially(unsigned char);    
void cct_init(void);
sbit Appliance1 = P1^0;
sbit Appliance2 = P1^1;
sbit Appliance3 = P1^2;
sbit Appliance4 = P1^3;
sbit Appliance5 = P1^4;
sbit Appliance6 = P1^5;
sbit Appliance7 = P1^6;
sbit Appliance8 = P1^7;
void main()
{
    cct_init();
    SerialInitialize();    
    EA = 1;
    ES = 1;
    while(1) {;}
}
void cct_init(void)   //initialize cct
{
    P0 = 0x00; //not used
    P1 = 0x00; //Used for Appliances
    P2 = 0x00; //not used
    P3 = 0x03; //used for serial
}
void SerialInitialize(void)                   // INITIALIZE SERIAL PORT
{
    TMOD = 0x20;                           // Timer 1 IN MODE 2 -AUTO RELOAD TO GENERATE BAUD RATE
    SCON = 0x50;                           // SERIAL MODE 1, 8-DATA BIT 1-START BIT, 1-STOP BIT, REN ENABLED
    TH1 = Baud_rate;                       // LOAD BAUDRATE TO TIMER REGISTER
    TR1 = 1;                               // START TIMER
}
void SendByteSerially(unsigned char serialdata)
{
    SBUF = serialdata;                        // LOAD DATA TO SERIAL BUFFER REGISTER
    while(TI == 0);                            // WAIT UNTIL TRANSMISSION TO COMPLETE
    TI = 0;                                    // CLEAR TRANSMISSION INTERRUPT FLAG
}
void serial_ISR (void) interrupt 4
{
    //receive character
    char chr;
    if(RI==1)
    {
        chr = SBUF;
        RI = 0;
    }
    P0 = ~P0;    //Show the data has been updated
    switch(chr)
    {
     case '1':  Appliance1 = 1; SendByteSerially('k');  break;
     case '2':  Appliance2 = 1; SendByteSerially('k');  break;
     case '3':  Appliance3 = 1; SendByteSerially('k');  break;
     case '4':  Appliance4 = 1; SendByteSerially('k');  break;
     case '5':  Appliance5 = 1; SendByteSerially('k');  break;
     case '6':  Appliance6 = 1; SendByteSerially('k');  break;
     case '7':  Appliance7 = 1; SendByteSerially('k');  break;
     case '8':  Appliance8 = 1; SendByteSerially('k');  break;
     case 'a':  Appliance1 = 0; SendByteSerially('k');  break;
     case 'b':  Appliance2 = 0; SendByteSerially('k');  break;
     case 'c':  Appliance3 = 0; SendByteSerially('k');  break;
     case 'd':  Appliance4 = 0; SendByteSerially('k');  break;
     case 'e':  Appliance5 = 0; SendByteSerially('k');  break;
     case 'f':  Appliance6 = 0; SendByteSerially('k');  break;
     case 'g':  Appliance7 = 0; SendByteSerially('k');  break;
     case 'h':  Appliance8 = 0; SendByteSerially('k');  break;
     default: ;    break;     //do nothing
    }
    RI = 0;
}
#include<reg51.h>
sbit LED = P1^0;          
void cct_init(void);
void delay(int a);
int main(void)
{
   cct_init();             
 
   while(1)
   {
       LED = 0;             
       delay(30000);      
       LED = 1;            
       delay(30000);       
   }
}
void cct_init(void)
{  
    P1 = 0x00;    
}
void delay(int a)
{
   int i;
   for(i=0;i<a;i++); 
}
Download Proteus Simulation & Keil Code
That's all for today, will come soon with new tutorial on 8051 Microcontroller so stay tuned and have fun. Cheers !!! :)
There are many ways for power factor measurement and today's the method we are gonna use is called zero crossing detection. We will first detect the zero crossing of our signal and then we are gonna do the power factor measurement based on the detection of zero crossing of our voltage and current signal. Seems bit difficultdon't worry we are gonna do everything and in quite full detail so stay with me and enjoy the tutorial. But before going into the details of power factor measurement, let's first discuss the basics of power factor measurement because before that you wont understand a bit.
We have designed this simulation after quite a lot of effort so its not for sale but has a quite small cost of $20 so that engineering students can buy it easily. You can buy the simulation along with hex file and code by clicking on the above button and it will lead you to Product page of this product. So, let get started with it.
We are all quite well aware of these and if you are not then I must say you wont read further and must first get some basic knowledge about these loads. Among these three loads Resistive loads are known as the most decent loads as they don't mess up with the current and just simply let the current pass through it and that's why there's no such power loss in these types of loads. But when it comes to Capacitive or Inductive loads. they are quite disturbing types of loads and hence they don't let the current easily pass through them and slightly distort the current signals. In case of Capactive loads, the current waveform got ahead of the voltage waveform and hence got a lead angle. In other words, current waveform leads the voltage waveform. While in case of Inductive loads, the scenario is quite the opposite. In Inductive loads, current waveform lags the voltage waveform. The below figure shown the difference between these loads output.
Power Factor = Cos ( 60 degrees )
Power Factor = 0.5
void pf_func(){
while(1)
{
       if ( PINC.4==1 )
       {
           TCNT1=0;
           TCCR1B = 0x01;
           break;
       }
       else {
               continue;
             }
}
while(1){
     if ( PINC.3 == 1 ){
     TCCR1B = 0x00;
     g=TCNT1;
     break;
}
else {
continue;
}
}
}
int powerfactor(){
k=0;
// To complete number of counts
g=g+1; //Value from the timer
//To convert into seconds
pf=(float)g/1000000;
//To convert into radians
pf=pf*50*360*(3.14/180);
//power facor
pf = cos(pf);
//power factor into percentage
k=abs(ceil(pf*100));
return k;
}
So, buy it and test it and hopefully you will get something big out of it. So that's all about Power Factor Measurement using Atmega. I will post it on Arduino as well quite soon and may be on PIC Microcontroller as well. So, till next tutorial take care !!! :)