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;
00038 PE.DR.WORD &= ~0x0100;
00039 PE.DR.WORD |= (duty <= 0) ? 0 : 0x0100;
00040 } else {
00041 PFC.PECR1.WORD |= 0x0001;
00042 MTU3.TGRB = duty;
00043 }
00044 } else if (id == 1) {
00045 if (duty <= 0 || duty >= 255) {
00046 PFC.PECR1.WORD &= ~0x0010;
00047 PE.DR.WORD &= ~0x0400;
00048 PE.DR.WORD |= (duty <= 0) ? 0 : 0x0400;
00049 } else {
00050 PFC.PECR1.WORD |= 0x0010;
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
00068 if (mode == MTR_MODE_CCW_BREAK) {
00069 PE.DR.WORD |= 0x0020;
00070 PE.DR.WORD &= ~0x0080;
00071 } else if (mode == MTR_MODE_CW_BREAK) {
00072 PE.DR.WORD &= ~0x0020;
00073 PE.DR.WORD &= ~0x0080;
00074 } else {
00075 PE.DR.WORD |= 0x0080;
00076 }
00077
00078 } else if (id == 1) {
00079
00080 if (mode == MTR_MODE_CCW_BREAK) {
00081 PE.DR.WORD |= 0x0200;
00082 PE.DR.WORD &= ~0x0800;
00083 } else if (mode == MTR_MODE_CW_BREAK) {
00084 PE.DR.WORD &= ~0x0200;
00085 PE.DR.WORD &= ~0x0800;
00086 } else {
00087 PE.DR.WORD |= 0x0800;
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;
00112 MTU3.TCR.BYTE = 0x20 | 0x01;
00113 MTU3.TMDR.BYTE = 0xc2;
00114 MTU3.TIOR.BYTE.H = 0x12;
00115 MTU3.TIOR.BYTE.L = 0x12;
00116 MTU3.TGRA = MTU3.TGRC = 255;
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;
00124
00125 MTU.TSTR.BYTE |= 0xc0;
00126
00127 PFC.PECR1.WORD &= ~0x0044;
00128 PFC.PECR2.WORD &= ~0x4400;
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
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