How to Generate PWM in 8051 Microcontroller

Hello everyone, hope you all are fine and having fun with your lives. In today's post, I am going to share How to generate PWM in 8051 Microcontroller. PWM is an abbreviation of Pulse Width Modulation and is used in many engineering projects. It is used in those engineering projects where you want an analog output. For example, you want to control the speed of your DC motor then you need a PWM pulse. Using PWM signal you can move your motor at any speed from 0 to its max speed. Similarly suppose you wanna dim your LED light, again you are gonna use PWM pulse. So, in short, it has numerous uses. If you are working on Arduino then you should read How to use Arduino PWM Pins.

PWM, as the name suggests, is simply a pulse width modulation. We take a pulse and then we modulate its width and make it small or big. Another term important while studying PWM is named duty cycle. The duty cycle shows the duration for which the PWM pulse remains HIGH. Now if the pulse remains high for 50% and LOW for 50% then we say that PWM pulse has a duty cycle of 50%. Similarly, if the pulse is HIGH for 70% and Low for 30% then it has a duty cycle of 70%.

Most of the microcontrollers have special pins assigned for PWM as in Arduino UNO it has 6 PWM pins on it. Similarly, PIC Microcontrollers also have PWM pins but unfortunately, the 8051 Microcontroller doesn't have this luxury means there are no special PWM pins available in 8051 Microcontroller. But PWM is necessary so we are going to manually generate the PWM pulse using Timer0 interrupt. So, before reading this tutorial you must first read How to use Timer Interrupt in 8051 Microcontroller so that you understand the functioning of Timer Interrupt. Anyways, let's get started with the generation of PWM in the 8051 Microcontroller.

Where To Buy?
No.ComponentsDistributorLink To Buy
18051 MicrocontrollerAmazonBuy Now

How to Generate PWM in 8051 Microcontroller ???

  • You can download both the simulation and the programming code for PWM in 8051 Microcontroller by clicking the below button:
Download PWM Code & Simulation
  • First of all, design a simple circuit as shown in the below figure:
  • Now what we are gonna do is we are gonna generate a PWM pulse using timer0 interrupt and then we are gonna send it to P2.0.
  • I have attached an oscilloscope on which we can easily monitor this PWM pulse and can check whether it's correct or not.

Code in Keil uvision 3

  • Now, copy the below code and paste it into your Keil uvision software. I have used Keil uvision 3 for this code compiling.
#include<reg51.h>

// PWM_Pin
sbit PWM_Pin = P2^0;		   // Pin P2.0 is named as PWM_Pin

// Function declarations
void cct_init(void);
void InitTimer0(void);
void InitPWM(void);

// Global variables
unsigned char PWM = 0;	  // It can have a value from 0 (0% duty cycle) to 255 (100% duty cycle)
unsigned int temp = 0;    // Used inside Timer0 ISR

// PWM frequency selector
/* PWM_Freq_Num can have values in between 1 to 257	only
 * When PWM_Freq_Num is equal to 1, then it means highest PWM frequency
 * which is approximately 1000000/(1*255) = 3.9kHz
 * When PWM_Freq_Num is equal to 257, then it means lowest PWM frequency
 * which is approximately 1000000/(257*255) = 15Hz
 *
 * So, in general you can calculate PWM frequency by using the formula
 *     PWM Frequency = 1000000/(PWM_Freq_Num*255)
 */
#define PWM_Freq_Num   1	 // Highest possible PWM Frequency


// Main Function
int main(void)
{
   cct_init();   	       // Make all ports zero
   InitPWM();              // Start PWM
 
   PWM = 127;              // Make 50% duty cycle of PWM

   while(1)                // Rest is done in Timer0 interrupt
   {}
}

// Init CCT function
void cct_init(void)
{
	P0 = 0x00;   
	P1 = 0x00;   
	P2 = 0x00;   
	P3 = 0x00;  
}

// Timer0 initialize
void InitTimer0(void)
{
	TMOD &= 0xF0;    // Clear 4bit field for timer0
	TMOD |= 0x01;    // Set timer0 in mode 1 = 16bit mode
	
	TH0 = 0x00;      // First time value
	TL0 = 0x00;      // Set arbitrarily zero
	
	ET0 = 1;         // Enable Timer0 interrupts
	EA  = 1;         // Global interrupt enable
	
	TR0 = 1;         // Start Timer 0
}

// PWM initialize
void InitPWM(void)
{
	PWM = 0;         // Initialize with 0% duty cycle
	InitTimer0();    // Initialize timer0 to start generating interrupts
					 // PWM generation code is written inside the Timer0 ISR
}

// Timer0 ISR
void Timer0_ISR (void) interrupt 1   
{
	TR0 = 0;    // Stop Timer 0

	if(PWM_Pin)	// if PWM_Pin is high
	{
		PWM_Pin = 0;
		temp = (255-PWM)*PWM_Freq_Num;
		TH0  = 0xFF - (temp>>8)&0xFF;
		TL0  = 0xFF - temp&0xFF;	
	}
	else	     // if PWM_Pin is low
	{
		PWM_Pin = 1;
		temp = PWM*PWM_Freq_Num;
		TH0  = 0xFF - (temp>>8)&0xFF;
		TL0  = 0xFF - temp&0xFF;
	}

	TF0 = 0;     // Clear the interrupt flag
	TR0 = 1;     // Start Timer 0
}

  • I have added the comments in the above codes so it won't be much difficult to understand. If you have a problem then ask in the comments and I will resolve them.
  • Now in this code, I have used a PWM variable and I have given 127 to it as a starting value.
  • PWM pulse varies from 0 to 255 as it's an 8-bit value so 127 is the mid-value which means the duty cycle will be 50%.
  • You can change its value as you want it to be.

