This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Having trouble varying pwm duty cycle

need to control the position of a dc motor and the circuit is configured that 50% is stop.. higher is one direction and lower is the other direction.. Im using AT89C51CC03:
im testing on two motors. the problem is i set motor1 on 50% and not control it but try control motor2, motor does not stop. motor2 changes direction with control but never stops at desired position.

#include <stdio.h>
#include <math.h>
#include <at89c51cc03.h>



main()
{
// Setup PWM mode

        CMOD = 0x02; //CPS1=0 CPS0 = 1; Setup PCA timer
        CL = 0x00;
        CH = 0x00;

        CCAP0L = 0x80;                  // Set the initial value same as CCAP0H
        CCAP0H = 0x80;                  // 50% Duty Cycle
        CCAP1L = 0x80;
        CCAP1H = 0x80;

        CCAPM0 = 0x42;                  // Setup PCA module 0 in PWM mode.
       CCAPM1 = 0x42
        CR = 1;                         // Start PCA Timer.*/

}
/


the above stops both motors and works independantly.

This is the code giving me problems:



#include <stdio.h>
#include <math.h>
#include <at89c51cc03.h>

/****define global constant control variables****/
#define KP 15 / 10        //proportional gain
#define KI 5 / 10         //integral gain
#define KD 10 / 10        //differential gain
#define DELAY 255         // approx 10ms delay time
#define MX_CHN 2          // set constant for max reads and channels

/****Prototype Functions****/
int readADC(int channel);         // function to read from ADC
void motor(int number, int speed);//function to set pwm of motor
void delay(void);

/****assign pins to external pins on the ADC****/
sbit BUSY = P3^2;
sbit HBEN = P2^1;
sbit WRi = P3^6;
sbit RDi = P3^7;

/******************declare global variables******************/
// this contains value to be written as MSB to Port 0, which is connected to the ADC. CHOOSES CHANNEL TO READ FROM
                 //  ch1,ch2,ch3,ch4,ch5,ch6,ch7,ch8  - adc Analogue In channels starting in array position 0 to 7
int wrMSB[MX_CHN] = {224,240};//,228,244,232,248,236,252};
int HBYTE, LBYTE;                                // stores 8MSB and 8LSB respectively from ADC



void main()
{
/****** local variables ********/
int adc_value1, adc_value2;                     //adc values
signed int joint;                               // joint channel
signed int glove;                               // glove channel
signed int error[MX_CHN];                       //error
signed int d_error[MX_CHN];                     //rate of change of error
signed int int_error[MX_CHN];                   //integral error
signed int last_error[MX_CHN];                  //last error store
signed int pwm;                                  //pwm output
/*** proportional + integral + differential Controls ***/
signed int p_out=0;                              //proportional output
signed int i_out=0;                              //integral output
signed int d_out=0;                              //differential output


/****** initialise PWM *********/
CMOD = 0x00;                                    // Setup PCA (Programmable Counter Array) counter mode register to use internal clock
CL = 0x00;                                      //counter high value
CH = 0x00;                                      //counter low value

/*set all pins to 50% duty-cycle as default*/
CCAP0L = 128;
CCAP0H = 128;

CCAP1L = 128;
CCAP1H = 128;

CCAP2L = 128;
CCAP2H = 128;

CCAP3L = 128;
CCAP3H = 128;

/* Set module/pin to PWM mode */
CCAPM0 = 0x42;
CCAPM1 = 0x42;
CCAPM2 = 0x42;
CCAPM3 = 0x42;
CR = 1;                                    // PCA timer start


while(1)
{
/****** loop starts ************/
 for(glove=0;glove<MX_CHN;glove+=2)
 {//for starts

 joint=glove+1;

 adc_value1 = readADC(glove);
 adc_value2 = readADC(joint);

 /***** ERRORS *****/
 error[glove] = adc_value1 - adc_value2;
 d_error[glove] = error[glove]-last_error[glove];
 int_error[glove]+= error[glove];

 /**limitting integral error**/
 if(int_error[glove] > 127)
        int_error[glove] = 127;
 if(int_error[glove] < -127)
        int_error[glove] = -127;

 /** Propotional, Integral, defferential controls **/
p_out = error[glove]*KP;
i_out = int_error[glove]*KI;
d_out = d_error[glove]*KD;
pwm = p_out+i_out+d_out;                // add all controls together

 /***limiting pwm output***/
if(pwm > 127)
        pwm = 127;
if(pwm < -127)
        pwm = -127;

last_error[glove]=error[glove];         // store error

motor(glove, pwm+127);
}//end if
}//end while
}//end main



I try change pwm in here:



void motor(int number, int speed)
{//start motor
switch(number) {//switch start case 0: // motor1 select { CCAP0H = speed; break; }
}//end switch
}//end motor



shortened the cases for simplicity in this case. any ideas whats wrong or how to go about it?