pcbway




pwm in 8051, 8051 pwm, 8051 pwm code, pwm in 8051 microcontroller, 8051 and pwmHello everyone, hope you all are fine and having fun with your lives. In toda’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 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 as duty cycle. Duty cycle shows the duration for which the PWM pulse remains HIGH. Now if the pulse is remain high for 50% and LOW for 50% then we say that PWM pulse has a duty cycle of 50%. Similarly if 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 8051 Microcontroller doesn’t has this luxury means there’s no special PWM pins available in 8051 Microcontroller. But PWM is necessary so we are gonna 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 generation of PWM in 8051 Microcontroller.

How to Generate PWM in 8051 Microcontroller ???

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

pwm in 8051, 8051 pwm, 8051 pwm code, pwm in 8051 microcontroller, 8051 and pwm

  • 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 its correct or not.
  • Now, copy the below code and paste it in 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 above codes so it wont be much difficult to understand. If you have problem then ask in comments and I will resolve them.
  • Now in this code I have used PWM variable and I have given 127 to it as a starting value.
  • PWM pulse varies from 0 to 255 as its 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.
  • So, now when you upload the hex file and run your simulation then you will get below results:

pwm in 8051, 8051 pwm, 8051 pwm code, pwm in 8051 microcontroller, 8051 and pwm




  • Now you can check in the above figure that the duration of HIGH and LOW is same means the pulse is HIGH for 50% and LOW of 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 results:

pwm in 8051, 8051 pwm, 8051 pwm code, pwm in 8051 microcontroller, 8051 and pwm

  • Now you can easily compare above two figures and can get the difference. In the above figure now duty cycle has decreased as the HIGH timing of pulse is now reduced to 1/3 and pulse is LOW for 2/3 of the total time.
  • You can download both the simulation and the programming code for PWM in 8051 Microcontroller by clicking the below button:

Download PWM Code & Simulation

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 !!! 🙂

8 Comments

  1. Hi Sir,

    If I am going to use this PWM program to control my DC motor, how would the circuit looks like in Proteus. When I tried to connect the DC Motor to the same pin in simulation, the DC Motor just rotate and rotate and the status of the microcontroller pin is gray (undefined).

    Can you please provide me the schematic diagram.

    Thanks,

    Cris

    • Hi sir,

      I already got the answer of the above question. I used a driver (ULN2003) to drive my DC Motor. In the code above which I show below,
      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;
      }
      Can you explain this in detail?

      Thanks,

      Cris

  2. sir i have to varymy duty cycle according to ldr to get required output in led, so how can i get that type of program which will change interms of ldr and how the code will modified then?

  3. I am doing a project on street light sensing system, i need the led switch on in a dim brightness at night and become very bright when detected a vehicle, i haven’t learn this before,please help me?

  4. hello sir actually i wanted to produce pwm wave and i wanted to increse or decrease the duty cycle based on the status of input pins , whether the switch is pressed on input pins or not like that , so how can we do it???

Leave a Reply