Proteus Simulation Result

  • So, now when you upload the hex file and run your simulation then you will get below results:
  • Now you can check in the above figure that the duration of HIGH and LOW is the same means the pulse is HIGH for 50% and LOW for the remaining 50% cycle.
  • Now let's change the PWM duty cycle to 85 which is 1/3 and it will generate a PWM pulse of 33% duty cycle. Here's the result:
  • Now you can easily compare the above two figures and can get the difference. In the above figure now the duty cycle has decreased as the HIGH timing of the pulse is now reduced to 1/3 and pulse is LOW for 2/3 of the total time.
That's all, for today. That's how we can generate PWM in 8051 Microcontroller. Will meet you guys in the next tutorial. Till then take care !!! :)

Interrupt Based Digital Clock with 8051 Microcontroller

Hello friends, hope you all are fine and having fun with your lives. In today's post, I am going to share Interrupt based Digital clock with 8051 Microcontroller. In the previous post, I have explained in detail How to use Timer Interrupt in 8051 Microcontroller. We have seen in that post that we can use two timers in 8051 Microcontroller which are Timer0 and Timer1. Using these timers we can easily generate interrupts. So, before going into details of this post, you must read that timer post as I am gonna use these timer interrupts in today's post.

After reading this post, you will also get the skilled hand on timer interrupt and can understand them more easily. In today's post, I am gonna design a digital clock which will increment after every one second and we will calculate this one second increment using timer interrupt. This clock will be displayed on LCD so if you are not familiar with LCD then must read Interfacing of LCD with 8051 Microcontroller. You can also implement this digital clock with any other microcontroller like Arduino or PIC Microcontroller but today we are gonna implement it on 8051 Microcontroller. The complete simulation along with code is given at the end of this post but my suggestion is to design it on your own so that you get most of it. Use our code and simulation as a guide. So, let's get started with Interrupt based Digital clock with 8051 Microcontroller. :)

Interrupt Based Digital Clock with 8051 Microcontroller

  • First of all, design a circuit as shown in below figure:

  • Now use the below code and get your hex file. I have designed this code in Keil uvision 3 compiler for 8051 Microcontroller.
#include<reg51.h>

//Function declarations
void cct_init(void);
void delay(int);
void lcdinit(void);
void WriteCommandToLCD(int);
void WriteDataToLCD(char);
void ClearLCDScreen(void);
void InitTimer0(void);
void UpdateTimeCounters(void);
void DisplayTimeToLCD(unsigned int,unsigned int,unsigned int);
void WebsiteLogo();
void writecmd(int);
void writedata(char);

//*******************
//Pin description
/*
P2.4 to P2.7 is data bus
P1.0 is RS
P1.1 is E
*/
//********************

// Defines Pins
sbit RS = P1^0;
sbit E  = P1^1;

// Define Clock variables
unsigned int usecCounter = 0;
unsigned int msCounter   = 0;
unsigned int secCounter  = 0;
unsigned int minCounter  = 0;
unsigned int hrCounter   = 0;



// ***********************************************************
// Main program
//
void main(void)
{
   cct_init();             // Make all ports zero
   lcdinit();              // Initilize LCD
   InitTimer0();           // Start Timer0
  // WebsiteLogo();			
	while(1)
	{
		if( msCounter == 0 )                                       // msCounter becomes zero after exact one sec
		{
			DisplayTimeToLCD(hrCounter, minCounter, secCounter);   // Displays time in HH:MM:SS format
		}

		UpdateTimeCounters();                                      // Update sec, min, hours counters
  	}
}
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 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 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 InitTimer0(void)
{
	TMOD &= 0xF0;    // Clear 4bit field for timer0
	TMOD |= 0x02;    // Set timer0 in mode 2
	
	TH0 = 0x05;      // 250 usec reloading time
	TL0 = 0x05;      // First time value
	
	ET0 = 1;         // Enable Timer0 interrupts
	EA  = 1;         // Global interrupt enable
	
	TR0 = 1;         // Start Timer 0
}


void Timer0_ISR (void) interrupt 1     // It is called after every 250usec
{
	usecCounter = usecCounter + 250;   // Count 250 usec
	
	if(usecCounter==1000)              // 1000 usec means 1msec 
	{
		msCounter++;
		usecCounter = 0;
	}

	TF0 = 0;     // Clear the interrupt flag
}

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 UpdateTimeCounters(void)
{
	if (msCounter==1000)
	{
		secCounter++;
		msCounter=0;
	}

	if(secCounter==60)
	{
		minCounter++;
		secCounter=0;
	}

	if(minCounter==60)
	{
		hrCounter++;
		minCounter=0;
	}

	if(hrCounter==24)
	{
		hrCounter = 0;
	}
}


void DisplayTimeToLCD( unsigned int h, unsigned int m, unsigned int s )   // Displays time in HH:MM:SS format
{
	ClearLCDScreen();      // Move cursor to zero location and clear screen

	// Display Hour
	WriteDataToLCD( (h/10)+0x30 );
	WriteDataToLCD( (h%10)+0x30 );

	//Display ':'
	WriteDataToLCD(':');

	//Display Minutes
	WriteDataToLCD( (m/10)+0x30 );
	WriteDataToLCD( (m%10)+0x30 );

	//Display ':'
	WriteDataToLCD(':');

	//Display Seconds
	WriteDataToLCD( (s/10)+0x30 );
	WriteDataToLCD( (s%10)+0x30 );
}


