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?
The PCA cookbook www.intel.com/.../270609.htm
Erik