Help needed! PWM speed increases but does not decreses

Thread Starter

0killingsoul0

Joined Mar 1, 2012
2
I am trying to make a pwm using 8051. I am using external interrupt 0 (pin 3.1) to increase speed and interrupt 1 (pin 3.2) to decrease speed. My code is working fine for increasing speed but it does not work for decreasing speed. i.e interrupt 1 is not working properly.






Rich (BB code):
#include<reg51.h>
 
 
 
 
unsigned char inc = 0;
 
void MSDelay(unsigned int);
void ex0_isr (void) interrupt 0
{
inc++;   // Increment the count
}
 
 
void ex1_isr (void) interrupt 1
{
inc=inc--;   // Deccrement the count
}
 
 
 
sbit pwm=P2^0;
sbit pwmn=P2^1;
sbit enable=P2^2;
 
 
 
 
 
void universal_delay(unsigned int);
 
void main( )
{     IT0 = 1;   // Configure interrupt 0 for falling edge on /INT0 (P3.2)
      IT1 = 1;   // Configure interrupt 1 for falling edge on /INT0 (P3.2)
      
      
      EX0 = 1;   // Enable EX0 Interrupt
      EX1 = 1;
      
      EA = 1;    // Enable Global Interrupt Flag
     
     enable=1;          
     
     pwm=0;       //  making outputs
     pwmn=0;
 
 
 
    
 
    while(1)
    {     
        universal_delay(inc);
    }
 
}
 
 
 
void universal_delay(unsigned int d)
{
            if (d==1)
            {   
                
                pwm=1;
                pwmn=0;
                
                MSDelay(50);      //  50 ms delay
                    
                pwm=0;
                pwmn=1;
 
                MSDelay(50);
                
            
            }
 
        else if (d== 2)
        
        {   
             pwm=1;
                pwmn=0;
                
                MSDelay(55);
                    
                pwm=0;
                pwmn=1;
 
                MSDelay(45);    
                    
            }
 
 
        else if (d== 3)
            {   
                 pwm=1;
                pwmn=0;
                
                MSDelay(60);    
                    
                pwm=0;
                pwmn=1;
 
                MSDelay(40);
        }
 
        
        else if (d==4)
            {    
                                pwm=1;
                pwmn=0;
                
                MSDelay(65);    
                    
                pwm=0;
                pwmn=1;
 
                MSDelay(35);
            }
 
            else if (d==5)
        
            {    pwm=1;
                pwmn=0;
                
                MSDelay(70);    
                    
                pwm=0;
                pwmn=1;
 
                MSDelay(30);
            
            }
 
        else if (d== 6)
        
            {   
                 pwm=1;
                pwmn=0;
                
                MSDelay(75);    
                    
                pwm=0;
                pwmn=1;
 
                MSDelay(30);
            }
 
        else if (d== 7)
              {
                 pwm=1;
                pwmn=0;
                
                MSDelay(75);    
                    
                pwm=0;
                pwmn=1;
 
                MSDelay(25);
                }
 
                    else if (d== 8)
              {
                 pwm=1;
                pwmn=0;
                
                MSDelay(80);    
                    
                pwm=0;
                pwmn=1;
 
                MSDelay(20);
                }
 
                else if (d== 9)
              {
                 pwm=1;
                pwmn=0;
                
                MSDelay(85);    
                    
                pwm=0;
                pwmn=1;
 
                MSDelay(15);
                }
                else if (d== 10)
              {
                 pwm=1;
                pwmn=0;
                
                MSDelay(90);    
                    
                pwm=0;
                pwmn=1;
 
                MSDelay(10);
                }
        
 
                    else if (d>10)
              {
                 pwm=1;
                pwmn=0;
                               
                MSDelay(100);   
                    
                pwm=0;
                pwmn=1;
 
                MSDelay(0);
                }
 
 
        
    
}
 
 
 
void MSDelay(unsigned int itime)
{
unsigned int i,j;
for (i=0;i<itime;i++)
for (j=0;j<1275;j++);
}
 

ErnieM

Joined Apr 24, 2011
8,377
Now this is a curious bit of code:
Rich (BB code):
    inc=inc--;   // Deccrement the count
Literally it says "assign the value of inc to inc, then decrement the value of inc." Exactly what such a concatenation of operations actually does is wildly dependent on the specific C implementation.

In other words, Simon sez "don't do that."

Rich (BB code):
    inc--;   // Decrement the count
would be a much better statement to use.

Also, while I have never used an 8051 I would have to question if the ISR's are correct or don't you have to reset the calling service request flag to keep an endless cascade of interrupts from happening?
 

Thread Starter

0killingsoul0