void delay(int a)
{
   int i;
   for(i=0;i<a;i++);   //null statement
}

void WriteDataToLCD(char t)
{
   RS = 1;             // This is data

   P2 &= 0x0F;		   // Make P2.4 to P2.7 zero
   P2 |= (t&0xF0);     // Write Upper nibble of data

   E  = 1;             // => E = 1
   delay(150);
   E  = 0;             // => E = 0
   delay(150);

   P2 &= 0x0F;		   // Make P2.4 to P2.7 zero
   P2 |= ((t<<4)&0xF0);// Write Lower nibble of data

   E  = 1;             // => E = 1
   delay(150);
   E  = 0;             // => E = 0
   delay(150);
}


void WriteCommandToLCD(int z)
{
   RS = 0;             // This is command

   P2 &= 0x0F;		   // Make P2.4 to P2.7 zero
   P2 |= (z&0xF0);     // Write Upper nibble of data

   E  = 1;             // => E = 1
   delay(150);
   E  = 0;             // => E = 0
   delay(150);

   P2 &= 0x0F;		   // Make P2.4 to P2.7 zero
   P2 |= ((z<<4)&0xF0);// Write Lower nibble of data

   E  = 1;             // => E = 1
   delay(150);
   E  = 0;             // => E = 0
   delay(150);
}

void lcdinit(void)
{
  ///////////// Reset process from datasheet /////////
     delay(15000);

	 P2 &= 0x0F;		   // Make P2.4 to P2.7 zero
	 P2 |= (0x30&0xF0);    // Write 0x3
	
	 E  = 1;               // => E = 1
	 delay(150);
	 E  = 0;               // => E = 0
	 delay(150);

     delay(4500);

	 P2 &= 0x0F;		   // Make P2.4 to P2.7 zero
	 P2 |= (0x30&0xF0);    // Write 0x3
	
	 E  = 1;               // => E = 1
	 delay(150);
	 E  = 0;               // => E = 0
	 delay(150);

     delay(300);

	 P2 &= 0x0F;		   // Make P2.4 to P2.7 zero
	 P2 |= (0x30&0xF0);    // Write 0x3
	
	 E  = 1;               // => E = 1
	 delay(150);
	 E  = 0;               // => E = 0
	 delay(150);

     delay(650);

	 P2 &= 0x0F;		   // Make P2.4 to P2.7 zero
	 P2 |= (0x20&0xF0);    // Write 0x2
	
	 E  = 1;               // => E = 1
	 delay(150);
	 E  = 0;               // => E = 0
	 delay(150);

	 delay(650);

  /////////////////////////////////////////////////////
   WriteCommandToLCD(0x28);    //function set
   WriteCommandToLCD(0x0c);    //display on,cursor off,blink off
   WriteCommandToLCD(0x01);    //clear display
   WriteCommandToLCD(0x06);    //entry mode, set increment
}

void ClearLCDScreen(void)
{
	WriteCommandToLCD(0x01);   // Clear screen command
	delay(1000);
}
  • Now run your simulation and if everything goes fine then you will get results as shown in below figure:
  • The above figure is taken after 10 seconds of start of simulation in Proteus ISIS.
  • As the simulation keeps on running the clock will also keep on ticking.
  • The code is self explanatory but let me explain the interrupt function.
  • I have used Timer0 interrupt in this digital Clock.
  • The timer interrupt function is incrementing the userCounter variable by 250 which is in micro seconds. So we need 1000us as it will become 1 second. That's why I have placed the check that when userCounter == 1000 then increment the second.
  • I have added comments in the code so read it in detail and still if you stuck somewhere then ask in comments and I will resolve them.
  • You can download the complete code along with Proteus Simulation by clicking the below button:

Download Proteus Simulation and Code for Digital Clock

That's all for today. Hope you have enjoyed today's project. Will meet you guys soon in the next post. Till then take care !!! :)

How to use Timer Interrupt in 8051 Microcontroller

Hello friends, hope you all are fine and having fun with your lives.In today's post, we are gonna see How to use timer interrupt in 8051 Microcontroller.8051 Microcontroller comes with timer as well. They normally have two timer in them named as Timer0 and Timer1. These timers are used for counting purposes like you want to start some countdown in your project then you can use these timers or you wanna create some clock then in that case as well you need timers. So, in short there are numerous uses of timers in a project. Timers are also used for delays like you wanna create some delay of 10 sec but you dont wanna use the delay function in your project so you can use timers. You start the timer and then when it comes to 10 seconds then you can do your work. So, these are different uses of a timer and clearly we can't neglect its importance, so today we are gonna see How to use these timer interrupt in 8051 Microcontroller.

Now coming towards interrupt, interrupt is interrupt :P Yeah really, we call it interrupt because its an interrupt. In programming codes there are many things which needs to run in background and appear when its time for them to appear. Here where interrupt comes handy. Interrupt is kind of a background code which keeps on running in the background while the main code keeps on running in front but when the interrupt condition is fullfilled then it interrupts the main program and executes the functions defined in it. For Timer interrupts, suppose I wanna blink my LED after every 2 seconds then what will I do is I will start a timer for 2 seconds and when this timer completes I will generate an interrupt. So, in this way after every two seconds the led will blink. So, let's start with timers interrupt in 8051 Microcontroller and see how we are gonna do this.

How to use Timer interrupt in 8051 Microcontroller ???

