[SOLVED] controlling pwm duty cycle using at89c51rd2

Status
Not open for further replies.

pravin b

Member level 5
Joined
May 20, 2012
Messages
85
Helped
2
Reputation
4
Reaction score
1
Trophy points
1,288
Location
Mumbai, India
Activity points
2,083
Hello Friends,

I am trying to control duty cycle of my pwm wave using at89c51rd2 & ADC0804. I am attaching my code and proteus simulation file here.
However I need to clear some of my doubts , please be nice as always.

1.I have seen sample code on internet for this application and constructed my own code following the same. But why I cant use TL0 to load the duty cycle values, why only TH0? My understanding is to use timer overflow flag after 255 counts….am I correct?

2.I am using timer0; however when I use T0 in mode 1(M1=0,M0=1) duty cycle changes abruptly at initial 25% and final 25% , why so? But when I use T0 in mode 0 duty cycle changes linealy with ADC values (0-255) (which seems to be correct! But…….).

3.Even with timer 0, mode0 I am unable to achieve 0% (at 0V) and 100%(at 5V) duty cycle. How should I do it? Do I have any bugs in my code, which is I am missing?

4.To control speed of DC motor what should be ideal frequency or frequency range? I assume that it should be greater than human audio range! With this design I am getting frequency of 11Hz, how can I change or control pwm wave frequency?

Thanks & regards,
Pravin

Here is my code...
Code:
#include<reg51.h>

#define adc_port P1
sbit pwm_pin=P3^4;
sbit rd=P3^0;
sbit wr=P3^1;
sbit intr=P3^2;
unsigned char pwm_width;
unsigned int adc_value;

int pwm_setup();
unsigned int adc_init();
void delay(unsigned int);

void main()
{
while(1)
	{
	adc_init();
	pwm_setup();
	}
}

unsigned int adc_init()			/*ADC initialization and read values from 0-255*/
{
adc_port=0xFF;
intr=1;
rd=0;
wr=0;
delay(2);
wr=1;
	while(intr==1)
	{
	rd=0;
	adc_value=adc_port;
	rd=1;
	}
	return(adc_value);
}

/*pwm setup with duty cycle controlled by adc_value (range 0-255)*/
int pwm_setup()  
{
TMOD=0x01;
pwm_width=adc_value;
EA=1;
ET0=1;
TR0=1;
return(pwm_width);
}

void delay(unsigned int count)	/*Delay function*/
{
int i,j;
for(i=0;i<=count;i++)			
	for(j=0;j<=1275;j++);
}

void timer0() interrupt 1	   /*Tomer0 ISR*/
{
TR0=0;
 if(pwm_pin==1)
 {
 pwm_pin=0;
 TH0=pwm_width;
 TF0=0;
 return; 
 }

 else
 {
 pwm_pin=1;
 TH0=255-pwm_width;
 TF0=0;
 return;
 }
}
 

Attachments

  • dc_motor.zip
    76.8 KB · Views: 86

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…