UVW 3 phases Brushless DC motor control

Dependencies:   QEI mbed-rtos mbed

Fork of DCmotor by manabu kosaka

UVWpwm.cpp

Committer:
kosaka
Date:
2012-12-21
Revision:
12:a4b17bb682eb
Child:
13:791e20f1af43

File content as of revision 12:a4b17bb682eb:

#include "mbed.h"
#include "controller.h"
#include "UVWpwm.h"

#define DEADTIME_US (unsigned long)(DEADTIME*1000000)  // [us], deadtime to be set between plus volt. to/from minus

Timeout pwm[3];

DigitalOut pwm_upper[] = {(U_UPPER_PORT), (V_UPPER_PORT),(W_UPPER_PORT)};
DigitalOut pwm_lower[] = {(U_LOWER_PORT), (V_LOWER_PORT),(W_LOWER_PORT)};

pwm_parameters     uvw[3]; // UVW pwm の定数、変数

// 関数配列: NG
//void (*pwmUVWout[])(int) = {pwmout,pwmout,pwmout};
//  pwmUVWout[i](i);

#if PWM_WAVEFORM==0   // 0: saw tooth wave comparison
void pwmUout() {    // pwm out using timer
    unsigned char   i=0;
    uvw[i].mode += 1;
    if( uvw[i].mode==1 ){
        pwm_upper[i] = 1;
        pwm_lower[i] = 0;
        uvw[i].upper_us = uvw[i].duty*1000000/PWM_FREQ - DEADTIME_US;   // ON time of Uupper
        pwm[i].attach_us(&pwmUout, uvw[i].upper_us); // setup pwmU to call pwmUout after t [us]
        uvw[i].lower_us = 1000000/PWM_FREQ -uvw[i].upper_us - 2*DEADTIME_US; // ON time of Ulower
    }else if( uvw[i].mode==2 ){
        pwm[i].attach_us(&pwmUout, DEADTIME_US); // setup pwmU to call pwmUout after t [us]
        pwm_upper[i] = 0;
        pwm_lower[i] = 0;
    }else if( uvw[i].mode==3 ){
        pwm[i].attach_us(&pwmUout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us]
        pwm_upper[i] = 0;
        pwm_lower[i] = 1;
    }else{// if( u.mode==4 ){
        pwm[i].attach_us(&pwmUout, DEADTIME_US); // setup pwmU to call pwmUout after t [us]
        pwm_upper[i] = 0;
        pwm_lower[i] = 0;
        uvw[i].mode = 0;
    }
}

void pwmVout() {    // pwm out using timer
    unsigned char   i=1;
    uvw[i].mode += 1;
    if( uvw[i].mode==1 ){
        pwm_upper[i] = 1;
        pwm_lower[i] = 0;
        uvw[i].upper_us = uvw[i].duty*1000000/PWM_FREQ - DEADTIME_US;   // ON time of Uupper
        pwm[i].attach_us(&pwmVout, uvw[i].upper_us); // setup pwmU to call pwmUout after t [us]
        uvw[i].lower_us = 1000000/PWM_FREQ -uvw[i].upper_us - 2*DEADTIME_US; // ON time of Ulower
    }else if( uvw[i].mode==2 ){
        pwm[i].attach_us(&pwmVout, DEADTIME_US); // setup pwmU to call pwmUout after t [us]
        pwm_upper[i] = 0;
        pwm_lower[i] = 0;
    }else if( uvw[i].mode==3 ){
        pwm[i].attach_us(&pwmVout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us]
        pwm_upper[i] = 0;
        pwm_lower[i] = 1;
    }else{// if( u.mode==4 ){
        pwm[i].attach_us(&pwmVout, DEADTIME_US); // setup pwmU to call pwmUout after t [us]
        pwm_upper[i] = 0;
        pwm_lower[i] = 0;
        uvw[i].mode = 0;
    }
}

