DC motor control program using TA7291P type H bridge driver and rotary encoder with A, B phase.
Fork of DCmotor2 by
Diff: Hbridge.cpp
- Revision:
- 12:459af534d1ee
- Child:
- 13:ba71733c11d7
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Hbridge.cpp Fri Jan 04 12:00:48 2013 +0000 @@ -0,0 +1,122 @@ +#include "mbed.h" +#include "controller.h" +#include "Hbridge.h" + +#define DEADTIME_US (unsigned long)(DEADTIME*1000000) // [us], deadtime to be set between plus volt. to/from minus + +Timeout pwm; + +DigitalOut pwm_upper = UPPER_PORT; +DigitalOut pwm_lower = LOWER_PORT; + +pwm_parameters IN; // UVW pwm の定数、変数 + +DigitalOut debug_p24(p24); // p17 for debug +//DigitalOut Led3(LED3); + +#if PWM_WAVEFORM==0 // 0: saw tooth wave comparison + #if 1 +void pwm_out() { // pwm out using timer +//debug_p24=1; + IN.mode += 1; +//IN.duty=0.9;IN.fReverse[0]=1; + if( IN.fDeadtime==1 && IN.mode==1){ + pwm.attach_us(&pwm_out, DEADTIME_US); // setup pwmU to call pwm_out after t [us] + pwm_upper = 0; pwm_lower = 0; + IN.fDeadtime = 0; + IN.fReverse[1] = IN.fReverse[0]; + IN.mode = 0; + }else if( IN.mode==1 ){ + if( IN.fReverse[1]==0 ){ + pwm_upper = 1; pwm_lower = 0; + }else{ + pwm_upper = 0; pwm_lower = 1; + } + IN.upper_us = IN.duty*1000000/PWM_FREQ; // ON time of pwm + if( IN.upper_us < TMIN ){ IN.upper_us=TMIN;} + pwm.attach_us(&pwm_out, IN.upper_us); // setup pwmU to call pwm_out after t [us] + IN.lower_us = 1000000/PWM_FREQ -IN.upper_us; // OFF time of pwm + if( IN.lower_us < TMIN ){ IN.lower_us=TMIN;} + }else{// if( IN.mode==2 ){ + pwm.attach_us(&pwm_out, IN.lower_us); // setup pwmU to call pwm_out after t [us] + pwm_upper = 0; pwm_lower = 0; + IN.mode = 0; + } +//debug_p24=0; +} + #else +void pwm_out() { // pwm out using timer + IN.mode += 1; + if( IN.mode==1 ){ + pwm_upper = 1; + pwm_lower = 0; + IN.upper_us = IN.duty*1000000/PWM_FREQ - DEADTIME_US; // ON time of Uupper + if( IN.upper_us < TMIN ){ IN.upper_us=TMIN;} + pwm.attach_us(&pwm_out, IN.upper_us); // setup pwmU to call pwm_out after t [us] + IN.lower_us = 1000000/PWM_FREQ -IN.upper_us - 2*DEADTIME_US; // ON time of Ulower + if( IN.lower_us < TMIN ){ IN.lower_us=TMIN;} + }else if( IN.mode==2 ){ + pwm.attach_us(&pwm_out, DEADTIME_US); // setup pwmU to call pwm_out after t [us] + pwm_upper = 0; + pwm_lower = 0; + }else if( IN.mode==3 ){ + pwm.attach_us(&pwm_out, IN.lower_us); // setup pwmU to call pwm_out after t [us] + pwm_upper = 0; + pwm_lower = 1; + }else{// if( u.mode==4 ){ + pwm.attach_us(&pwm_out, DEADTIME_US); // setup pwmU to call pwm_out after t [us] + pwm_upper = 0; + pwm_lower = 0; + IN.mode = 0; + } +} + #endif +#elif PWM_WAVEFORM==1 // 1: triangler wave comparison +void pwm_out() { // pwm out using timer + IN.mode += 1; + if( IN.fDeadtime==1 && IN.mode==1){ + pwm.attach_us(&pwm_out, DEADTIME_US); // setup pwmU to call pwm_out after t [us] + pwm_upper = 0; pwm_lower = 0; + IN.fDeadtime = 0; + IN.fReverse[1] = IN.fReverse[0]; + IN.mode = 0; + }else if( IN.mode==1 ){ + IN.upper_us = IN.duty*1000000/PWM_FREQ; // ON time of Uupper + IN.lower_us = 1000000/PWM_FREQ -IN.upper_us; // ON time of Ulower + IN.lower_us /= 2; + if( IN.lower_us < TMIN ){ IN.lower_us=TMIN;} + pwm.attach_us(&pwm_out, IN.lower_us); // setup pwmU to call pwm_out after t [us] + if( IN.upper_us < TMIN ){ IN.upper_us=TMIN;} + pwm_upper = 0; pwm_lower = 0; + }else if( IN.mode==2 ){ + pwm.attach_us(&pwm_out, IN.upper_us); // setup pwmU to call pwm_out after t [us] + if( IN.fReverse[1]==0 ){ + pwm_upper = 1; pwm_lower = 0; + }else{ + pwm_upper = 0; pwm_lower = 1; + } + }else{// if( IN.mode==3 ){ + pwm.attach_us(&pwm_out, IN.lower_us); // setup pwmU to call pwm_out after t [us] + pwm_upper = 0; pwm_lower = 0; + IN.mode = 0; + } +} +#endif + + +void start_pwm(){ + IN.duty = 0.0; + pwm_upper = pwm_lower = 0; + IN.mode = 0; + IN.fDeadtime = 1; + IN.fReverse[0] = 0; + + pwm_out(); +} + +void stop_pwm(){ + IN.duty = 0.0; + pwm_upper = pwm_lower = 0; + IN.mode = 0; + pwm.detach(); +}