Joined Mar 1, 2012
2
Now this is a curious bit of code:
Rich (BB code):
    inc=inc--;   // Deccrement the count
Literally it says "assign the value of inc to inc, then decrement the value of inc." Exactly what such a concatenation of operations actually does is wildly dependent on the specific C implementation.

In other words, Simon sez "don't do that."

Rich (BB code):
    inc--;   // Decrement the count
would be a much better statement to use.

Also, while I have never used an 8051 I would have to question if the ISR's are correct or don't you have to reset the calling service request flag to keep an endless cascade of interrupts from happening?




Thanks for the inc-- thing. I just did it in hurry :). My first interrupt is working fine and the second interupt just stucks there. I am quite sure i am calling interrupt correctly. Just saw an example on keil website

 

pradeep23

Joined Dec 13, 2012
5
hello sir i am using the circuit also but i didnt get the output wat will be the problem.....

but if i put it's not accepting the interrupt the motor is continusly running what will be the problem can anyone help me in that..............
 
Last edited by a moderator:

pradeep23

Joined Dec 13, 2012
5
then how can i give that using interrupt......

shall i give some other port for interrupt......switch....

even i want to increase decrease the speed of dc motor how can i give for that help us to that want to change any other circuit or in program.....
 
Last edited by a moderator:

Ian Rogers

Joined Dec 12, 2012
1,136
I Thought you said you were using 0killingsoul0's circuit?

Rich (BB code):
void ex1_isr (void) interrupt 1
{
inc=inc--;   // Deccrement the count
}
should be
Rich (BB code):
void ex1_isr (void) interrupt 2
{
inc--;   // Deccrement the count
}
 

pradeep23

Joined Dec 13, 2012
5
then how can igive for that any suggestions..............

yes i am using the same circuit and code as well as.....but it's working simply motor is running thats it.......

i changed as like you say but it's not working.....
 
Last edited by a moderator:

pradeep23

Joined Dec 13, 2012
5
Rich (BB code):
#include<reg51.h>
 
 
 
 
unsigned char inc = 0;
 
void MSDelay(unsigned int);
void ex0_isr (void) interrupt 0
{
inc++;   // Increment the count
}
 
 
void ex1_isr (void) interrupt 1
{
inc--;   // Deccrement the count
}
 
 
 
sbit pwm=P2^0;
sbit pwmn=P2^1;
sbit enable=P2^2;
 
 
 
 
 
void universal_delay(unsigned int);
 
void main( )
{     IT0 = 1;   // Configure interrupt 0 for falling edge on /INT0 (P3.2)
      IT1 = 1;   // Configure interrupt 1 for falling edge on /INT0 (P3.2)
      
      
      EX0 = 1;   // Enable EX0 Interrupt
      EX1 = 1;
      
      EA = 1;    // Enable Global Interrupt Flag
     
     enable=1;          
     
     pwm=0;       //  making outputs
     pwmn=0;
 
 
 
    
 
    while(1)
    {     
        universal_delay(inc);
    }
 
}
 
 
 
void universal_delay(unsigned int d)
{
            if (d==1)
            {   
                
                pwm=1;
                pwmn=0;
                
                MSDelay(50);      //  50 ms delay
                    
                pwm=0;
                pwmn=1;
 
                MSDelay(50);
                
            
            }
 
        else if (d== 2)
        
        {   
             pwm=1;
                pwmn=0;
                
                MSDelay(55);
                    
                pwm=0;
                pwmn=1;
 
                MSDelay(45);    
                    
            }
 
 
        else if (d== 3)
            {   
                 pwm=1;
                pwmn=0;
                
                MSDelay(60);    
                    
                pwm=0;
                pwmn=1;
 
                MSDelay(40);
        }
 
        
        else if (d==4)
            {    
                                pwm=1;
                pwmn=0;
                
                MSDelay(65);    
                    
                pwm=0;
                pwmn=1;
 
                MSDelay(35);
            }
 
            else if (d==5)
        
            {    pwm=1;
                pwmn=0;
                
                MSDelay(70);    
                    
                pwm=0;
                pwmn=1;
 
                MSDelay(30);
            
            }
 
        else if (d== 6)
        
            {   
                 pwm=1;
                pwmn=0;
                
                MSDelay(75);    
                    
                pwm=0;
                pwmn=1;
 
                MSDelay(30);
            }
 
        else if (d== 7)
              {
                 pwm=1;
                pwmn=0;
                
                MSDelay(75);    
                    
                pwm=0;
                pwmn=1;
 
                MSDelay(25);
                }
 
                    else if (d== 8)
              {
                 pwm=1;
                pwmn=0;
                
                MSDelay(80);    
                    
                pwm=0;
                pwmn=1;
 
                MSDelay(20);
                }
 
                else if (d== 9)
              {
                 pwm=1;
                pwmn=0;
                
                MSDelay(85);    
                    
                pwm=0;
                pwmn=1;
 
                MSDelay(15);
                }
                else if (d== 10)
              {
                 pwm=1;
                pwmn=0;
                
                MSDelay(90);    
                    
                pwm=0;
                pwmn=1;
 
                MSDelay(10);
                }
        
 
                    else if (d>10)
              {
                 pwm=1;
                pwmn=0;
                               
                MSDelay(100);   
                    
                pwm=0;
                pwmn=1;
 
                MSDelay(0);
                }
 
 
        
    
}
 
 
 