void pwmWout() {    // pwm out using timer
    unsigned char   i=2;
    uvw[i].mode += 1;
    if( uvw[i].mode==1 ){
        pwm_upper[i] = 1;
        pwm_lower[i] = 0;
        uvw[i].upper_us = uvw[i].duty*1000000/PWM_FREQ - DEADTIME_US;   // ON time of Uupper
        pwm[i].attach_us(&pwmWout, uvw[i].upper_us); // setup pwmU to call pwmUout after t [us]
        uvw[i].lower_us = 1000000/PWM_FREQ -uvw[i].upper_us - 2*DEADTIME_US; // ON time of Ulower
    }else if( uvw[i].mode==2 ){
        pwm[i].attach_us(&pwmWout, DEADTIME_US); // setup pwmU to call pwmUout after t [us]
        pwm_upper[i] = 0;
        pwm_lower[i] = 0;
    }else if( uvw[i].mode==3 ){
        pwm[i].attach_us(&pwmWout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us]
        pwm_upper[i] = 0;
        pwm_lower[i] = 1;
    }else{// if( u.mode==4 ){
        pwm[i].attach_us(&pwmWout, DEADTIME_US); // setup pwmU to call pwmUout after t [us]
        pwm_upper[i] = 0;
        pwm_lower[i] = 0;
        uvw[i].mode = 0;
    }
}
#elif PWM_WAVEFORM==1   // 1: triangler wave comparison
void pwmUout() {    // pwm out using timer
    unsigned char   i=0;
    uvw[i].mode += 1;
    if( uvw[i].mode==1 ){
        uvw[i].upper_us = uvw[i].duty*1000000/PWM_FREQ - DEADTIME_US;   // ON time of Uupper
        uvw[i].lower_us = 1000000/PWM_FREQ -uvw[i].upper_us - 2*DEADTIME_US; // ON time of Ulower
        pwm_upper[i] = 0;
        pwm_lower[i] = 1;
        uvw[i].lower_us /= 2;
        pwm[i].attach_us(&pwmUout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us]
    }else if( uvw[i].mode==2 ){
        pwm[i].attach_us(&pwmUout, DEADTIME_US); // setup pwmU to call pwmUout after t [us]
        pwm_upper[i] = 0;
        pwm_lower[i] = 0;
    }else if( uvw[i].mode==3 ){
        pwm[i].attach_us(&pwmUout, uvw[i].upper_us); // setup pwmU to call pwmUout after t [us]
        pwm_upper[i] = 1;
        pwm_lower[i] = 0;
    }else if( uvw[i].mode==4 ){
        pwm[i].attach_us(&pwmUout, DEADTIME_US); // setup pwmU to call pwmUout after t [us]
        pwm_upper[i] = 0;
        pwm_lower[i] = 0;
    }else{// if( uvw[i].mode==5 ){
        pwm[i].attach_us(&pwmUout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us]
        pwm_upper[i] = 0;
        pwm_lower[i] = 1;
        uvw[i].mode = 0;
    }
}
void pwmVout() {    // pwm out using timer
    unsigned char   i=1;
    uvw[i].mode += 1;
    if( uvw[i].mode==1 ){
        uvw[i].upper_us = uvw[i].duty*1000000/PWM_FREQ - DEADTIME_US;   // ON time of Uupper
        uvw[i].lower_us = 1000000/PWM_FREQ -uvw[i].upper_us - 2*DEADTIME_US; // ON time of Ulower
        pwm_upper[i] = 0;
        pwm_lower[i] = 1;
        uvw[i].lower_us /= 2;
        pwm[i].attach_us(&pwmVout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us]
    }else if( uvw[i].mode==2 ){
        pwm[i].attach_us(&pwmVout, DEADTIME_US); // setup pwmU to call pwmUout after t [us]
        pwm_upper[i] = 0;
        pwm_lower[i] = 0;
    }else if( uvw[i].mode==3 ){
        pwm[i].attach_us(&pwmVout, uvw[i].upper_us); // setup pwmU to call pwmUout after t [us]
        pwm_upper[i] = 1;
        pwm_lower[i] = 0;
    }else if( uvw[i].mode==4 ){
        pwm[i].attach_us(&pwmVout, DEADTIME_US); // setup pwmU to call pwmUout after t [us]
        pwm_upper[i] = 0;
        pwm_lower[i] = 0;
    }else{// if( uvw[i].mode==5 ){
        pwm[i].attach_us(&pwmVout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us]
        pwm_upper[i] = 0;
        pwm_lower[i] = 1;
        uvw[i].mode = 0;
    }
}

void pwmWout() {    // pwm out using timer
    unsigned char   i=2;
    uvw[i].mode += 1;
    if( uvw[i].mode==1 ){
        uvw[i].upper_us = uvw[i].duty*1000000/PWM_FREQ - DEADTIME_US;   // ON time of Uupper
        uvw[i].lower_us = 1000000/PWM_FREQ -uvw[i].upper_us - 2*DEADTIME_US; // ON time of Ulower
        pwm_upper[i] = 0;
        pwm_lower[i] = 1;
        uvw[i].lower_us /= 2;
        pwm[i].attach_us(&pwmWout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us]
    }else if( uvw[i].mode==2 ){
        pwm[i].attach_us(&pwmWout, DEADTIME_US); // setup pwmU to call pwmUout after t [us]
        pwm_upper[i] = 0;
        pwm_lower[i] = 0;
    }else if( uvw[i].mode==3 ){
        pwm[i].attach_us(&pwmWout, uvw[i].upper_us); // setup pwmU to call pwmUout after t [us]
        pwm_upper[i] = 1;
        pwm_lower[i] = 0;
    }else if( uvw[i].mode==4 ){
        pwm[i].attach_us(&pwmWout, DEADTIME_US); // setup pwmU to call pwmUout after t [us]
        pwm_upper[i] = 0;
        pwm_lower[i] = 0;
    }else{// if( uvw[i].mode==5 ){
        pwm[i].attach_us(&pwmWout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us]
        pwm_upper[i] = 0;
        pwm_lower[i] = 1;
        uvw[i].mode = 0;
    }
}
#endif


void start_pwm(){
    unsigned char i; 
    for( i=0;i<3;i++ ){
        uvw[i].duty = 0.5;
        pwm_upper[i] = pwm_lower[i] = 0;
        uvw[i].mode = 0;
    }
    pwmUout();
    pwmVout();
    pwmWout();
}

void stop_pwm(){
    unsigned char i; 
    for( i=0;i<3;i++ ){
        pwm_upper[i] = pwm_lower[i] = 0;
        uvw[i].mode = 0;
        pwm[i].detach();
    }
}