UVW 3 phases Brushless DC motor control

Dependencies:   QEI mbed-rtos mbed

Fork of DCmotor by manabu kosaka

Committer:
kosaka
Date:
Fri Dec 21 22:06:56 2012 +0000
Revision:
12:a4b17bb682eb
Child:
13:791e20f1af43
121222a

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kosaka 12:a4b17bb682eb 1 #include "mbed.h"
kosaka 12:a4b17bb682eb 2 #include "controller.h"
kosaka 12:a4b17bb682eb 3 #include "UVWpwm.h"
kosaka 12:a4b17bb682eb 4
kosaka 12:a4b17bb682eb 5 #define DEADTIME_US (unsigned long)(DEADTIME*1000000) // [us], deadtime to be set between plus volt. to/from minus
kosaka 12:a4b17bb682eb 6
kosaka 12:a4b17bb682eb 7 Timeout pwm[3];
kosaka 12:a4b17bb682eb 8
kosaka 12:a4b17bb682eb 9 DigitalOut pwm_upper[] = {(U_UPPER_PORT), (V_UPPER_PORT),(W_UPPER_PORT)};
kosaka 12:a4b17bb682eb 10 DigitalOut pwm_lower[] = {(U_LOWER_PORT), (V_LOWER_PORT),(W_LOWER_PORT)};
kosaka 12:a4b17bb682eb 11
kosaka 12:a4b17bb682eb 12 pwm_parameters uvw[3]; // UVW pwm の定数、変数
kosaka 12:a4b17bb682eb 13
kosaka 12:a4b17bb682eb 14 // 関数配列: NG
kosaka 12:a4b17bb682eb 15 //void (*pwmUVWout[])(int) = {pwmout,pwmout,pwmout};
kosaka 12:a4b17bb682eb 16 // pwmUVWout[i](i);
kosaka 12:a4b17bb682eb 17
kosaka 12:a4b17bb682eb 18 #if PWM_WAVEFORM==0 // 0: saw tooth wave comparison
kosaka 12:a4b17bb682eb 19 void pwmUout() { // pwm out using timer
kosaka 12:a4b17bb682eb 20 unsigned char i=0;
kosaka 12:a4b17bb682eb 21 uvw[i].mode += 1;
kosaka 12:a4b17bb682eb 22 if( uvw[i].mode==1 ){
kosaka 12:a4b17bb682eb 23 pwm_upper[i] = 1;
kosaka 12:a4b17bb682eb 24 pwm_lower[i] = 0;
kosaka 12:a4b17bb682eb 25 uvw[i].upper_us = uvw[i].duty*1000000/PWM_FREQ - DEADTIME_US; // ON time of Uupper
kosaka 12:a4b17bb682eb 26 pwm[i].attach_us(&pwmUout, uvw[i].upper_us); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 27 uvw[i].lower_us = 1000000/PWM_FREQ -uvw[i].upper_us - 2*DEADTIME_US; // ON time of Ulower
kosaka 12:a4b17bb682eb 28 }else if( uvw[i].mode==2 ){
kosaka 12:a4b17bb682eb 29 pwm[i].attach_us(&pwmUout, DEADTIME_US); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 30 pwm_upper[i] = 0;
kosaka 12:a4b17bb682eb 31 pwm_lower[i] = 0;
kosaka 12:a4b17bb682eb 32 }else if( uvw[i].mode==3 ){
kosaka 12:a4b17bb682eb 33 pwm[i].attach_us(&pwmUout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 34 pwm_upper[i] = 0;
kosaka 12:a4b17bb682eb 35 pwm_lower[i] = 1;
kosaka 12:a4b17bb682eb 36 }else{// if( u.mode==4 ){
kosaka 12:a4b17bb682eb 37 pwm[i].attach_us(&pwmUout, DEADTIME_US); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 38 pwm_upper[i] = 0;
kosaka 12:a4b17bb682eb 39 pwm_lower[i] = 0;
kosaka 12:a4b17bb682eb 40 uvw[i].mode = 0;
kosaka 12:a4b17bb682eb 41 }
kosaka 12:a4b17bb682eb 42 }
kosaka 12:a4b17bb682eb 43
kosaka 12:a4b17bb682eb 44 void pwmVout() { // pwm out using timer
kosaka 12:a4b17bb682eb 45 unsigned char i=1;
kosaka 12:a4b17bb682eb 46 uvw[i].mode += 1;
kosaka 12:a4b17bb682eb 47 if( uvw[i].mode==1 ){
kosaka 12:a4b17bb682eb 48 pwm_upper[i] = 1;
kosaka 12:a4b17bb682eb 49 pwm_lower[i] = 0;
kosaka 12:a4b17bb682eb 50 uvw[i].upper_us = uvw[i].duty*1000000/PWM_FREQ - DEADTIME_US; // ON time of Uupper
kosaka 12:a4b17bb682eb 51 pwm[i].attach_us(&pwmVout, uvw[i].upper_us); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 52 uvw[i].lower_us = 1000000/PWM_FREQ -uvw[i].upper_us - 2*DEADTIME_US; // ON time of Ulower
kosaka 12:a4b17bb682eb 53 }else if( uvw[i].mode==2 ){
kosaka 12:a4b17bb682eb 54 pwm[i].attach_us(&pwmVout, DEADTIME_US); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 55 pwm_upper[i] = 0;
kosaka 12:a4b17bb682eb 56 pwm_lower[i] = 0;
kosaka 12:a4b17bb682eb 57 }else if( uvw[i].mode==3 ){
kosaka 12:a4b17bb682eb 58 pwm[i].attach_us(&pwmVout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 59 pwm_upper[i] = 0;
kosaka 12:a4b17bb682eb 60 pwm_lower[i] = 1;
kosaka 12:a4b17bb682eb 61 }else{// if( u.mode==4 ){
kosaka 12:a4b17bb682eb 62 pwm[i].attach_us(&pwmVout, DEADTIME_US); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 63 pwm_upper[i] = 0;
kosaka 12:a4b17bb682eb 64 pwm_lower[i] = 0;
kosaka 12:a4b17bb682eb 65 uvw[i].mode = 0;
kosaka 12:a4b17bb682eb 66 }
kosaka 12:a4b17bb682eb 67 }
kosaka 12:a4b17bb682eb 68
kosaka 12:a4b17bb682eb 69 void pwmWout() { // pwm out using timer
kosaka 12:a4b17bb682eb 70 unsigned char i=2;
kosaka 12:a4b17bb682eb 71 uvw[i].mode += 1;
kosaka 12:a4b17bb682eb 72 if( uvw[i].mode==1 ){
kosaka 12:a4b17bb682eb 73 pwm_upper[i] = 1;
kosaka 12:a4b17bb682eb 74 pwm_lower[i] = 0;
kosaka 12:a4b17bb682eb 75 uvw[i].upper_us = uvw[i].duty*1000000/PWM_FREQ - DEADTIME_US; // ON time of Uupper
kosaka 12:a4b17bb682eb 76 pwm[i].attach_us(&pwmWout, uvw[i].upper_us); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 77 uvw[i].lower_us = 1000000/PWM_FREQ -uvw[i].upper_us - 2*DEADTIME_US; // ON time of Ulower
kosaka 12:a4b17bb682eb 78 }else if( uvw[i].mode==2 ){
kosaka 12:a4b17bb682eb 79 pwm[i].attach_us(&pwmWout, DEADTIME_US); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 80 pwm_upper[i] = 0;
kosaka 12:a4b17bb682eb 81 pwm_lower[i] = 0;
kosaka 12:a4b17bb682eb 82 }else if( uvw[i].mode==3 ){
kosaka 12:a4b17bb682eb 83 pwm[i].attach_us(&pwmWout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 84 pwm_upper[i] = 0;
kosaka 12:a4b17bb682eb 85 pwm_lower[i] = 1;
kosaka 12:a4b17bb682eb 86 }else{// if( u.mode==4 ){
kosaka 12:a4b17bb682eb 87 pwm[i].attach_us(&pwmWout, DEADTIME_US); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 88 pwm_upper[i] = 0;
kosaka 12:a4b17bb682eb 89 pwm_lower[i] = 0;
kosaka 12:a4b17bb682eb 90 uvw[i].mode = 0;
kosaka 12:a4b17bb682eb 91 }
kosaka 12:a4b17bb682eb 92 }
kosaka 12:a4b17bb682eb 93 #elif PWM_WAVEFORM==1 // 1: triangler wave comparison
kosaka 12:a4b17bb682eb 94 void pwmUout() { // pwm out using timer
kosaka 12:a4b17bb682eb 95 unsigned char i=0;
kosaka 12:a4b17bb682eb 96 uvw[i].mode += 1;
kosaka 12:a4b17bb682eb 97 if( uvw[i].mode==1 ){
kosaka 12:a4b17bb682eb 98 uvw[i].upper_us = uvw[i].duty*1000000/PWM_FREQ - DEADTIME_US; // ON time of Uupper
kosaka 12:a4b17bb682eb 99 uvw[i].lower_us = 1000000/PWM_FREQ -uvw[i].upper_us - 2*DEADTIME_US; // ON time of Ulower
kosaka 12:a4b17bb682eb 100 pwm_upper[i] = 0;
kosaka 12:a4b17bb682eb 101 pwm_lower[i] = 1;
kosaka 12:a4b17bb682eb 102 uvw[i].lower_us /= 2;
kosaka 12:a4b17bb682eb 103 pwm[i].attach_us(&pwmUout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 104 }else if( uvw[i].mode==2 ){
kosaka 12:a4b17bb682eb 105 pwm[i].attach_us(&pwmUout, DEADTIME_US); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 106 pwm_upper[i] = 0;
kosaka 12:a4b17bb682eb 107 pwm_lower[i] = 0;
kosaka 12:a4b17bb682eb 108 }else if( uvw[i].mode==3 ){
kosaka 12:a4b17bb682eb 109 pwm[i].attach_us(&pwmUout, uvw[i].upper_us); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 110 pwm_upper[i] = 1;
kosaka 12:a4b17bb682eb 111 pwm_lower[i] = 0;
kosaka 12:a4b17bb682eb 112 }else if( uvw[i].mode==4 ){
kosaka 12:a4b17bb682eb 113 pwm[i].attach_us(&pwmUout, DEADTIME_US); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 114 pwm_upper[i] = 0;
kosaka 12:a4b17bb682eb 115 pwm_lower[i] = 0;
kosaka 12:a4b17bb682eb 116 }else{// if( uvw[i].mode==5 ){
kosaka 12:a4b17bb682eb 117 pwm[i].attach_us(&pwmUout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 118 pwm_upper[i] = 0;
kosaka 12:a4b17bb682eb 119 pwm_lower[i] = 1;
kosaka 12:a4b17bb682eb 120 uvw[i].mode = 0;
kosaka 12:a4b17bb682eb 121 }
kosaka 12:a4b17bb682eb 122 }
kosaka 12:a4b17bb682eb 123 void pwmVout() { // pwm out using timer
kosaka 12:a4b17bb682eb 124 unsigned char i=1;
kosaka 12:a4b17bb682eb 125 uvw[i].mode += 1;
kosaka 12:a4b17bb682eb 126 if( uvw[i].mode==1 ){
kosaka 12:a4b17bb682eb 127 uvw[i].upper_us = uvw[i].duty*1000000/PWM_FREQ - DEADTIME_US; // ON time of Uupper
kosaka 12:a4b17bb682eb 128 uvw[i].lower_us = 1000000/PWM_FREQ -uvw[i].upper_us - 2*DEADTIME_US; // ON time of Ulower
kosaka 12:a4b17bb682eb 129 pwm_upper[i] = 0;
kosaka 12:a4b17bb682eb 130 pwm_lower[i] = 1;
kosaka 12:a4b17bb682eb 131 uvw[i].lower_us /= 2;
kosaka 12:a4b17bb682eb 132 pwm[i].attach_us(&pwmVout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 133 }else if( uvw[i].mode==2 ){
kosaka 12:a4b17bb682eb 134 pwm[i].attach_us(&pwmVout, DEADTIME_US); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 135 pwm_upper[i] = 0;
kosaka 12:a4b17bb682eb 136 pwm_lower[i] = 0;
kosaka 12:a4b17bb682eb 137 }else if( uvw[i].mode==3 ){
kosaka 12:a4b17bb682eb 138 pwm[i].attach_us(&pwmVout, uvw[i].upper_us); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 139 pwm_upper[i] = 1;
kosaka 12:a4b17bb682eb 140 pwm_lower[i] = 0;
kosaka 12:a4b17bb682eb 141 }else if( uvw[i].mode==4 ){
kosaka 12:a4b17bb682eb 142 pwm[i].attach_us(&pwmVout, DEADTIME_US); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 143 pwm_upper[i] = 0;
kosaka 12:a4b17bb682eb 144 pwm_lower[i] = 0;
kosaka 12:a4b17bb682eb 145 }else{// if( uvw[i].mode==5 ){
kosaka 12:a4b17bb682eb 146 pwm[i].attach_us(&pwmVout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 147 pwm_upper[i] = 0;
kosaka 12:a4b17bb682eb 148 pwm_lower[i] = 1;
kosaka 12:a4b17bb682eb 149 uvw[i].mode = 0;
kosaka 12:a4b17bb682eb 150 }
kosaka 12:a4b17bb682eb 151 }
kosaka 12:a4b17bb682eb 152
kosaka 12:a4b17bb682eb 153 void pwmWout() { // pwm out using timer
kosaka 12:a4b17bb682eb 154 unsigned char i=2;
kosaka 12:a4b17bb682eb 155 uvw[i].mode += 1;
kosaka 12:a4b17bb682eb 156 if( uvw[i].mode==1 ){
kosaka 12:a4b17bb682eb 157 uvw[i].upper_us = uvw[i].duty*1000000/PWM_FREQ - DEADTIME_US; // ON time of Uupper
kosaka 12:a4b17bb682eb 158 uvw[i].lower_us = 1000000/PWM_FREQ -uvw[i].upper_us - 2*DEADTIME_US; // ON time of Ulower
kosaka 12:a4b17bb682eb 159 pwm_upper[i] = 0;
kosaka 12:a4b17bb682eb 160 pwm_lower[i] = 1;
kosaka 12:a4b17bb682eb 161 uvw[i].lower_us /= 2;
kosaka 12:a4b17bb682eb 162 pwm[i].attach_us(&pwmWout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 163 }else if( uvw[i].mode==2 ){
kosaka 12:a4b17bb682eb 164 pwm[i].attach_us(&pwmWout, DEADTIME_US); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 165 pwm_upper[i] = 0;
kosaka 12:a4b17bb682eb 166 pwm_lower[i] = 0;
kosaka 12:a4b17bb682eb 167 }else if( uvw[i].mode==3 ){
kosaka 12:a4b17bb682eb 168 pwm[i].attach_us(&pwmWout, uvw[i].upper_us); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 169 pwm_upper[i] = 1;
kosaka 12:a4b17bb682eb 170 pwm_lower[i] = 0;
kosaka 12:a4b17bb682eb 171 }else if( uvw[i].mode==4 ){
kosaka 12:a4b17bb682eb 172 pwm[i].attach_us(&pwmWout, DEADTIME_US); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 173 pwm_upper[i] = 0;
kosaka 12:a4b17bb682eb 174 pwm_lower[i] = 0;
kosaka 12:a4b17bb682eb 175 }else{// if( uvw[i].mode==5 ){
kosaka 12:a4b17bb682eb 176 pwm[i].attach_us(&pwmWout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us]
kosaka 12:a4b17bb682eb 177 pwm_upper[i] = 0;
kosaka 12:a4b17bb682eb 178 pwm_lower[i] = 1;
kosaka 12:a4b17bb682eb 179 uvw[i].mode = 0;
kosaka 12:a4b17bb682eb 180 }
kosaka 12:a4b17bb682eb 181 }
kosaka 12:a4b17bb682eb 182 #endif
kosaka 12:a4b17bb682eb 183
kosaka 12:a4b17bb682eb 184
kosaka 12:a4b17bb682eb 185 void start_pwm(){
kosaka 12:a4b17bb682eb 186 unsigned char i;
kosaka 12:a4b17bb682eb 187 for( i=0;i<3;i++ ){
kosaka 12:a4b17bb682eb 188 uvw[i].duty = 0.5;
kosaka 12:a4b17bb682eb 189 pwm_upper[i] = pwm_lower[i] = 0;
kosaka 12:a4b17bb682eb 190 uvw[i].mode = 0;
kosaka 12:a4b17bb682eb 191 }
kosaka 12:a4b17bb682eb 192 pwmUout();
kosaka 12:a4b17bb682eb 193 pwmVout();
kosaka 12:a4b17bb682eb 194 pwmWout();
kosaka 12:a4b17bb682eb 195 }
kosaka 12:a4b17bb682eb 196
kosaka 12:a4b17bb682eb 197 void stop_pwm(){
kosaka 12:a4b17bb682eb 198 unsigned char i;
kosaka 12:a4b17bb682eb 199 for( i=0;i<3;i++ ){
kosaka 12:a4b17bb682eb 200 pwm_upper[i] = pwm_lower[i] = 0;
kosaka 12:a4b17bb682eb 201 uvw[i].mode = 0;
kosaka 12:a4b17bb682eb 202 pwm[i].detach();
kosaka 12:a4b17bb682eb 203 }
kosaka 12:a4b17bb682eb 204 }