As I explained earlier, we are gonna use Timer interrupt in 8051 Microcontroller. so, now before gong into the details, let me first throw some light on how we are gonna implement this. Timers count from 0 to 255 in 8 bit mode as in 8 bit 255 is the maximum value and when timer hits the 255 number then we say that our timer is overflowed. Now when timer overflows, then it sends us a indication using which we generate our intterupt. In timers, there are few registers in which they store their value. If we are talking about Timer0 then timer0 stores its value in TL0 register. Now suppose I want my timer to start counting from 10 instead 0 then I will store 10 in my TL0 register and it will count from 10 instead 0 and when it reaches 255 it will overflow. Now when Timer0 will overflow then it will make TF0 bit HIGH. TF0 is another register value, if its 1 then it means that our timer is full and if its 0 then it means our timer is still counting. So, that's how we count from our timer and check the pin TF0. Now first of all, I am gonna use Timer0 and then we will have a quick look at Timer1.

Timer0 Interrupt
  • First of all, design a simple circuit as shown in below figure:
  • Now upload the below code in your Keil software and get the hex file.
#include<reg51.h>

// Out Pin
sbit Out = P2^0;		   // Pin P2.0 is named as Out

//Function declarations
void cct_init(void);
void InitTimer0(void);


int main(void)
{
   cct_init();   	       // Make all ports zero
   InitTimer0();           // Start Timer0
 
   while(1)                // Rest is done in Timer0 interrupt
   {
   }
}

void cct_init(void)
{
	P0 = 0x00;   
	P1 = 0x00;   
	P2 = 0x00;   
	P3 = 0x00;  
}


void InitTimer0(void)
{
	TMOD &= 0xF0;    // Clear 4bit field for timer0
	TMOD |= 0x02;    // Set timer0 in mode 2
	
	TH0 = 0x05;      // 250 usec reloading time
	TL0 = 0x05;      // First time value
	
	ET0 = 1;         // Enable Timer0 interrupts
	EA  = 1;         // Global interrupt enable
	
	TR0 = 1;         // Start Timer 0
}


void Timer0_ISR (void) interrupt 1   // It is called after every 250usec
{
	Out = ~Out;  // Toggle Out pin

	TF0 = 0;     // Clear the interrupt flag
}

  • In the above code, the main function is our InitTimer0 function.
  • In this function what I have done is I simply set the timer 0 to mode 2. In mode 2, it will auto reload means once the timer0 overflows then it will comes back to its original value and will start again.
  • TL0 has 0x05 in it which is the initial value of timer0 and it will count for 250 micro seconds.
  • TH0 also has the 0x05. On reload timer uploads the vlaue from TH0 into TL0 so thats why we have given the same value to TH0.
  • After that we make ET0 bit enabled which will enable the timer, if you dont set this pin HIGH then our timer will not work.
  • EA bit will enable the global interrupt. if we dont enable this pin then timer will work but it wont generate the interrupt.
  • Finally after setting all configurations, we started our timer.
  • Now when the Timer0 overflows after every 250 micro seconds, it will generate the interrupt and it will come to Timer0_ISR function.
  • In Timer0_ISR function, I simply toggled the OUt pin which is Pin2.0 and then I again set the interrupt bit to 0 which is TF0.
  • That's how our timer is working and if we check the P2.0 pin on oscilloscope then it will look something as shown in below figure:
  • You can see in the above figure that our pin is toggling with an interval of 250 usec.
  • One important thing to note is there's no function written in while(1) loop and still its working because its running on background and performing the interrupt routine. You can add any function in your MAin code and it will keep on working and meanwhile at the background your interrupt will also keep on generating.
  • You can download this Simulation and programming code by clicking on below button.

Download Timer0 Code and Simulation

  • Now, lets have a quick look on Timer1 interrupt in 8051 Microcontroller.
Timer1 Interrupt
  • Now let's have a quick look on Timer1 interrupt in 8051 Microcontroller. For that, design the same simulation in Proteus as we did for Timer 0.
  • Now, upload the below code in your Keil software and get the hex file.
#include<reg51.h>

// Out Pin
sbit Out = P2^0;		   // Pin P2.0 is named as Out

//Function declarations
void cct_init(void);
void InitTimer1(void);


int main(void)
{
   cct_init();   	       // Make all ports zero
   InitTimer1();           // Start Timer1
 
   while(1)                // Rest is done in Timer1 interrupt
   {
   }
}

void cct_init(void)
{
	P0 = 0x00;   
	P1 = 0x00;   
	P2 = 0x00;   
	P3 = 0x00;  
}


void InitTimer1(void)
{
	TMOD &= 0x0F;    // Clear 4bit field for timer1
	TMOD |= 0x20;    // Set timer1 in mode 2
	
	TH1 = 0x05;      // 250 usec reloading time
	TL1 = 0x05;      // First time value
	
	ET1 = 1;         // Enable Timer1 interrupts
	EA  = 1;         // Global interrupt enable
	
	TR1 = 1;         // Start Timer 1
}


void Timer1_ISR (void) interrupt 3   // It is called after every 250usec
{
	Out = ~Out;  // Toggle Out pin

	TF1 = 0;     // Clear the interrupt flag
}

  • Now you can see in the above code that its exactly the same as we used for Timer0 with a slight difference that now we are using registers for Timer1.
  • Instead of TL0, now we are using TL1 and similarly TH1 instead of TH0 and TR1 instead of TR0.
  • Rest of the code is exactly the same and hence it will give the same result as for Timer0 and is shown in below figure:
  • You can download the code for Timer1 along with simulation by clicking the below button.