void MSDelay(unsigned int itime)
{
unsigned int i,j;
for (i=0;i<itime;i++)
for (j=0;j<1275;j++);
}
i am using the same code only ..... but its not working.........
 
Last edited by a moderator:

Ian Rogers

Joined Dec 12, 2012
1,136
OMG!! I can think of easier ways to produce PWM


Try and use code tags otherwise it's too much effort to read the code..

You are still calling interrupt 1..... You need interrupt 2.

Rich (BB code):
#include<reg51.h>

unsigned char inc = 0;

void MSDelay(unsigned int);
void ex0_isr (void) interrupt 0
	{
	inc++; // Increment the count
	}


void ex1_isr (void) interrupt 2  // <-- This is the interrupt to use
	{
	inc--; // Deccrement the count
	}

sbit pwm=P2^0;
sbit pwmn=P2^1;
sbit enable=P2^2;


void universal_delay(unsigned int);

void main( )
	{ 
	IT0 = 1; // Configure interrupt 0 for falling edge on /INT0 (P3.2)
	IT1 = 1; // Configure interrupt 2 for falling edge on /INT0 (P3.2)

	EX0 = 1; // Enable EX0 Interrupt
	EX1 = 1;

	EA = 1; // Enable Global Interrupt Flag

	enable=1; 

	pwm=0; // making outputs
	pwmn=0;

	while(1)
		{ 
		universal_delay(inc);
		}

	}

void universal_delay(unsigned int d)
	{
	if (d==1)
		{ 
		pwm=1;
		pwmn=0;

		MSDelay(50); // 50 ms delay

		pwm=0;
		pwmn=1;

		MSDelay(50);

		}

	else if (d== 2)
		{ 
		pwm=1;
		pwmn=0;

		MSDelay(55);

		pwm=0;
		pwmn=1;

		MSDelay(45); 

		}

	else if (d== 3)
		{ 
		pwm=1;
		pwmn=0;

		MSDelay(60); 

		pwm=0;
		pwmn=1;

		MSDelay(40);
		}

	else if (d==4)
		{ 
		pwm=1;
		pwmn=0;

		MSDelay(65); 

		pwm=0;
		pwmn=1;

		MSDelay(35);
		}

	else if (d==5)
		{ 
		pwm=1;
		pwmn=0;

		MSDelay(70); 

		pwm=0;
		pwmn=1;

		MSDelay(30);

		}
	else if (d== 6)
		{ 
		pwm=1;
		pwmn=0;

		MSDelay(75); 

		pwm=0;
		pwmn=1;

		MSDelay(30);
		}

	else if (d== 7)
		{
		pwm=1;
		pwmn=0;

		MSDelay(75); 

		pwm=0;
		pwmn=1;

		MSDelay(25);
		}

	else if (d== 8)
		{
		pwm=1;
		pwmn=0;

		MSDelay(80); 

		pwm=0;
		pwmn=1;

		MSDelay(20);
		}

	else if (d== 9)
		{
		pwm=1;
		pwmn=0;

		MSDelay(85); 

		pwm=0;
		pwmn=1;

		MSDelay(15);
		}
		
	else if (d== 10)
		{
		pwm=1;
		pwmn=0;

		MSDelay(90); 

		pwm=0;
		pwmn=1;

		MSDelay(10);
		}

	else if (d>10)
		{
		pwm=1;
		pwmn=0;

		MSDelay(100); 

		pwm=0;
		pwmn=1;

		MSDelay(0);
		}
}

void MSDelay(unsigned int itime)
	{
	unsigned int i,j;
	for (i=0;i<itime;i++)
	for (j=0;j<1275;j++);
	}
I'm going to chuck this on ISIS and I'l get back to you..
 

Ian Rogers

Joined Dec 12, 2012
1,136
Two things.... The PWM period is 1 second.... What motor is it driving....

Most people use a 2khz+ period (2000 cycles not 1)...

Secondly. The universal_delay is a bit... well rubbish!

When I do PWM I use the interrupt to generate the duty and period... I then poll the switches and change the duty outside the interrupt...
 
Top