motorCtrl.c

Go to the documentation of this file.
00001 
00010 #include "motorCtrl.h"
00011 #include "encCtrl.h"
00012 #ifdef SIMULATOR
00013 enum { SMP_USEC = 1000 };
00014 void set_mode(const unsigned char id, const int mode) {}
00015 void set_pwm(const unsigned char id, const int duty) {}
00016 #else
00017 #include <7040S.H>
00018 
00019 #include "tRunCtrl.h"
00020 #ifndef SMP_USEC
00021 #define SMP_USEC 1000
00022 #endif
00023 
00024 
00033 void set_pwm(const unsigned char id, const int duty) {
00034 
00035   if (id == 0) {
00036     if (duty <= 0 || duty >= 255) {
00037       PFC.PECR1.WORD &= ~0x0001; /* PE8 */
00038       PE.DR.WORD &= ~0x0100;
00039       PE.DR.WORD |= (duty <= 0) ? 0 : 0x0100;
00040     } else {
00041       PFC.PECR1.WORD |= 0x0001; /* TIOC3A */
00042       MTU3.TGRB = duty;
00043     }
00044   } else if (id == 1) {
00045     if (duty <= 0 || duty >= 255) {
00046       PFC.PECR1.WORD &= ~0x0010; /* PE10 */
00047       PE.DR.WORD &= ~0x0400;
00048       PE.DR.WORD |= (duty <= 0) ? 0 : 0x0400;
00049     } else {
00050       PFC.PECR1.WORD |= 0x0010; /* TIOC3C */
00051       MTU3.TGRD = duty;
00052     }
00053   }
00054 }
00055 
00056 
00065 void set_mode(const unsigned char id, const int mode) {
00066   if (id == 0) {
00067     /* DIR(PE5), EN(PE7) */
00068     if (mode == MTR_MODE_CCW_BREAK) {
00069       PE.DR.WORD |= 0x0020;     /* DIR(PE5)=1 */
00070       PE.DR.WORD &= ~0x0080;    /* EN(PE7)=0 */
00071     } else if (mode == MTR_MODE_CW_BREAK) {
00072       PE.DR.WORD &= ~0x0020;    /* DIR(PE5)=0 */
00073       PE.DR.WORD &= ~0x0080;    /* EN(PE7)=0 */
00074     } else {                    /* MTR_MODE_FREE */
00075       PE.DR.WORD |= 0x0080;     /* EN(PE7)=1 */
00076     }
00077 
00078   } else if (id == 1) {
00079     /* DIR(PE9), EN(PE11) */
00080     if (mode == MTR_MODE_CCW_BREAK) {
00081       PE.DR.WORD |= 0x0200;     /* DIR(PE9)=1 */
00082       PE.DR.WORD &= ~0x0800;    /* EN(PE11)=1 */
00083     } else if (mode == MTR_MODE_CW_BREAK) {
00084       PE.DR.WORD &= ~0x0200;    /* DIR(PE9)=0 */
00085       PE.DR.WORD &= ~0x0800;    /* EN(PE11)=1 */
00086     } else {                    /* MTR_MODE_FREE */
00087       PE.DR.WORD |= 0x0800;     /* EN(PE11)=1 */
00088     }
00089   }
00090 }
00091 
00092 
00093 // 直接制御用
00094 void setDirectMotorMode(unsigned char id, int mode) {
00095   set_mode(id, mode);
00096 }
00097 
00098 void setDirectMotorPwm(unsigned char id, int duty) {
00099   set_pwm(id, duty);
00100 }
00101 
00102 
00108 void initMotor(void) {
00109   int i;
00110 
00111   PFC.PEIOR.WORD |= 0x0500;     /* use TIOC3A, TIOC3C port */
00112   MTU3.TCR.BYTE = 0x20 | 0x01;  /* cycle=TGRA, duty=TGRB, cycle/4 */
00113   MTU3.TMDR.BYTE = 0xc2;        /* pwm mode 1, buffer disable */
00114   MTU3.TIOR.BYTE.H = 0x12;      /* CMA=0, CMB=1 */
00115   MTU3.TIOR.BYTE.L = 0x12;      /* CMC=0, CMD=1 */
00116   MTU3.TGRA = MTU3.TGRC = 255;  /* cycle */
00117 
00118   for (i = 0; i <= 1; ++i) {
00119     set_pwm(i, 0);
00120     set_mode(i, MTR_MODE_FREE);
00121   }
00122 
00123   PFC.PECR1.WORD |= 0x0011;     /* use TGRA, TGRC port */
00124 
00125   MTU.TSTR.BYTE |= 0xc0;        /* pwm active */
00126 
00127   PFC.PECR1.WORD &= ~0x0044;    /* TIOC3B, TIOC3D */
00128   PFC.PECR2.WORD &= ~0x4400;    /* TIOC1B, TIOC2B */
00129   PFC.PEIOR.WORD |= 0x0aa0;
00130 }
00131 #endif
00132 
00133 
00142 void initMotorInfo(const unsigned char id, motorInfo_t *mtr) {
00143   mtr->id = id;
00144   mtr->gain_p = MTR_GAIN_P;
00145   mtr->gain_i = MTR_GAIN_I;
00146   mtr->i_value = 0;
00147 
00148   mtr->r_per_v = (int)((1<<MTR_I_BIT_WIDTH) * MTR_OHM / MTR_POWER);
00149   mtr->ke_per_v = (int)(1.0 / MTR_RPM_PER_V
00150                         * 60 * 1000 / (SMP_USEC / 1000)
00151                         * (1 << MTR_I_BIT_WIDTH) / (MTR_POWER * ENC_PULSE));
00152 }
00153 
00154 
00183 static int calcGainOutput(const int ref_cnt, const int cnt_diff,
00184                           motorInfo_t *mtr) {
00185   int diff;
00186   int output;
00187 
00188   diff = ref_cnt - cnt_diff;
00189   mtr->i_value += diff;
00190   if (mtr->i_value > I_VALUE_MAX) {
00191     mtr->i_value = I_VALUE_MAX;
00192   } else if (mtr->i_value < -I_VALUE_MAX) {
00193     mtr->i_value = -I_VALUE_MAX;
00194   }
00195   output = (mtr->gain_p * diff) + (mtr->gain_i * mtr->i_value);
00196   output <<= (MTR_I_BIT_WIDTH - 10);
00197 
00198   return output;
00199 }
00200 
00201 
00202 // モータに対して、MTR_I_BIT_SHIF シフトされた電流[A] を流すように設定する
00203 static int calcInvertedCtrlPwm(const int output, const int cnt_diff,
00204                                motorInfo_t *mtr) {
00205 
00206   int sign;
00207   int pwm;
00208 
00209   pwm = (mtr->r_per_v * output) + (mtr->ke_per_v * cnt_diff);
00210   sign = (pwm < 0) ? -1 : +1;
00211   pwm = (sign * pwm) >> ((MTR_I_BIT_WIDTH << 1) - 8);
00212   if (pwm > 0xff) {
00213     pwm = 0xff;
00214   }
00215   return (sign * pwm);
00216 }
00217 
00218 
00226 void setMotorFree(motorInfo_t *mtr) {
00227   set_mode(mtr->id, MTR_MODE_FREE);
00228 }
00229 
00230 
00242 int setMotorRevolution(const int ref_cnt, const int cnt_diff,
00243                        motorInfo_t *mtr) {
00244   int ref_pwm;
00245   int mode;
00246   int pwm;
00247   int output;
00248 
00249   output = calcGainOutput(ref_cnt, cnt_diff, mtr);
00250   ref_pwm = calcInvertedCtrlPwm(output, cnt_diff, mtr);
00251   mode = (ref_pwm >= 0) ? MTR_MODE_CW_BREAK : MTR_MODE_CCW_BREAK;
00252   pwm = (ref_pwm >= 0) ? ref_pwm : -ref_pwm;
00253 
00254   set_pwm(mtr->id, pwm);
00255   set_mode(mtr->id, mode);
00256 
00257   return ref_pwm;
00258 }
00259 

Generated on Mon Apr 13 22:52:01 2009 by  doxygen 1.5.7.1