Download Timer1 Code and Simulation

That's all for today, I hope you guys have got something out of today's post and gonna like this one. In the coming post, I am gonna design some simple project on 8051 Microcontroller in which I will use these Timers, then you will get know more about them. So, stay tuned and subscribe us by email. Take care !!! :)

8051 Microcontroller Projects

Hello everyone, hope you all are fine and having fun with your lives. Today, I am going to share 8051 Microcontroller Projects. Recently, I have shared quite a lot of tutorials on 8051 Microcontroller which are not much arranged as a whole. So, today, I thought to arrange all those tutorials and place them here so that you can get all of them quite easily. I will upload more 8051 Microcontroller Projects and I am gonna add their links in this post so stay subscribed to this post if you are interested in learning 8051 Microcontroller.

8051 Microcontroller, as we all know, is another Microcontroller series just like PIC Microcontroller or Arduino etc. The benefit of 8051 Microcontrollers is that they are quite cheap and easily available so if you are going to design some product then its better to use 8051 Microcontroller instead of PIC Microcontroller or Arduino etc. As they are cheap so they also come with a disadvantage which is that they are not much rich with features. Few of 8051 Microcontrollers doesn't even support Serial Communication. So, before choosing it for your project, must check their datasheet to confirm that they are suitable for your projects.

In most of these below projects, I have designed the complete simulation in Proteus and the code is also given but my suggestions is don't simply download the simulation and run it. Instead design the simulation from scratch and then design your code and run the simulation on your own. Consider my codes and simulations as a guide but dont get dependent on them as then you are not gonna get anything. Anyways let's get started with 8051 Microcontroller Projects.

8051 Microcontroller Projects

Below are mentioned all the 8051 Microcontrollers Projects, which I have shared on this blog. You can check these projects and can also download their simulations designed in Proteus. I have given codes for most of these projects but few are paid, which you can buy from our shop at a quite minimal rate.

Basic Projects

These are basic projects and are best for beginner level programmers. If you are new to 8051 Microcontroller then first read these projects. These all projects contain complete codes as well as the Proteus simulation so you can quite easily test them in Proteus software and can edit the codes and learn from it.

Intermediate Projects

These are Intermediate level 8051 Microcontroller Projects. If you wanna do these projects then you must first learn or atleast have a look at basic 8051 Microcontroller projects as they are using same components as we interfaced in basic level. If you feel any problem then ask in comments.

That's all for today, but I am gonna add more projects in it and will keep on updating the list. Subscribe us and get these exciting tutorials straight to your mail box.

XBee Library for Proteus

Hello everyone, today I am going to share a new XBee Library for Proteus. I am quite excited while sharing it as we are the first developer for this XBee Library. Now you can quite easily use XBee module in your Proteus software using this XBee Library for Proteus.Wehave spent quite a lot of time in developing this and that's the reason I couldn't share new tutorials in the past few days. Anyways we are done with this new exciting XBee Library for Proteus, hope you are gonna enjoy this one. I have already sharede two libraried for Proteus which are Arduino Library for Proteus and GPS Library for Proteus. You can also interface this XBee module with Microcontrollers like Arduino, PIC Microcontroller and 8051 Microcontroller quite easily.

As its the first version of our XBee Library for Proteus so its not quite perfect and can't do the complex tasks such as analog inputs etc. It will just do the serial communication. This xbee module has two pins TX and RX and you can do your communication with it quite easily. We have designed this XBee Library for Proteus, after quite a lot of effort and we are quite proud that we are presenting it first time for Proteus. Other bloggers are welcome to share this library on their blogs to share the knowledge but do mention our blog post link in your post. :) You should also have a look at XBee Arduino Interfacing. So, let's get started with it.

XBee Library for Proteus

  • First of all, download this XBee Library for Proteus by clicking on the below button:
XBee Library for Proteus

  • Now once you click it you will get a zip file to download so download this zip and open it.
  • In this zip file you will get two files named as:
    • XBeeTEP.LIB
    • XBeeTEP.IDX
  • So, now place these two files in the libraries folder of your Proteus software.
Note:
  • Now, start your Proteus ISIS software or restart it if its already running.
  • Go to your components library and search for XBee Module as shown in below figure:
  • Now place it in your workspace and it will look something as shown in below figure:
  • If you don't know much about xbee module then you should also have a look at Introduction to XBee Module.
  • As you can see in the above figure, its our xbee module in Proteus for the first time.
  • As, I mentioned earlier, its a first version of xbee module so its not very advanced and it will do just the basic serial communication i.e. sending and receiving data.
  • It has two pins on it which are TX and RX and using these two pins you can send and receive data quite easily.
  • So, let's design a simple example and we will see How to do the Serial communication using this new XBee library for Proteus.
  • Design a simple circuit as shown in below figure:
  • Now what I did is, I simply place a Virtual terminal with both of these xbee modules.
  • Now we need to change the Properties of one of these XBee module so double click on any one of these and you will get the below window:
  • You should also have a look at Interfacing of XBee with Computer.
  • Now, I have simply changed the Physical Port of this module to COM2 while the other module is at COM1.
  • So, now one of my XBee module is at COM1 while the second module is at COM2.
  • Now when I run my simulation then both XBee will start sending and receiving data on their respective COM Ports.
  • So, what I need to do is to virtually combine these two ports and for that I have used a software named as Virtual Software Driver from Eltima and I combine these two ports.
  • Now, run your simulation and whatever you type in the Virtual Terminal of first xbee will appear in the virtual terminal of second xbee. as shown in below figure:
  • You can also interface this XBee modue with other microcontrollers like Arduino, PIC Microcontrollers or 8051 Microcontrollers etc.
  • I have explained this whole tutorial in below video as well.
