Aim:
In this tutorial 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.
In this tutorial 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.
Description:
Pulse width modulation is basically a square wave with a varying high
and low time. A basic PWM signal is shown in the figure below.
Pulse width modulation wave
There are various terms associated with PWM:
- On-Time: Duration of time signal is high
- Off-Time: Duration of time signal is low
- Period: It is represented as the sum of on-time and off-time of PWM signal
- Duty cycle: It is represented as percentage of time signal remains on during the period of the PWM signal
Pulse width modulation is basically a square wave with a varying high
and low time. A basic PWM signal is shown in the figure below.
Pulse width modulation wave
There are various terms associated with PWM:
- On-Time: Duration of time signal is high
- Off-Time: Duration of time signal is low
- Period: It is represented as the sum of on-time and off-time of PWM signal
- Duty cycle: It is represented as percentage of time signal remains on during the period of the PWM signal
Period
As shown in the the figure, Ton denotes the on-time and Toff denotes the off time of signal. Period is the sum of both on and off times and is calculated as shown in the equation below:
As shown in the the figure, Ton denotes the on-time and Toff denotes the off time of signal. Period is the sum of both on and off times and is calculated as shown in the equation below:
Duty Cycle
Duty cycle is calculated as on-time to the period of time. Using the period calculated above, duty cycle is calculated as:
Duty cycle is calculated as on-time to the period of time. Using the period calculated above, duty cycle is calculated as:
PWM: Voltage Regulation
PWM signal when used at a different duty cycles gives a varying voltage
at the output. This method is used in various areas of application like:
- Switching regulators
- LED dimmers
- Audio
- Analog signal generation
- and many more…
Voltage regulation is done by averaging the PWM signal. Output voltage is represented by the following equation:
As you can see from the equation the output voltage can be directly varied by varying the Ton value.
If Ton is 0, Vout is also 0. if Ton is Ttotal then Vout is Vin or say maximum.
PWM signal when used at a different duty cycles gives a varying voltage
at the output. This method is used in various areas of application like:
- Switching regulators
- LED dimmers
- Audio
- Analog signal generation
- and many more…
Voltage regulation is done by averaging the PWM signal. Output voltage is represented by the following equation:
As you can see from the equation the output voltage can be directly varied by varying the Ton value.
If Ton is 0, Vout is also 0. if Ton is Ttotal then Vout is Vin or say maximum.
Implementing PWM on 8051
The basic idea behind PWM implementation on 8051 is using timers and
switching port pin high/low at defined intervals. As we have discussed
in the introduction of PWM that by changing the Ton time, we can vary
the width of square wave keeping same time period of the square wave.
We will be using 8051 Timer0 in Mode 0. Values for high and low level
will be loaded in such a way that total delay remains same. If for high
level we load a value X in TH0 then for low level TH0 will be loaded
with 255-X so that total remains as 255.
The basic idea behind PWM implementation on 8051 is using timers and
switching port pin high/low at defined intervals. As we have discussed
in the introduction of PWM that by changing the Ton time, we can vary
the width of square wave keeping same time period of the square wave.
We will be using 8051 Timer0 in Mode 0. Values for high and low level
will be loaded in such a way that total delay remains same. If for high
level we load a value X in TH0 then for low level TH0 will be loaded
with 255-X so that total remains as 255.
Block Diagram
Schematic
Code
// ***********************************************
// Project: Interfacing PWM to 8051
// Author: Code Bloges
// Module description: Operate array of LED's
// ***********************************************
#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
}
// 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
}
// *********************************************** // Project: Interfacing PWM to 8051 // Author: Code Bloges // Module description: Operate array of LED's // *********************************************** #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 } // 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 }
Downloads:
The code was compiled in Keil uvision4 and simulation was made in Proteus v7.7.
To download code and proteus simulation click here.
Further Reading suggestions:
You may also like,
- Interfacing keypad with 8051
- Interfacing with UART of 8051 controller
- Interfacing SPI communication with 8051
- 8051 Displaying Custom Characters on LCD
- 8051 Graphical LCD
- RTC interfacing using I2C in 8051
- Interfacing ultrasonic sensor with 8051
- Interfacing GPS Modu with 8051
- Interfacing GSM Module with 8051
- ADC Module interfacing with 8051
- Interfacing keypad with 8051
- Interfacing with UART of 8051 controller
- Interfacing SPI communication with 8051
- 8051 Displaying Custom Characters on LCD
- 8051 Graphical LCD
- RTC interfacing using I2C in 8051
- Interfacing ultrasonic sensor with 8051
- Interfacing GPS Modu with 8051
- Interfacing GSM Module with 8051
- ADC Module interfacing with 8051
No comments:
Post a Comment