LV8548 Motor Driver Stepper Motor Dc MOtor
Dependents: LV8548_ON_MD_Modlle_kit_DCMtr_And_STEPMtr
LV8548.cpp
00001 /** 00002 [LV8548.cpp] 00003 Copyright (c) [2018] [YAMASHO] 00004 This software is released under the MIT License. 00005 http://opensource.org/licenses/mit-license.php 00006 */ 00007 00008 #include "LV8548.h" 00009 #include "mbed.h" 00010 00011 #define _DEBUG_ (0) 00012 00013 #define COIL_A (0X1) 00014 #define COIL_B (0X2) 00015 #define COIL_C (0X4) 00016 #define COIL_D (0X8) 00017 00018 00019 00020 const uint8_t FullStepDrivePattern[STEPPHASEMAX] = 00021 #if 0 00022 {(COIL_A | COIL_D), 00023 (COIL_A | COIL_D), 00024 (COIL_A | COIL_B), 00025 (COIL_A | COIL_B), 00026 (COIL_B | COIL_C), 00027 (COIL_B | COIL_C), 00028 (COIL_C | COIL_D), 00029 (COIL_C | COIL_D)}; 00030 #else 00031 /// orgin 00032 {(COIL_A | COIL_C), 00033 (COIL_A | COIL_C), 00034 (COIL_B | COIL_C), 00035 (COIL_B | COIL_C), 00036 (COIL_B | COIL_D), 00037 (COIL_B | COIL_D), 00038 (COIL_A | COIL_D), 00039 (COIL_A | COIL_D)}; 00040 00041 #endif 00042 const uint8_t HaleStepDrivePattern[STEPPHASEMAX ] = 00043 #if 0 00044 {(COIL_A | COIL_D), 00045 (COIL_A), 00046 (COIL_A | COIL_B), 00047 (COIL_B), 00048 (COIL_B | COIL_C), 00049 (COIL_C), 00050 (COIL_C | COIL_D), 00051 (COIL_D)}; 00052 #else 00053 /// orgin 00054 {(COIL_A), 00055 (COIL_A | COIL_C), 00056 (COIL_C), 00057 (COIL_B | COIL_C), 00058 (COIL_B), 00059 (COIL_B | COIL_D), 00060 (COIL_D), 00061 (COIL_A | COIL_D)}; 00062 00063 #endif 00064 00065 00066 00067 LV8548::LV8548(PinName in1, PinName in2, PinName in3, PinName in4, DriverType drivertype,uint16_t baseus): 00068 _in1(in1),_in2(in2),_in3(in3),_in4(in4),_Drivertype(drivertype),_baseus(baseus) { 00069 00070 _in1 = 0; 00071 _in2 = 0; 00072 _in3 = 0; 00073 _in4 = 0; 00074 00075 _Pwmmode[MOTOR_A] = FWD_OPEN; 00076 _Pwmmode[MOTOR_B] = FWD_OPEN; 00077 00078 _Pwmout[MOTOR_A] = OUTPUT_OFF; 00079 _Pwmout[MOTOR_B] = OUTPUT_OFF; 00080 00081 _PwmPeriod[MOTOR_A] = 0.02f; // 20ms 00082 _PwmPeriod[MOTOR_B] = 0.02f; // 20ms 00083 00084 _PwmDuty[MOTOR_A] = 1.0f; // Duyt 100% 00085 _PwmDuty[MOTOR_B] = 1.0f; // Duyt 100% 00086 00087 if(_Drivertype == DCMOTOR ) return; // DC MotorにはTimerはない。 00088 if(_baseus == 0) return; // 0us のタイマも無し. 00089 00090 float TimeVal = (float)_baseus / 1000000; 00091 #if _DEBUG_ 00092 printf("TimerSetting %f",TimeVal); 00093 #endif 00094 _Lv8548BaseTimer.attach(this,&LV8548::SetStepTimerInt, TimeVal ); 00095 } 00096 00097 void LV8548::SetDcMotorStop(uint8_t ch) 00098 { 00099 if( _Drivertype != DCMOTOR ) return; 00100 if(ch == MOTOR_A) 00101 { 00102 _in1.write(0.0f); 00103 _in2.write(0.0f); 00104 } 00105 else 00106 { 00107 _in3.write(0.0f); 00108 _in4.write(0.0f); 00109 } 00110 } 00111 00112 void LV8548::SetDcMotor(uint8_t ch) 00113 { 00114 if( _Drivertype != DCMOTOR ) return; 00115 #if _DEBUG_ 00116 printf("Motor Set %2x %2x ",ch ,_Pwmout[ch]); 00117 #endif 00118 switch( _Pwmout[ch] ) 00119 { 00120 default: /* OUTPUT_OFF*/ 00121 if(ch == MOTOR_A) 00122 { 00123 _in1.write(0.0f); 00124 _in2.write(0.0f); 00125 #if _DEBUG_ 00126 printf("1:0.0 2:0.0 "); 00127 #endif 00128 } 00129 else 00130 if(ch == MOTOR_B) 00131 { 00132 _in3.write(0.0f); 00133 _in4.write(0.0f); 00134 #if _DEBUG_ 00135 printf("3:0.0 4:0.0 "); 00136 #endif 00137 } 00138 break; 00139 case OUTPUT_BRAKE: 00140 if(ch == MOTOR_A) 00141 { 00142 _in1.write(1.0f); 00143 _in2.write(1.0f); 00144 #if _DEBUG_ 00145 printf("1:1.0 2:1.0 "); 00146 #endif 00147 } 00148 else 00149 if(ch == MOTOR_B) 00150 { 00151 _in3.write(1.0f); 00152 _in4.write(1.0f); 00153 #if _DEBUG_ 00154 printf("3:1.0 4:1.0 "); 00155 #endif 00156 } 00157 break; 00158 case OUTPUT_START: 00159 if(ch == MOTOR_A) 00160 { 00161 switch(_Pwmmode[MOTOR_A]) 00162 { 00163 case FWD_BRAKE: /** FWD_BREAKE */ 00164 _in1.write(1.0f); 00165 _in2.write(1.0f-_PwmDuty[MOTOR_A]); 00166 #if _DEBUG_ 00167 printf("1:%f 2:1.0 ",_PwmDuty[MOTOR_A]); 00168 #endif 00169 break; 00170 case RVS_OPEN: /** REVERS OPEN */ 00171 _in1.write(0.0f); 00172 _in2.write(_PwmDuty[MOTOR_A]); 00173 #if _DEBUG_ 00174 printf("1:0.0 2:%f ",_PwmDuty[MOTOR_A]); 00175 #endif 00176 break; 00177 case RVS_BRAKE: /** REVSRS BRAKE */ 00178 _in1.write(1.0f-_PwmDuty[MOTOR_A]); 00179 _in2.write(1.0f); 00180 #if _DEBUG_ 00181 printf("1:1.0 2:%f ",_PwmDuty[MOTOR_A]); 00182 #endif 00183 break; 00184 default: /* FWD_OPEN */ 00185 _in1.write(_PwmDuty[MOTOR_A]); 00186 _in2.write(0.0f); 00187 #if _DEBUG_ 00188 printf("1:%f 2:0.0 ",_PwmDuty[MOTOR_A]); 00189 #endif 00190 break; 00191 } 00192 } 00193 else 00194 if(ch == MOTOR_B) 00195 { 00196 switch(_Pwmmode[MOTOR_B]) 00197 { 00198 case FWD_BRAKE: /** FWD_BREAKE */ 00199 _in3.write(1.0f); 00200 _in4.write(1.0f-_PwmDuty[MOTOR_B]); 00201 #if _DEBUG_ 00202 printf("3:%f 4:1.0 ",_PwmDuty[MOTOR_B]); 00203 #endif 00204 break; 00205 case RVS_OPEN: /** REVERS OPEN */ 00206 _in3.write(0.0f); 00207 _in4.write(_PwmDuty[MOTOR_B]); 00208 #if _DEBUG_ 00209 printf("3:0.0 4:%f",_PwmDuty[MOTOR_B]); 00210 #endif 00211 break; 00212 case RVS_BRAKE: /** REVSRS BRAKE */ 00213 _in3.write(1.0f-_PwmDuty[MOTOR_B]); 00214 _in4.write(1.0f); 00215 #if _DEBUG_ 00216 printf("3:1.0 4:%f ",_PwmDuty[MOTOR_B]); 00217 #endif 00218 break; 00219 default: /*FWD_OPEN FWD_OPEN */ 00220 _in3.write(_PwmDuty[MOTOR_B]); 00221 _in4.write(0.0f); 00222 #if _DEBUG_ 00223 printf("3:%f 4:0.0 ",_PwmDuty[1]); 00224 #endif 00225 break; 00226 } 00227 } 00228 break; 00229 } 00230 #if _DEBUG_ 00231 printf("\n"); 00232 #endif 00233 00234 } 00235 /***************************************************************************************************/ 00236 /* FFFFFF DDDD MM MM */ 00237 /* FF DD DD MMM MMM tt */ 00238 /* FF oooo rrrrr DD DD cccc MMMMMMM oooo tttttt oooo rrrrr */ 00239 /* FFFF oo oo rr rr DD DD cc MM M MM oo oo tt oo oo rr rr */ 00240 /* FF oo oo rr DD DD cc MM MM oo oo tt oo oo rr */ 00241 /* FF oo oo rr DD DD cc MM MM oo oo tt oo oo rr */ 00242 /* FF oooo rr DDDD cccc MM MM oooo ttt oooo rr */ 00243 /* */ 00244 /***************************************************************************************************/ 00245 void LV8548::SetDcPwmFreqency( uint8_t ch ,float Freq ) 00246 { 00247 if( _Drivertype != DCMOTOR ) return; 00248 00249 if(ch == MOTOR_A) 00250 { 00251 SetDcMotorStop(MOTOR_A); 00252 _PwmPeriod[MOTOR_A] = 1/Freq; 00253 #if USE_PWM_PORT 00254 _in1.period( _PwmPeriod[MOTOR_A] ); 00255 _in2.period( _PwmPeriod[MOTOR_A] ); 00256 #endif 00257 SetDcMotor(MOTOR_A); 00258 #if _DEBUG_ 00259 printf("freq0 : %f ",_PwmPeriod[MOTOR_A]); 00260 #endif 00261 }else 00262 if(ch == MOTOR_B) 00263 { 00264 SetDcMotorStop(MOTOR_B); 00265 _PwmPeriod[MOTOR_B] = 1/Freq; 00266 #if USE_PWM_PORT 00267 _in3.period( _PwmPeriod[MOTOR_B] ); 00268 _in4.period( _PwmPeriod[MOTOR_B] ); 00269 #endif 00270 #if _DEBUG_ 00271 printf("freq1 : %f ",_PwmPeriod[MOTOR_B]); 00272 #endif 00273 SetDcMotor(MOTOR_B); 00274 } 00275 00276 } 00277 00278 void LV8548::SetDcPwmMode( uint8_t ch ,DriverPwmMode Mode ) 00279 { 00280 if(ch < MOTOR_MAX) 00281 { 00282 #if _DEBUG_ 00283 printf("DC Pwm Set\n"); 00284 #endif 00285 00286 _Pwmmode[ch] = Mode; 00287 SetDcMotor(ch); 00288 } 00289 } 00290 00291 void LV8548::SetDcPwmDuty( uint8_t ch ,float Duty ) 00292 { 00293 if(ch < MOTOR_MAX) 00294 { 00295 #if _DEBUG_ 00296 printf("DC Duty Set\n"); 00297 #endif 00298 _PwmDuty[ch] = Duty; 00299 SetDcMotor(ch); 00300 } 00301 } 00302 00303 00304 void LV8548::SetDcOutPut( uint8_t ch ,DriverPwmOut Mode ) 00305 { 00306 if(ch < MOTOR_MAX) 00307 { 00308 #if _DEBUG_ 00309 printf("DC Out Set\n"); 00310 #endif 00311 _Pwmout[ch] = Mode; 00312 SetDcMotor(ch); 00313 } 00314 } 00315 00316 /*******************************************************************************************************************/ 00317 /* FFFFFF SSSS MM MM */ 00318 /* FF SS SS tt MMM MMM tt */ 00319 /* FF oooo rrrrr SS tttttt eeee ppppp MMMMMMM oooo tttttt oooo rrrrr */ 00320 /* FFFF oo oo rr rr SSSS tt ee ee pp pp MM M MM oo oo tt oo oo rr rr */ 00321 /* FF oo oo rr SS tt eeeeee pp pp MM MM oo oo tt oo oo rr */ 00322 /* FF oo oo rr SS SS tt ee ppppp MM MM oo oo tt oo oo rr */ 00323 /* FF oooo rr SSSS ttt eeee pp MM MM oooo ttt oooo rr */ 00324 /* pp */ 00325 /*******************************************************************************************************************/ 00326 void LV8548::SetStepAngle( uint16_t Angle) 00327 { 00328 _StepDeg = Angle; 00329 #if _DEBUG_ 00330 printf("Set Angle Deg:%f \n",_StepDeg); 00331 #endif 00332 } 00333 /// 周波数1~4800 00334 /// DEG 0~65535 00335 /// rotation 0:CW 1:CCW 00336 /// EXP 0:FullStep 1:HalfStep 00337 void LV8548::SetStepDeg ( uint16_t frequency , uint16_t deg , uint8_t Direction, uint8_t StepMode) 00338 { 00339 #if _DEBUG_ 00340 printf("Deg Commnad freq:%d deg:%d dir:%d Mode%d\n",frequency , deg , Direction, StepMode); 00341 #endif 00342 00343 if ( frequency == 0 ) return; 00344 00345 if( frequency > STEPMAX_FREQ ) 00346 { 00347 frequency = STEPMAX_FREQ; 00348 } 00349 00350 SetStepStop(); /* Step Motor 初期化 */ 00351 00352 _TragetStepDirection = (DriverMotorDirction )Direction; // CW/CCW 00353 _TargetStepMode = (DriverStepMode )StepMode; // Full/Half; 00354 if(_TargetStepMode != _NowStepMode) 00355 { /* 動作モード変更の為初期化 */ 00356 _StepPhase = 0; 00357 #if _DEBUG_ 00358 printf("Stepper Mode Change Then StepPhase 0\n"); 00359 #endif 00360 } 00361 #if 0 // 意味の無い処理なのでコメント化 00362 if( _TragetStepDirection != _NowStepDirection ) 00363 { // 方向の変更があった時 /// 00364 if( _TragetStepDirection == DIR_CW ) 00365 { 00366 _StepPhase++; //なぜ2パターン?? 00367 _StepPhase++; // 元のソースは2パターン戻すが、必要なもないので削除 00368 } 00369 else 00370 if( _TragetStepDirection == DIR_CCW ) 00371 { 00372 _StepPhase--; //なぜ2パターン?? 00373 _StepPhase--; // 元のソースは2パターン戻すが、必要なもないので削除 00374 } 00375 _StepPhase &= STEPPHASEMAX; // 0-7に! 00376 } 00377 #endif 00378 _StepFreq = frequency ; 00379 if(_StepDeg) 00380 { 00381 _TargetStep = ( deg / _StepDeg); 00382 if(_TargetStepMode) 00383 { /* HALF時2倍 */ 00384 _TargetStep = _TargetStep + _TargetStep; 00385 } 00386 } 00387 else 00388 { 00389 _TargetStep = 0; 00390 } 00391 00392 #if _DEBUG_ 00393 printf("Analyze StepFreq:%f TargetStep:%d StepPhase:%d \n",_StepFreq ,_TargetStep,_StepPhase); 00394 #endif 00395 SetStepMotor(); 00396 } 00397 00398 void LV8548::SetStepTime ( uint16_t frequency , uint16_t time , uint8_t Direction, uint8_t StepMode) 00399 { 00400 #if _DEBUG_ 00401 printf("Time Commnad freq:%d Time:%d dir:%d Mode%d\n",frequency ,time, Direction, StepMode); 00402 #endif 00403 if ( frequency == 0 ) return; 00404 00405 if( frequency > STEPMAX_FREQ ) 00406 { 00407 frequency = STEPMAX_FREQ; 00408 } 00409 SetStepStop(); /* Step Motor 初期化 */ 00410 00411 _TragetStepDirection = (DriverMotorDirction )Direction; 00412 _TargetStepMode = (DriverStepMode )StepMode; // Full/Half; 00413 00414 if(_TargetStepMode != _NowStepMode) 00415 { /* 動作モード変更の為初期化 */ 00416 _StepPhase = 0; 00417 #if _DEBUG_ 00418 printf("Stepper Mode Change Then StepPhase 0\n"); 00419 #endif 00420 } 00421 00422 _StepFreq = frequency ; 00423 _TargetStep = ( time * frequency ); 00424 #if _DEBUG_ 00425 printf("Analyze StepFreq:%f TargetStep:%d StepPhase:%d \n",_StepFreq ,_TargetStep,_StepPhase); 00426 #endif 00427 SetStepMotor(); 00428 } 00429 00430 void LV8548::SetStepStep ( uint16_t frequency , uint16_t step , uint8_t Direction, uint8_t StepMode) 00431 { 00432 #if _DEBUG_ 00433 printf("Step Commnad freq:%d step:%d dir:%d Mode%d\n",frequency , step , Direction, StepMode); 00434 #endif 00435 if ( frequency == 0 ) return; 00436 00437 if( frequency > STEPMAX_FREQ ) 00438 { 00439 frequency = STEPMAX_FREQ; 00440 } 00441 SetStepStop(); /* Step Motor 初期化 */ 00442 00443 _TragetStepDirection = (DriverMotorDirction )Direction; 00444 _TargetStepMode = (DriverStepMode )StepMode; // Full/Half; 00445 00446 if(_TargetStepMode != _NowStepMode) 00447 { /* 動作モード変更の為初期化 */ 00448 _StepPhase = 0; 00449 #if _DEBUG_ 00450 printf("Stepper Mode Change Then StepPhase 0\n"); 00451 #endif 00452 } 00453 #if 0 00454 if( _TragetStepDirection != _NowStepDirection ) 00455 { // 方向の変更があった時 /// 00456 if( _TragetStepDirection == DIR_CW ) 00457 { 00458 _StepPhase++; //なぜ2パターン?? 00459 _StepPhase++; 00460 } 00461 else 00462 if( _TragetStepDirection == DIR_CCW ) 00463 { 00464 _StepPhase--; //なぜ2パターン?? 00465 _StepPhase--; 00466 } 00467 _StepPhase &= STEPPHASEMAX; // 0-7に! 00468 } 00469 #endif 00470 _StepFreq = frequency; 00471 _TargetStep = step; 00472 #if _DEBUG_ 00473 printf("Analyze StepFreq:%f %f TargetStep:%d StepPhase:%d \n",_StepFreq ,_TargetStep,_StepPhase); 00474 #endif 00475 SetStepMotor(); 00476 } 00477 void LV8548::SetStepStop ( void ) 00478 { 00479 if( _Drivertype != STEPERMOTOR ) return; 00480 /* 割込内の終了処理と同じ */ 00481 _StepOperation = false; 00482 _TimerCounter = 0.0f; 00483 _NowStep = 0; 00484 #if _DEBUG_ 00485 printf("StepStop:%d \n",_StepPhase ); 00486 #endif 00487 00488 } 00489 void LV8548::SetStepFree ( void ) 00490 { 00491 #if _DEBUG_ 00492 printf("StepFree:%d \n",_StepPhase ); 00493 #endif 00494 if( _Drivertype != STEPERMOTOR ) return; 00495 00496 SetStepStop(); 00497 00498 _StepPhase = 0; 00499 _in1.write(0.0f); 00500 _in2.write(0.0f); 00501 _in3.write(0.0f); 00502 _in4.write(0.0f); 00503 00504 } 00505 00506 void LV8548::SetStepMotor(void) 00507 { 00508 _StepOperation = false; // 00509 00510 _NowStepDirection = _TragetStepDirection; 00511 _NowStepMode = _TargetStepMode; 00512 _IntTimerCount = _StepTimeCount; /* 即初回次のシーケンス起動 なんで初回の1回も普通にカウントしているの?*/ 00513 if( _NowStepMode == FULLSTEP ) 00514 { 00515 _NowStep = 1; /* 波形比較により1/2シフト */ 00516 _StepTimeCount = 500000.0F / _StepFreq ; 00517 _TargetStep = _TargetStep + _TargetStep; /* FULL時は2倍 */ 00518 } 00519 else 00520 { 00521 _NowStep = 0; 00522 _StepTimeCount = 1000000.0F / _StepFreq; 00523 } 00524 #if _DEBUG_ 00525 printf("StepTimeCount:%d \n",_StepTimeCount ); 00526 #endif 00527 _StepOperation = true; 00528 } 00529 00530 void LV8548::SetStepTimerInt(void) 00531 { 00532 uint8_t OutputImage; 00533 if(!_StepOperation ) return; 00534 _IntTimerCount += _baseus; 00535 00536 if( _IntTimerCount >= _StepTimeCount) 00537 { 00538 _IntTimerCount = 0; 00539 if( _TargetStep ) 00540 { 00541 if(_NowStep >= _TargetStep) 00542 { // ステップ数よる停止条件の場合 */ 00543 /* Stop処理と同じ */ 00544 _StepOperation = false; 00545 _TimerCounter = 0.0f; 00546 _NowStep = 0; 00547 return; /* 元ソースと同じ動作にあわせる為 */ 00548 } 00549 /// Image 作成 ///////////////////// 00550 ++_NowStep; 00551 switch(_NowStepMode) 00552 { 00553 case FULLSTEP: 00554 OutputImage = FullStepDrivePattern[ _StepPhase ]; 00555 break; 00556 case HALFSTEP: 00557 OutputImage = HaleStepDrivePattern[ _StepPhase ]; 00558 break; 00559 default: 00560 OutputImage = 0; 00561 break; 00562 } 00563 #if _DEBUG_ 00564 printf("Ot:%x %x %x\n",OutputImage,_StepPhase,_TargetStepMode); 00565 #endif 00566 #if USE_PWM_PORT 00567 if( OutputImage & COIL_A ) _in1.write(1.0f); 00568 else _in1.write(0.0f); 00569 if( OutputImage & COIL_B ) _in2.write(1.0f); 00570 else _in2.write(0.0f); 00571 if( OutputImage & COIL_C ) _in3.write(1.0f); 00572 else _in3.write(0.0f); 00573 if( OutputImage & COIL_D ) _in4.write(1.0f); 00574 else _in4.write(0.0f); 00575 #else 00576 _in1 = (( OutputImage & COIL_A ) != 0); 00577 _in2 = (( OutputImage & COIL_B ) != 0); 00578 _in3 = (( OutputImage & COIL_C ) != 0); 00579 _in4 = (( OutputImage & COIL_D ) != 0); 00580 #endif 00581 if(_NowStepDirection) _StepPhase --; 00582 else _StepPhase ++; 00583 _StepPhase = _StepPhase & (STEPPHASEMAX -1); 00584 } 00585 } 00586 }
Generated on Wed Jul 13 2022 23:00:39 by 1.7.2