I hope you have enjoyed it and are gonna like it. Let me know if you got into any trouble and have problems in using this library. Also share your suggestions about improvement in this XBee Library for Proteus. :)

GPS Library for Proteus

Hello friends, hope you all are fine and having fun with your lives. In today's tutorial, I am gonna share another awesome library designed by our team for Proteus, which is GPS Library for Proteus. It's my second library for Proteus, the first one was Arduino Library for Proteus which I have already shared. I am really enjoying designing these modules in Proteus because its a new and quite challenging thing. I haven't found even a single website who has designed these modules in Proteus already. So, now for the first time, you can have the GPS Library for Proteus using which you can easily simulate your GPS module in Proteus and can design your code for Arduino, PIC Microcontroller or 8051 Microcontroller.

Other bloggers are welcome to share this library and its my humble request that do mention our blog in credits. :) The GPS module, I have designed for Proteus is a simple GPS which has TX and RX pins and when you start the simulation, this module starts sending the NMEA data on its TX pin, which you can easily check using Virtual Terminal. I am gonna show you how to check it in today's post. Another important thing, obviously in Proteus Simulation we can't get the actual values of longitude,latitude etc, so in our model, I have used the dummy values for all these data. The benefit of this module is that you can easily design your code for GPS and can test it in your simulation. Plus, its design is cool as well. ;)

Note:

GPS Library for Proteus

  • First of all, click on the below button and download GPS Library for Proteus.
GPS Library for Proteus
  • After downloading, you will get a zip file containing three files in it.
  • Now extract all these three files named as:
    • GpsTEP.LIB
    • GpsTEP.IDX
    • GpsTEP.HEX
  • Place these files in Libraries folder of your Proteus software.
Note:
  • Now open your Proteus software, if you have already opened it then restart your Proteus software.
  • Now in components list search for GPS Module and place it in your workspace.
  • If everything's fine then you will get your module as shown in below figure:
  • As you can see in the above figure, it has two pins in total which are TX and RX.
  • Now double click this GPS module and you will get to its properties as shown in below figure:
  • Now, one last thing you need to do is to upload the GpsTEP.HEX file, which you got in the downloaded zip file, in the Program File section.
  • This GpsTEP.HEX file is essential for this model as its adding the functionality of GPS in this model.
  • So, after adding the link of GpsTEP.HEX file in the Program File section, now your Gps module is ready to use in your circuit.
  • So, now let's add a Virtual terminal and check the output of this GPS Module. If you haven't worked on Virtual Terminal before then you should read How to use Virtual Terminal in Proteus ISIS.
  • Design a small circuit as shown in below figure:
Note:
  • The baud rate of this GPS Module is 9600.
  • The data sent by this GPS module is dummy as we can't get these values in simulation.
  • Now let's run the simulation and check the Virtual Terminal and if everything goes fine then you will get results as shown in below figure:
  • The first line is just the intro for this module and after that you will start receiving data which is in NMEA format.
  • NMEA data will remain constant but will keep on coming.
  • Now, instead of using this Virtual Terminal, you can use any microcontroller here like Arduino, PIC Microcontroller or 8051 Microcontroller etc. and can write your code easily and test it.
  • In my coming tutorials, I am gonna share examples for this GPS module in which I will interface it with different Microcontroller.
  • In the below video, I have explained this tutorial again so if you got any trouble then watch it as well.
That's all for today. You should also have a look at Interfacing of GPS Module with Arduino in Proteus ISIS. I hope you guys have enjoyed today's post and are gonna get benefit from it. Let me know your views about today's tutorial and also give your suggestions and help us in making this GPS Library for Proteus more smarter. :)

Arduino Pro Mini Library for Proteus

Update: We have created a new version of this library, which you can check here: Arduino Pro Mini Library for Proteus V2.0.
Hello friends, hope you all are fine and having fun with your lives. In today's post, I am gonna share Arduino Pro Mini Library for Proteus. Recently, I have shared Arduino Nano Library for Proteus, and before that I have also posted Arduino UNO Library for Proteus as well as Arduino Mega 2560 Library for Proteus, and now I am gonna share Arduino Pro Mini Library for Proteus. Arduino Pro Mini is another Arduino board which also uses the same Atmega328 Microcontroller and has almost the same number of pins as Arduino UNO and Arduino Nano. Arduino Pro Mini is even more smaller than Arduino Nano board. It doesn't have the programmer on it so if you need to program it you have to use some TTL to Serial converter or you can also use Arduino UNO board in order to burn programming code in it. So, in today's tutorial, I am gonna share the Arduino Pro Mini Library for Proteus, which is the first library ever made for this board. You won't find the Arduino Pro Mini Library for Proteus anywhere. I am quite proud that our blog is sharing this library for the first time. You can download this library freely from the link below and can now simulate your circuits quite easily. So, now let's get started with this new Arduino Pro Mini Library for Proteus. 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.

Arduino Pro Mini Library for Proteus

  • First of all, download the Arduino Pro Mini Library for Proteus by clicking the below button.
Arduino Pro Mini Library for Proteus

  • Now when you click it, you will get a zip file so extract this zip file and you will get two files named as ArduinoProMiniTEP.LIB and ArduinoProMiniTEP.IDX.
  • So download these two files and place it in the libraries folder of your Proteus software.
