Stepper Motor Driver library for Uni-polar type
Dependents: NucleoL152_stepper_w_lib
stepper.cpp
00001 /* 00002 * mbed library program 00003 * Stepping Motor 00004 * 00005 * Copyright (c) 2014 Kenji Arai / JH1PJL 00006 * http://www.page.sannet.ne.jp/kenjia/index.html 00007 * http://mbed.org/users/kenjiArai/ 00008 * Created: August 20th, 2014 00009 * Revised: August 23rd, 2014 00010 * 00011 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 00012 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE 00013 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00014 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00015 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00016 */ 00017 00018 #include "mbed.h" 00019 #include "stepper.h" 00020 00021 const uint8_t pase_cw[4][4] = {{1, 1, 0, 0}, {0, 1, 1, 0}, {0, 0, 1, 1}, {1, 0, 0, 1}}; 00022 const uint8_t pase_ccw[4][4] = {{1, 1, 0, 0}, {1, 0, 0, 1}, {0, 0, 1, 1}, {0, 1, 1, 0}}; 00023 extern uint8_t pls_width[]; 00024 00025 STEPPER::STEPPER (PinName xp, PinName xn, PinName yp, PinName yn): 00026 _xp(xp), _xn(xn), _yp(yp), _yn(yn) { 00027 init(); 00028 } 00029 00030 void STEPPER::move (int32_t steps){ 00031 if (steps < 0){ 00032 inf.direction = D_CCW; 00033 steps = -steps; 00034 } else { 00035 inf.direction = D_CW; 00036 } 00037 inf.total_step = steps; 00038 setup_mtr_drv_dt(&inf, &cntl); 00039 } 00040 00041 void STEPPER::set_max_speed (uint32_t time_base_us){ 00042 if (time_base_us < (MT_PLS_WIDTH_MIN * 1000)){ 00043 time_base_us = (MT_PLS_WIDTH_MIN * 1000); 00044 } 00045 _smdrv.attach_us(this, &STEPPER::millisec_inteval, time_base_us); 00046 } 00047 00048 uint8_t STEPPER::status (void){ 00049 return cntl.state; 00050 } 00051 00052 void STEPPER::init(void){ 00053 busy_sm_drv = 0; 00054 _xp = 0; 00055 _xn = 0; 00056 _yp = 0; 00057 _yn = 0; 00058 } 00059 00060 void STEPPER::set4ports (uint32_t step, int8_t dir){ 00061 uint8_t i; 00062 00063 i = (uint8_t)(step % 4); 00064 if (dir == D_CW) { 00065 _xp = pase_cw[i][0]; 00066 _xn = pase_cw[i][1]; 00067 _yp = pase_cw[i][2]; 00068 _yn = pase_cw[i][3]; 00069 } else { 00070 _xp = pase_ccw[i][0]; 00071 _xn = pase_ccw[i][1]; 00072 _yp = pase_ccw[i][2]; 00073 _yn = pase_ccw[i][3]; 00074 } 00075 } 00076 00077 void STEPPER::setup_mtr_drv_dt(Motor_Inf *mi, Motor_Control *mt){ 00078 busy_sm_drv = 1; 00079 if (mi->total_step == 0){ 00080 if (mt->state != M_STOP){ 00081 mt->state = M_CHANGE; 00082 mt->change_cnt = 5; 00083 mt->pls_width = 0; 00084 mt->ongoing = 0; 00085 mt->up_cnt = 0; 00086 mt->up_cnt_keep = 0; 00087 mt->down_cnt = 0; 00088 mt->continue_cnt = 0; 00089 } 00090 busy_sm_drv = 0; 00091 return; 00092 } 00093 if ((mt->state == M_CONTINUE) && ( mt->direction == mi->direction)){ 00094 if (mi->total_step < MT_SLOP_STEP){ 00095 mt->up_cnt = 0; 00096 mt->up_cnt_keep = 0; 00097 mt->down_cnt = mi->total_step; 00098 mt->continue_cnt = 0; 00099 mt->state = M_DOWN; 00100 mt->ongoing = 0; 00101 } else { 00102 mt->up_cnt = 0; 00103 mt->up_cnt_keep = 0; 00104 mt->down_cnt = MT_SLOP_STEP -1; 00105 mt->continue_cnt = mi->total_step - (MT_SLOP_STEP - 1); 00106 } 00107 } else { 00108 if ((mt->state == M_CONTINUE) && ( mt->direction != mi->direction)){ 00109 mt->state = M_CHANGE; 00110 mt->change_cnt = 5; 00111 } else { 00112 mt->motor_step = 0; 00113 mt->state = M_UP; 00114 } 00115 mt->pls_width = 0; 00116 mt->ongoing = 0; 00117 mt->direction = mi->direction; 00118 if (mi->total_step < MT_MIN_STEP){ 00119 if (mi->total_step == MT_MIN_STEP - 1){ 00120 mt->up_cnt = MT_SLOP_STEP; 00121 } else { 00122 mt->up_cnt = mi->total_step / 2; 00123 } 00124 mt->up_cnt_keep = mt->up_cnt; 00125 mt->down_cnt = mi->total_step - mt->up_cnt; 00126 mt->continue_cnt = 0; 00127 } else { 00128 mt->up_cnt = MT_SLOP_STEP; 00129 mt->up_cnt_keep = mt->up_cnt; 00130 mt->down_cnt = MT_SLOP_STEP -1 ; 00131 mt->continue_cnt = mi->total_step - MT_SLOP_STEP - (MT_SLOP_STEP - 1); 00132 } 00133 } 00134 busy_sm_drv = 0; 00135 } 00136 00137 void STEPPER::millisec_inteval() { 00138 if (busy_sm_drv == 1){ return;} 00139 switch (cntl.state){ 00140 case M_STOP: 00141 _xp = 0; 00142 _xn = 0; 00143 _yp = 0; 00144 _yn = 0; 00145 break; 00146 case M_UP: 00147 if (cntl.ongoing){ 00148 if (--cntl.pls_width == 0){ 00149 if (--cntl.up_cnt == 0){ 00150 cntl.ongoing = 0; 00151 if (cntl.continue_cnt == 0){ 00152 cntl.state = M_DOWN; 00153 } else { 00154 cntl.state = M_CONTINUE; 00155 } 00156 } else { 00157 set4ports(cntl.motor_step, cntl.direction); 00158 cntl.motor_step++; 00159 cntl.pls_width = pls_width[cntl.up_cnt_keep - cntl.up_cnt]; 00160 } 00161 } else { 00162 break; 00163 } 00164 } else { // 1st entry from M_STOP 00165 set4ports(cntl.motor_step, cntl.direction); 00166 cntl.motor_step++; 00167 cntl.pls_width = pls_width[cntl.up_cnt_keep - cntl.up_cnt]; 00168 cntl.ongoing = 1; 00169 } 00170 break; 00171 case M_CONTINUE: 00172 set4ports(cntl.motor_step, cntl.direction); 00173 cntl.motor_step++; 00174 if (--cntl.continue_cnt == 0){ 00175 cntl.ongoing = 0; 00176 cntl.state = M_DOWN; 00177 } 00178 break; 00179 case M_DOWN: 00180 if (cntl.ongoing){ 00181 if (--cntl.pls_width == 0){ 00182 if (--cntl.down_cnt == 0){ 00183 cntl.ongoing = 0; 00184 cntl.state = M_STOP; 00185 }else { 00186 set4ports(cntl.motor_step, cntl.direction); 00187 cntl.motor_step++; 00188 cntl.pls_width = pls_width[cntl.down_cnt]; 00189 } 00190 } else { 00191 break; 00192 } 00193 } else { // 1st entry from M_UP or M_CONTINUE 00194 set4ports(cntl.motor_step, cntl.direction); 00195 cntl.motor_step++; 00196 cntl.pls_width = pls_width[cntl.down_cnt]; 00197 cntl.ongoing = 1; 00198 } 00199 break; 00200 case M_CHANGE: 00201 if (cntl.ongoing){ 00202 if (--cntl.pls_width == 0){ 00203 if (--cntl.change_cnt == 0){ 00204 cntl.ongoing = 0; 00205 if (cntl.up_cnt == 0){ 00206 cntl.state = M_STOP; 00207 } else { 00208 cntl.state = M_UP; 00209 } 00210 }else { 00211 if (cntl.direction == D_CW){ 00212 set4ports(cntl.motor_step, D_CCW); 00213 } else { 00214 set4ports(cntl.motor_step, D_CW); 00215 } 00216 cntl.motor_step++; 00217 cntl.pls_width = pls_width[cntl.change_cnt]; 00218 } 00219 } else { 00220 break; 00221 } 00222 } else { // 1st entry 00223 if (cntl.direction == D_CW){ 00224 set4ports(cntl.motor_step, D_CCW); 00225 } else { 00226 set4ports(cntl.motor_step, D_CW); 00227 } 00228 cntl.motor_step++; 00229 cntl.pls_width = pls_width[cntl.change_cnt]; 00230 cntl.ongoing = 1; 00231 } 00232 break; 00233 default : 00234 cntl.state = M_STOP; 00235 } 00236 }
Generated on Tue Jul 19 2022 20:50:35 by
