DC motor control program using TA7291P type H bridge driver and rotary encoder with A, B phase.
Fork of DCmotor2 by
Hbridge.cpp@12:459af534d1ee, 2013-01-04 (annotated)
- Committer:
- kosaka
- Date:
- Fri Jan 04 12:00:48 2013 +0000
- Revision:
- 12:459af534d1ee
- Child:
- 13:ba71733c11d7
DC motor control program using TA7291P type H bridge driver and rotary encoder with A, B phase.;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kosaka | 12:459af534d1ee | 1 | #include "mbed.h" |
kosaka | 12:459af534d1ee | 2 | #include "controller.h" |
kosaka | 12:459af534d1ee | 3 | #include "Hbridge.h" |
kosaka | 12:459af534d1ee | 4 | |
kosaka | 12:459af534d1ee | 5 | #define DEADTIME_US (unsigned long)(DEADTIME*1000000) // [us], deadtime to be set between plus volt. to/from minus |
kosaka | 12:459af534d1ee | 6 | |
kosaka | 12:459af534d1ee | 7 | Timeout pwm; |
kosaka | 12:459af534d1ee | 8 | |
kosaka | 12:459af534d1ee | 9 | DigitalOut pwm_upper = UPPER_PORT; |
kosaka | 12:459af534d1ee | 10 | DigitalOut pwm_lower = LOWER_PORT; |
kosaka | 12:459af534d1ee | 11 | |
kosaka | 12:459af534d1ee | 12 | pwm_parameters IN; // UVW pwm の定数、変数 |
kosaka | 12:459af534d1ee | 13 | |
kosaka | 12:459af534d1ee | 14 | DigitalOut debug_p24(p24); // p17 for debug |
kosaka | 12:459af534d1ee | 15 | //DigitalOut Led3(LED3); |
kosaka | 12:459af534d1ee | 16 | |
kosaka | 12:459af534d1ee | 17 | #if PWM_WAVEFORM==0 // 0: saw tooth wave comparison |
kosaka | 12:459af534d1ee | 18 | #if 1 |
kosaka | 12:459af534d1ee | 19 | void pwm_out() { // pwm out using timer |
kosaka | 12:459af534d1ee | 20 | //debug_p24=1; |
kosaka | 12:459af534d1ee | 21 | IN.mode += 1; |
kosaka | 12:459af534d1ee | 22 | //IN.duty=0.9;IN.fReverse[0]=1; |
kosaka | 12:459af534d1ee | 23 | if( IN.fDeadtime==1 && IN.mode==1){ |
kosaka | 12:459af534d1ee | 24 | pwm.attach_us(&pwm_out, DEADTIME_US); // setup pwmU to call pwm_out after t [us] |
kosaka | 12:459af534d1ee | 25 | pwm_upper = 0; pwm_lower = 0; |
kosaka | 12:459af534d1ee | 26 | IN.fDeadtime = 0; |
kosaka | 12:459af534d1ee | 27 | IN.fReverse[1] = IN.fReverse[0]; |
kosaka | 12:459af534d1ee | 28 | IN.mode = 0; |
kosaka | 12:459af534d1ee | 29 | }else if( IN.mode==1 ){ |
kosaka | 12:459af534d1ee | 30 | if( IN.fReverse[1]==0 ){ |
kosaka | 12:459af534d1ee | 31 | pwm_upper = 1; pwm_lower = 0; |
kosaka | 12:459af534d1ee | 32 | }else{ |
kosaka | 12:459af534d1ee | 33 | pwm_upper = 0; pwm_lower = 1; |
kosaka | 12:459af534d1ee | 34 | } |
kosaka | 12:459af534d1ee | 35 | IN.upper_us = IN.duty*1000000/PWM_FREQ; // ON time of pwm |
kosaka | 12:459af534d1ee | 36 | if( IN.upper_us < TMIN ){ IN.upper_us=TMIN;} |
kosaka | 12:459af534d1ee | 37 | pwm.attach_us(&pwm_out, IN.upper_us); // setup pwmU to call pwm_out after t [us] |
kosaka | 12:459af534d1ee | 38 | IN.lower_us = 1000000/PWM_FREQ -IN.upper_us; // OFF time of pwm |
kosaka | 12:459af534d1ee | 39 | if( IN.lower_us < TMIN ){ IN.lower_us=TMIN;} |
kosaka | 12:459af534d1ee | 40 | }else{// if( IN.mode==2 ){ |
kosaka | 12:459af534d1ee | 41 | pwm.attach_us(&pwm_out, IN.lower_us); // setup pwmU to call pwm_out after t [us] |
kosaka | 12:459af534d1ee | 42 | pwm_upper = 0; pwm_lower = 0; |
kosaka | 12:459af534d1ee | 43 | IN.mode = 0; |
kosaka | 12:459af534d1ee | 44 | } |
kosaka | 12:459af534d1ee | 45 | //debug_p24=0; |
kosaka | 12:459af534d1ee | 46 | } |
kosaka | 12:459af534d1ee | 47 | #else |
kosaka | 12:459af534d1ee | 48 | void pwm_out() { // pwm out using timer |
kosaka | 12:459af534d1ee | 49 | IN.mode += 1; |
kosaka | 12:459af534d1ee | 50 | if( IN.mode==1 ){ |
kosaka | 12:459af534d1ee | 51 | pwm_upper = 1; |
kosaka | 12:459af534d1ee | 52 | pwm_lower = 0; |
kosaka | 12:459af534d1ee | 53 | IN.upper_us = IN.duty*1000000/PWM_FREQ - DEADTIME_US; // ON time of Uupper |
kosaka | 12:459af534d1ee | 54 | if( IN.upper_us < TMIN ){ IN.upper_us=TMIN;} |
kosaka | 12:459af534d1ee | 55 | pwm.attach_us(&pwm_out, IN.upper_us); // setup pwmU to call pwm_out after t [us] |
kosaka | 12:459af534d1ee | 56 | IN.lower_us = 1000000/PWM_FREQ -IN.upper_us - 2*DEADTIME_US; // ON time of Ulower |
kosaka | 12:459af534d1ee | 57 | if( IN.lower_us < TMIN ){ IN.lower_us=TMIN;} |
kosaka | 12:459af534d1ee | 58 | }else if( IN.mode==2 ){ |
kosaka | 12:459af534d1ee | 59 | pwm.attach_us(&pwm_out, DEADTIME_US); // setup pwmU to call pwm_out after t [us] |
kosaka | 12:459af534d1ee | 60 | pwm_upper = 0; |
kosaka | 12:459af534d1ee | 61 | pwm_lower = 0; |
kosaka | 12:459af534d1ee | 62 | }else if( IN.mode==3 ){ |
kosaka | 12:459af534d1ee | 63 | pwm.attach_us(&pwm_out, IN.lower_us); // setup pwmU to call pwm_out after t [us] |
kosaka | 12:459af534d1ee | 64 | pwm_upper = 0; |
kosaka | 12:459af534d1ee | 65 | pwm_lower = 1; |
kosaka | 12:459af534d1ee | 66 | }else{// if( u.mode==4 ){ |
kosaka | 12:459af534d1ee | 67 | pwm.attach_us(&pwm_out, DEADTIME_US); // setup pwmU to call pwm_out after t [us] |
kosaka | 12:459af534d1ee | 68 | pwm_upper = 0; |
kosaka | 12:459af534d1ee | 69 | pwm_lower = 0; |
kosaka | 12:459af534d1ee | 70 | IN.mode = 0; |
kosaka | 12:459af534d1ee | 71 | } |
kosaka | 12:459af534d1ee | 72 | } |
kosaka | 12:459af534d1ee | 73 | #endif |
kosaka | 12:459af534d1ee | 74 | #elif PWM_WAVEFORM==1 // 1: triangler wave comparison |
kosaka | 12:459af534d1ee | 75 | void pwm_out() { // pwm out using timer |
kosaka | 12:459af534d1ee | 76 | IN.mode += 1; |
kosaka | 12:459af534d1ee | 77 | if( IN.fDeadtime==1 && IN.mode==1){ |
kosaka | 12:459af534d1ee | 78 | pwm.attach_us(&pwm_out, DEADTIME_US); // setup pwmU to call pwm_out after t [us] |
kosaka | 12:459af534d1ee | 79 | pwm_upper = 0; pwm_lower = 0; |
kosaka | 12:459af534d1ee | 80 | IN.fDeadtime = 0; |
kosaka | 12:459af534d1ee | 81 | IN.fReverse[1] = IN.fReverse[0]; |
kosaka | 12:459af534d1ee | 82 | IN.mode = 0; |
kosaka | 12:459af534d1ee | 83 | }else if( IN.mode==1 ){ |
kosaka | 12:459af534d1ee | 84 | IN.upper_us = IN.duty*1000000/PWM_FREQ; // ON time of Uupper |
kosaka | 12:459af534d1ee | 85 | IN.lower_us = 1000000/PWM_FREQ -IN.upper_us; // ON time of Ulower |
kosaka | 12:459af534d1ee | 86 | IN.lower_us /= 2; |
kosaka | 12:459af534d1ee | 87 | if( IN.lower_us < TMIN ){ IN.lower_us=TMIN;} |
kosaka | 12:459af534d1ee | 88 | pwm.attach_us(&pwm_out, IN.lower_us); // setup pwmU to call pwm_out after t [us] |
kosaka | 12:459af534d1ee | 89 | if( IN.upper_us < TMIN ){ IN.upper_us=TMIN;} |
kosaka | 12:459af534d1ee | 90 | pwm_upper = 0; pwm_lower = 0; |
kosaka | 12:459af534d1ee | 91 | }else if( IN.mode==2 ){ |
kosaka | 12:459af534d1ee | 92 | pwm.attach_us(&pwm_out, IN.upper_us); // setup pwmU to call pwm_out after t [us] |
kosaka | 12:459af534d1ee | 93 | if( IN.fReverse[1]==0 ){ |
kosaka | 12:459af534d1ee | 94 | pwm_upper = 1; pwm_lower = 0; |
kosaka | 12:459af534d1ee | 95 | }else{ |
kosaka | 12:459af534d1ee | 96 | pwm_upper = 0; pwm_lower = 1; |
kosaka | 12:459af534d1ee | 97 | } |
kosaka | 12:459af534d1ee | 98 | }else{// if( IN.mode==3 ){ |
kosaka | 12:459af534d1ee | 99 | pwm.attach_us(&pwm_out, IN.lower_us); // setup pwmU to call pwm_out after t [us] |
kosaka | 12:459af534d1ee | 100 | pwm_upper = 0; pwm_lower = 0; |
kosaka | 12:459af534d1ee | 101 | IN.mode = 0; |
kosaka | 12:459af534d1ee | 102 | } |
kosaka | 12:459af534d1ee | 103 | } |
kosaka | 12:459af534d1ee | 104 | #endif |
kosaka | 12:459af534d1ee | 105 | |
kosaka | 12:459af534d1ee | 106 | |
kosaka | 12:459af534d1ee | 107 | void start_pwm(){ |
kosaka | 12:459af534d1ee | 108 | IN.duty = 0.0; |
kosaka | 12:459af534d1ee | 109 | pwm_upper = pwm_lower = 0; |
kosaka | 12:459af534d1ee | 110 | IN.mode = 0; |
kosaka | 12:459af534d1ee | 111 | IN.fDeadtime = 1; |
kosaka | 12:459af534d1ee | 112 | IN.fReverse[0] = 0; |
kosaka | 12:459af534d1ee | 113 | |
kosaka | 12:459af534d1ee | 114 | pwm_out(); |
kosaka | 12:459af534d1ee | 115 | } |
kosaka | 12:459af534d1ee | 116 | |
kosaka | 12:459af534d1ee | 117 | void stop_pwm(){ |
kosaka | 12:459af534d1ee | 118 | IN.duty = 0.0; |
kosaka | 12:459af534d1ee | 119 | pwm_upper = pwm_lower = 0; |
kosaka | 12:459af534d1ee | 120 | IN.mode = 0; |
kosaka | 12:459af534d1ee | 121 | pwm.detach(); |
kosaka | 12:459af534d1ee | 122 | } |