Most of the Electronics and Electrical people are aware of what is PWM?
If you are not, then let me explain. PWM stand for Pulse Width Modulation – means width of pulse is varied. Pulse width means ON time of pulse. Keeping the total time (frequency) fixed, on time and off time are changed (if on time increased, off time decreased and vice versa). There is very popular term known as duty cycle that is ratio of on time to total time
Duty cycle = on time / total time = on time / (on time + off time)
Its always measured in % and it directly indicates on time of pulse – that means width of pulse. For example duty cycle is 30 % means on time is 30% of total time – that means pulse width is 30 %. If total time is 10 ms then pulse width is of 3 ms.
PWM output is mainly used in
· Varying speed of DC motor
· Varying intensity of LED light
· Generating variable frequency wave output in VFD AC drives
The frequency at which PWM is generated is very important because some application requires high frequency PWM in terms of KHz while some devices operate at low frequency PWM. So in PWM we can change two parameters
1. Frequency
2. Duty cycle – pulse width
The project given here generates PWM at different frequencies like 100 Hz, 200 Hz, 500 Hz, 1KHz, 2 KHz, 5 KHz and 10 KHz. And it varies the pulse width from 10% to 100 % in step of 10. The frequency and desire pulse width can be selected and the project generates pulses of selected width at given frequency continuously. It uses 8 bit micro controller AT89C51 to generate this programmable PWM.
Circuit description:
As shown in figure the circuit is built using micro controller AT89C51, LCD and few other components like push buttons, resistors, capacitors etc.
· Four push buttons are connected to port P1 pins P1.0 to P1.3 that connects pins to ground when pressed. They will give logic 0 input to respective pin when pressed
· Port P0 drives data pins D0 – D7 of LCD. Two control pins Rs and En of LCD are connected to P2.7 and P2.6 respectively. Third control pin RW is connected to ground that makes LCD write always enable
· The PWM output is generated from P2.0 pin. It can be connected to CRO or DSO to observe generated PWM*
· A 12MHz crystal with two 33 pF capacitors is connected to crystal input pins as shown. It provides required clock to micro controller for its working and all internal operation
· The circuit works on 5 V supply that is given from external power supply source
* note : the PWM generated is of 5 V. If any one wants to have PWM output of higher volt (say 10 V or 15 V) then addition OP-AMP LM741 circuit can be connected at this output pin P2.0.
Working and operation:
· When the supply is given to circuit, the first message displayed on LCD as “set frequency” and it asks the user to set desire frequency
· The user can select desire frequency by pressing inc or dec button. User can select any one frequency from given 7 different frequencies – 100 Hz, 200 Hz, 500 Hz, 1KHz, 2 KHz, 5 KHz and 10 KHz
· After selecting the frequency the user has to press set button. The message is displayed as “the frequency is set to ______”
· Next it ask to set duty cycle in %
· Again the user has to press inc or dec button to increase/decrease duty cycle by 10%
· After selecting, again user has to press set button. The message is displayed as “the duty is set to _____ “
· Finally it asks to press start button to generate PWM
· When gen button is pressed, the desire PWM is generated on P2.0 pin that can be observed on CRO / DSO and also the message on LCD is displayed as “PWM : xx % @ xxx Hz Press Reset to off”
Software program:
The software program loaded in to internal memory (FLASH) of micro controller is responsible or above working and operation of circuit. The program takes care of all the following tasks
· Takes user inputs through buttons
· Handles LCD and displays messages and values
· Calculates on time and off time from entered frequency and duty cycle
· Calculates the count to be loaded into timers to generate this on time and off time
· Generates perfect PWM of entered frequency and duty cycle
The program is written in embedded C language for 8051 family of micro controllers. it is compiled for generic 8051 micro controllers using KEIL software. When it is compiled the hex file is generated. This hex file is loaded in to internal FLASH of AT89C51 using suitable programming HW and SW tools. Here is the complete C program code.
Project Source Code
###
#include<reg51.h> // header file
#include <string.h>
#define lcd_data_bus P0
int freq_value=0,duty=50;
int freq[7] = {100,200,500,1000,2000,5000,10000};
unsigned int freq_set_flag=1,duty_set_flag=0,freq_in_KHz_flag=0,duty_flag=0;
sbit rs = P2^7;
sbit en = P2^6;
sbit op = P2^0;
void lcddly()
{
int x;
for(x=0;x<1500;x++);
}
void message_display_delay()
{
int m,n;
for(m=0;m<30;m++)
for(n=0;n<10000;n++);
}
void key_press_delay()
{
int m,n;
for(m=0;m<150;m++)
for(n=0;n<1000;n++);
}
void lcd_send_cmd(unsigned char a)
{
lcddly();
rs = 0;
lcd_data_bus = a;
en = 1;
en = 0;
}
void lcd_send_data(unsigned char b)
{
lcddly();
rs = 1;
lcd_data_bus = b;
en = 1;
en = 0;
}
void lcd_print(unsigned char *s)
{
unsigned char l,i;
l = strlen(s);
for(i=1;i<=l;i++)
{
lcd_send_data(*s);
s++;
}
}
void initialize()
{
P3 = 0x00;
P2 = 0x00;
P1 = 0xFF;
TMOD = 0x01;
}
void display_data(unsigned int value)
{
unsigned char ascii_value[3];
unsigned int tmp,t;
if(value<100)
{
tmp = value%10;
ascii_value[1] = tmp+0x30;
value = value/10;
ascii_value[0] = value+0x30;
ascii_value[2] = 0x20;
freq_in_KHz_flag=0;
}
else if((value>=100) && (value<1000)) // if value is of 3 digits
{
tmp = value%10; // do same
ascii_value[2] = tmp+0x30;
value = value/10;
tmp = value%10;
ascii_value[1] = tmp+0x30;
value = value/10;
ascii_value[0] = value+0x30;
freq_in_KHz_flag = 0;
}
else if (value>=1000)
{
value = value/1000;
if(value<10)
{
ascii_value[0] = value+0x30;
ascii_value[1] = 0x20;
ascii_value[2] = 0x20;
}
else
{
tmp = value%10;
ascii_value[1] = tmp+0x30;
value = value/10;
ascii_value[0] = value+0x30;
ascii_value[2] = 0x20;
}
freq_in_KHz_flag = 1;
}
for(t=0;t<=2;t++) lcd_send_data(ascii_value[t]); // print value
}
/////////////////////// function for up-arrow key //////////////////////
void up_arrow_key()
{
if(freq_set_flag==1)
{
if(freq_value<7) freq_value++;
else if(freq_value == 8) freq_value = 0;
lcd_send_cmd(0xC0);
duty_flag=0;
display_data(freq[freq_value]);
if(freq_in_KHz_flag == 1) lcd_print("KHz");
else lcd_print(" Hz");
}
else if(duty_set_flag==1)
{
if(duty<100) duty+=10;
lcd_send_cmd(0xC0);
duty_flag=1;
display_data(duty); // display
if(duty_flag==1) lcd_send_data('%');
}
}
///////////////////// function for down-arrow key ///////////////////////
void down_arrow_key()
{
if(freq_set_flag==1) // to set frequency
{
if(freq_value>0) freq_value--; // increase frequency and
lcd_send_cmd(0xC0);
duty_flag=0;
display_data(freq[freq_value]); // display
if(freq_in_KHz_flag == 1) lcd_print("KHz");
else lcd_print(" Hz");
}
else if(duty_set_flag==1) // or set duty
{
if(duty>10) duty-=10;
lcd_send_cmd(0xC0);
duty_flag=1;
display_data(duty); // display
lcd_send_data('%');
}
}
///////////////////////// function for enter key ////////////////////////
void enter_key()
{
if(freq_set_flag==1) // when pressed to set frequency
{
lcd_send_cmd(0x80);
lcd_print("freq is set to "); // display message and
lcd_send_cmd(0xC0);
display_data(freq[freq_value]); // set frequ value
freq_set_flag=0;
message_display_delay(); // and after 2 second
lcd_send_cmd(0x01);
lcd_print("set duty cycle"); // again display message
lcd_send_cmd(0xC0);
lcd_print("50 %");
duty_set_flag=1;
duty_flag = 1;
}
else if(duty_set_flag==1) // when pressed to set duty
{
lcd_send_cmd(0x01);
lcd_print("duty is set to"); // display message as
lcd_send_cmd(0xC0);
display_data(duty);
lcd_send_data('%');
message_display_delay(); // after 2 seconds
lcd_send_cmd(0x01);
lcd_print("press start"); // again display message
}
}
//////////////////// function for start key //////////////////////////////
void start_key()
{
int load_value1, load_value2;
long time,on_time,off_time;
time = 1000000 / freq[freq_value];
on_time = (time*duty)/100;
off_time = time - on_time;
load_value1 = 0xFFFF - on_time;
load_value2 = 0xFFFF - off_time;
lcd_send_cmd(0x01);
lcd_print("PWM:");
display_data(duty);
lcd_send_data('%');
lcd_send_data('@');
display_data(freq[freq_value]);
if(freq_in_KHz_flag == 1) lcd_print("KHz");
else lcd_print("Hz");
lcd_send_cmd(0xC0);
lcd_print("Press RST to OFF");
TR0 = 1;
while(1)
{
TL0 = load_value1 & 0x00FF;
TH0 = (load_value1 & 0xFF00)>>8;
op = 1;
led = 0;
while(TF0==0);
op = 0;
TF0 = 0;
TL0 = load_value2 & 0x00FF;
TH0 = (load_value2 & 0xFF00)>>8;
while(TF0==0);
TF0 = 0;
}
}
void main()
{
initialize();
lcd_send_cmd(0x3C);
lcd_send_cmd(0x0E);
lcd_send_cmd(0x01);
lcd_print("set frequency");
lcd_send_cmd(0xC0);
display_data(freq[freq_value]);
lcd_print(" Hz");
while(1)
{
while(P1==0xFF);
switch(P1)
{
case 0xFE:
up_arrow_key();
break;
case 0xFD:
down_arrow_key();
break;
case 0xFB:
enter_key();
break;
case 0xF7:
start_key();
}
key_press_delay();
}
}
###
Circuit Diagrams
Project Video
Filed Under: Electronic Projects
Filed Under: Electronic Projects
Questions related to this article?
👉Ask and discuss on EDAboard.com and Electro-Tech-Online.com forums.
Tell Us What You Think!!
You must be logged in to post a comment.