00001 //****************************************************************************** 00011 //****************************************************************************** 00012 00013 /* Copyright (c) 2008, Atmel Corporation All rights reserved. 00014 * 00015 * Redistribution and use in source and binary forms, with or without 00016 * modification, are permitted provided that the following conditions are met: 00017 * 00018 * 1. Redistributions of source code must retain the above copyright notice, 00019 * this list of conditions and the following disclaimer. 00020 * 00021 * 2. Redistributions in binary form must reproduce the above copyright notice, 00022 * this list of conditions and the following disclaimer in the documentation 00023 * and/or other materials provided with the distribution. 00024 * 00025 * 3. The name of ATMEL may not be used to endorse or promote products derived 00026 * from this software without specific prior written permission. 00027 * 00028 * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED 00029 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00030 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND 00031 * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, 00032 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00033 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00034 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00035 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00036 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00037 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00038 */ 00039 00040 00041 //_____ I N C L U D E S ___________________________________________________ 00042 #include "config.h" 00043 #include "mc_control.h" 00044 #include "mc_interface.h" 00045 00046 #include "dac\dac_drv.h" 00047 00048 U8 duty_cycle = 0; 00049 U8 regulation_type = OPEN_LOOP; 00050 U8 duty_cycle_reference = 0; 00051 U8 duty_cycle_filter_presc = 0; 00052 00053 /* Speed regulation variables */ 00054 S16 speed_error = 0; 00055 S16 last_speed_error = 0; 00056 S16 speed_integral = 0; 00057 S16 speed_integ = 0; 00058 S16 speed_proportional = 0; 00059 S16 speed_derivative = 0; 00060 S16 speed_der = 0; 00061 00062 /* Current regulation variables */ 00063 S16 cur_error = 0; 00064 S16 last_cur_error = 0; 00065 S16 cur_integral = 0; 00066 S16 cur_integ = 0; 00067 S16 cur_proportional = 0; 00068 S16 cur_derivative = 0; 00069 S16 cur_der = 0; 00070 00071 #define K_DUTY 1 00072 00073 /************************************************************************************************************/ 00074 /* Speed Regulation */ 00075 /************************************************************************************************************/ 00082 U8 mc_control_speed(U8 speed_cmd) 00083 { 00084 U8 Duty = 0; 00085 S32 increment = 0; 00086 00087 // Error calculation 00088 speed_error = speed_cmd - mci_get_measured_speed();// value -255 <=> 255 00089 00090 // proportional term calculation 00091 speed_proportional = Kp_speed*speed_error; 00092 00093 // integral term calculation 00094 /* speed_integral = speed_integral + speed_error; 00095 00096 if(speed_integral > 255) speed_integral = 255; 00097 if(speed_integral < -255) speed_integral = -255; 00098 00099 speed_integ = Ki_speed*speed_integral; 00100 */ 00101 speed_integral = Ki_speed*(speed_integral + speed_error); 00102 00103 if(speed_integral > 255) speed_integral = 255; 00104 if(speed_integral < -255) speed_integral = -255; 00105 00106 // derivative term calculation 00107 /*speed_derivative = speed_error - last_speed_error; 00108 00109 if(speed_derivative > 255) speed_derivative = 255; 00110 if(speed_derivative < -255) speed_derivative = -255; 00111 00112 speed_der = Kd_speed*speed_derivative; 00113 00114 last_speed_error = speed_error;*/ 00115 00116 // Duty Cycle calculation 00117 increment = speed_proportional + speed_integ; 00118 //increment += speed_der; 00119 increment = increment >> K_speed_scal; 00120 00121 // Variable saturation 00122 if(increment >= (S16)(255)) Duty = 255; 00123 else 00124 { 00125 if(increment <= (S16)(0)) Duty = 0; 00126 else Duty = (U8)(increment); 00127 } 00128 00129 // return Duty Cycle 00130 return Duty; 00131 } 00132 00133 /************************************************************************************************************/ 00134 /* Current Regulation */ 00135 /************************************************************************************************************/ 00142 U8 mc_control_current(U8 cur_cmd) 00143 { 00144 U8 Duty = 0; 00145 S32 increment = 0; 00146 00147 // Error calculation 00148 cur_error = cur_cmd - (mci_get_measured_current());// value -255 <=> 255 00149 00150 // proportional term calculation 00151 cur_proportional = Kp_cur*cur_error; 00152 00153 // integral term calculation 00154 cur_integral = cur_integral + cur_error; 00155 00156 if(cur_integral > 255) cur_integral = 255; 00157 if(cur_integral < -255) cur_integral = -255; 00158 00159 cur_integ = Ki_cur*cur_integral; 00160 00161 // derivative term calculation 00162 /*cur_derivative = cur_error - last_cur_error; 00163 00164 if(cur_derivative > 255) cur_derivative = 255; 00165 if(cur_derivative < -255) cur_derivative = -255; 00166 00167 cur_der = Kd_cur*cur_derivative; 00168 00169 last_cur_error = cur_error;*/ 00170 00171 // Duty Cycle calculation 00172 increment = cur_proportional + cur_integ; 00173 //increment += cur_der; 00174 increment = increment >> K_cur_scal; 00175 00176 // Variable saturation 00177 if(increment >= (S16)(255)) Duty = 255; 00178 else 00179 { 00180 if(increment <= (S16)(0)) Duty = 0; 00181 else Duty = (U8)(increment); 00182 } 00183 00184 // return Duty Cycle 00185 return Duty; 00186 } 00187 00188 00189 00190 /******************************************************************************/ 00191 /* Selection of Regulation Loop */ 00192 /******************************************************************************/ 00193 00196 void mc_regulation_loop() 00197 { 00198 switch(regulation_type) 00199 { 00200 case OPEN_LOOP : duty_cycle_reference = mci_get_ref_speed();break; 00201 case SPEED_LOOP : duty_cycle_reference = mc_control_speed(2*mci_get_ref_speed());break; 00202 case CURRENT_LOOP : duty_cycle_reference = mc_control_current(mc_get_potentiometer_value());break; 00203 default : break; 00204 } 00205 } 00206 00207 00210 void mc_set_open_loop(){regulation_type = OPEN_LOOP;} 00211 00212 00214 void mc_set_speed_loop(){regulation_type = SPEED_LOOP;} 00215 00216 00218 void mc_set_current_loop(){regulation_type = CURRENT_LOOP;} 00219 00220 00222 U8 mc_get_duty_cycle() 00223 { 00224 return duty_cycle; 00225 } 00226 00227 void duty_cycle_filter (void) 00228 { 00229 duty_cycle_filter_presc++; 00230 if (duty_cycle_filter_presc == 30) 00231 { 00232 duty_cycle_filter_presc = 0; 00233 if (duty_cycle < duty_cycle_reference) 00234 { 00235 duty_cycle = duty_cycle + K_DUTY; 00236 } 00237 else 00238 { 00239 if (duty_cycle > duty_cycle_reference) 00240 { 00241 duty_cycle = duty_cycle - K_DUTY; 00242 } 00243 } 00244 } 00245 }
1.5.7.1