Note:
  • Now, after getting the Arduino Pro Mini Library for Proteus files and placing it properly in your Proteus software. Open your Proteus software and make a search for Arduino Pro Mini.
  • Once you get this board, place it in your Proteus workspace and it will look like something as shown in below figure:
  • Now next thing you need to do is to read How to get hex Fie from Arduino, so that you can get the hex file, which we are gonna upload in this Arduino Pro Mini board.
  • So, once you get the link for your hex file, simply double click this board to open its properties.
  • Now place this hex file in the Program File section of its Properties section as we have seen in Arduino Nano Library for Proteus tutorial.
  • That's all, now using this Arduino Pro Mini Library for Proteus, you can easily simulate your circuits in Proteus and can test your codes.
  • Now, let's design a simple blinking example as we have done for previous libraries.
  • So, in order to dos so, design a simple circuit in Proteus as shown in below figure:
  • So, now as usual, use the blink example from the Arduino software and get your hex file as described in How to get hex file from Arduino.
  • So, after uploading the hex file, run your simulation. If everything goes fine then you will get results as shown in below figure:
  • So, now that's how you can simulate Arduino Pro Mini in Proteus using Arduino Pro Mini Library for Proteus.

Seven Segment Display with 8051 Microcontroller

Hello friends, I hope you all are fine and having fun with your lives. In today's post, we are gonna have a look at How to interface Seven Segment display with 8051 Microcontroller. Seven Segment Display is normally used in those projects where counting or clock functionalities are required. If you wanna read the basic details of Seven Segment Display then must read Interfacing of Seven Segment Display with Arduino, I have explained 7 Segment Display in detail in that tutorial. And have also interfaced it with Arduino board. So, I am not gonna go into the details of 7 Segment in today's tutorial and I would recommend you to must read this tutorial.

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:

Interfacing of Seven Segment Display with 8051 Microcontroller

  • Seven Segment Display is of two types which is common cathode and common anode.
  • In this post, I have used common anode but you can easily use this code for common cathode but you have to do small change in the hardware.
  • If you are using common cathode then instead of GND you have to give +5V to the Seven Segment Display.
  • So, now let's first design the Proteus Simulation of Seven Segment Display with 8051 Microcontroller.
Proteus Simulation
  • First of all, design a Proteus Simulation for Interfacing of Seven Segment Display with 8051 Microcontroller,as shown in below figure:
  • Now you can see in the above figure that I have used 8051 Microcontroller which is AT89C51.
  • I have used Seven Segment display which is of Red color.
  • It has total 8 pins so we have connected these 8 pins of Seven Segment Display to 8 pins of Port 2 of 8051 Microcontroller.
  • Now, the last thing, I have used is 74LS245. Its kind of a current amplifier. 8051 Microcontroller provides quite small current on its output pins which is not quite enough for the Seven Segment Display to turn its LEDs ON.
  • So, we used this 74LS245 which provides extra current and makes the Seven Segment Display to work properly.
  • Now, let's design the programming code for this project.
Programming Code
  • I have designed the programming code for interfacing of Seven Segment Display with 8051 Microcontroller in Keil uvision 3 compiler.
  • The programming code is as follows:
#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;
	}	
}
  • Now the code code is quite simple. I have added a small delay of 1 second and then displayed the character and stored the next character in array.
  • So, in this way we are displaying the characters from 0 to 9 and then repeats the process.
  • Now, you have seen the basics of Seven Segment Display with 8051 Microcontroller and now you can design any kind of project on it, like you can create a counter or a timer.
  • Now, compile the code and get the hex file and upload it to your 8051 Microcontroller and run the simulation.
  • If everything goes fine then you will get the results as shown in below figure:
  • You can download the Programming code and Simulation for interfacing of Seven Segment Display with 8051 Microcontroller, by clicking on the below button.

Download Simulation and Code

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 !!! :)

Arduino Mega 2560 Library for Proteus

Update: We have created a new version of this library, which you can check here: Arduino Mega 2560 Library for Proteus V2.0.

Hello friends, hope you all are fine. In today's post, I am going to share Arduino Mega 2560 Library for Proteus. In the previous post, I have shared the Arduino UNO Library for Proteus and I have mentioned that I am gonna share more Arduino Libraries soon. Actually these days I am quite excited about this Proteus component designing and I am designing the Arduino boards as a starter. So, till now I have designed two Arduino boards in Proteus. First one was Arduino UNO which I have provided for download in previous post and today, I am going to share Arduino Mega 2560 Library for Proteus.

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.

Arduino Mega 2560 Library for Proteus

  • First of all, click the below button to download the Arduino Mega 2560 Library for Proteus.
Arduino Mega 2560 Library for Proteus

  • Now download this library and you will find a zip file.
  • Extract this zip file, it will contain two files named as ArduinoUnoTEP.LIB and ArduinoUnoTEP.IDX.
  • Place these files in the library folder of your Proteus software.
Note:
  • Now we have placed our Arduino Mega 2560 library for Proteus files in the libraries folder of Proteus software. So, now run your Proteus software and search Arduino Mega 2560.
  • Place this Arduino board in your workspace and it will look like something as shown in below figure:
  • It has become quite big but looking quite attractive and I am feeling kind of proud on my new invention. :)
  • Anyways, now next thing we need to do is to upload the hex file in it.
  • So, in order to do so, we need to double click the Arduino Mega 2560 board and its properties panel will poop up as shown in below figure:
  • Now browse for your hex file in the section PROGRAM FILE or paste the link as we did in previous Arduino UNO post.
  • You should read How to get Hex File from Arduino if you don't know already.
  • You can also change different options here but my suggestion is to not change anything else if you are not pro.
  • So, now we have seen How to get the Arduino Mega 2560 library for Proteus. Now let's design a simple example in which we will show led blinking with Arduino Mega 256 in Proteus software.
  • So, design a simple circuit as shown in below figure:
  • Now open the blink example from your Arduino software and get the hex file.
  • Upload this hex file in your Proteus software and run the simulation.
  • If everything goes fine then you will get something as shown in below figure:
  • Quite Simple. isn't it. Now below is given the video demonstration for Arduino Mega 2560 Library for Proteus.
So, that's all for today. Till now we have designed two Arduino boards in Proteus which are Arduino UNO and Arduino Mega 2560. I am planning on designing more Arduino boards and will post them soon.

Design a Simple Calculator with 8051 Microcontroller

Hello friends, today's post is about designing a simple calculator with 8051 Microcontroller. In our previous post, we have seen How to Interface keypad with 8051 Microcontroller in Proteus ISIS. Moreover, we have also worked on Interfacing of LCD with 8051 Microcontroller in Proteus ISIS. If you haven't read these two posts then my suggestion is to read them first before going into the details of this post, as we are going to use both keypad and LCD in order to design the simple calculator with 8051 Microcontroller.

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.

Design a Simple Calculator with 8051 Microcontroller

  • The calculator we are going to design in this post is quite basic calculator, it will only perform 4 tasks, which are as follows:
    • When you press the (+) button then it will add the two digits. For example, you want to add 2 and 3 then you need to press 2 + 2 = these four buttons in sequence and when you press the = button it will automatically will give you the sum.
    • When you press (-) button it will subtract the two digits like 3 - 2 = and it will give you the result.
    • When you press (x) button it will multiply the two digits.
    • When you press the (/) button it will simply divide the two digits.
  • Whenever you press the (=) button, it will give you the output depending on the function you used before and if you press (=) in the start then it will give "Wrong Input".
  • Finally, there's (ON/C) button on the Calculator, when you press this it will simply reset the code and will clear the LCD.
  • So, that's how this calculator is gonna work. Moreover, it will always reset when you try to calculate new value.
  • As its a simple calculator, so its only limited to 1 digit, means it will only apply the operation on single digit input like 2+3 but it won't work on more than 1 digit like 12 + 13.
  • I will soon design a more complicated calculator but for this one its only limited to single digit.
  • So, now let's design this calculator, so first we are gonna have a look at the Proteus simulation of Simple calculator with 8051 Microcontroller.
  • After that, we will do the coding part for calculator with 8051 Microcontroller.
  • So, now let's get started with Proteus Simulation.
Proteus Simulation
  • So, you can see we have used the same LCD which is 20x4 and have used the same keypad as did in previous tutorial.
  • You can see this keypad has all the required operations for this project which are (+), (-), (x) and (/).
  • So, now let's have a look at the programming code for calculator with 8051 Microcontroller.
Programming Code
  • We have already seen the programming code for keypad and LCD and I am assuming that you have also read those posts so I am not going into the details of those posts.
  • So,we know that how to print data on LCD and we are also aware of how to get key press from keypad and then display it on LCD.
  • So, now let's move on to adding these functions.
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
				 }                                 
			 }
		 }
     }
   }
  • As you can see in the above function, I have first check for the first key press.
  • When you pressed the first key on keypad then I get this key and converter it to integer.
  • After that I waited for the next key which must be some operation key like + - X or / otherwise it will generate the error message.
  • After that code is waiting for the third key which should be some numerical digit and then I converter it to integer again and if you entered some invalid key then it will generate the error.
  • Finally waiting for the = sign. When you press the = sign it will automatically perform the required operation which I placed in the switch case loop.
  • It will calculate the value and then print out the result and on next key press it will first clear the screen and then get the value and will continue.
  • Below is the detailed code for the project with comments and I hope you wont get into any trouble and will get it clearly.
#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
}

  • The above code is quite self explanatory and the main part I have already explained but still if you get into any troubled then ask in comments and I will resolve them.
  • Now copy this code in your keil uvision 3 and get the hex file.
  • Upload your hex file in Proteus ISIS and run your simulation.
  • The first screen you will get is as follows, which obviously displays our website address :P
  • Now, let's add 3 + 5 and we will get as shown in below figure:
  • Next operation, we are gonna do is the subtract one, so lets do this operation 3-9 = , shown below:
  • Now, lets do the third operation which is multiplication, so let's do this operation 9x9, shown below:
  • Now, finally do the last operation which is division, so I did 6/3 and result is shown below:
  • So, all the operations are shown in above figures, now if you give it wrong number like 2 digit number then it will display error message, as shown below:
  • It has become quite a lengthy post, so let's have the ending part. :)
  • You can download the Proteus Simulation along with hex file and code by clicking the below button.
Download Proteus Simulation and Code

So, that's all with the designing of simple Calculator with 8051 Microcontroller. I will try to work on advanced calculator, if I got time but I am not sure of that. :) So, that's all for today and will meet in next tutorial soon. till than have fun. !!! :)
Syed Zain Nasir

I am Syed Zain Nasir, the founder of <a href=https://www.TheEngineeringProjects.com/>The Engineering Projects</a> (TEP). I am a programmer since 2009 before that I just search things, make small projects and now I am sharing my knowledge through this platform.I also work as a freelancer and did many projects related to programming and electrical circuitry. <a href=https://plus.google.com/+SyedZainNasir/>My Google Profile+</a>

Share
Published by
Syed Zain Nasir