MC33926 is a H-Bridge from freescale. This driver allow to use it to drive a DC-Motor using 3 different driving methods: - Lock Antiphase - Sign-Magnitude braking - Sign-Magnitude coasting I used this board https://www.sparkfun.com/products/11080 for my tests and find a lot of informations here: http://modularcircuits.tantosonline.com/blog/articles/h-bridge-secrets/h-bridge-control/

mc33926.cpp

Committer:
garfunkheul
Date:
2013-10-08
Revision:
0:217bc3688cff

File content as of revision 0:217bc3688cff:

#include "mc33926.h"

mc33926::mc33926(PinName inv, PinName in1, PinName in2, PinName d1, PinName d2, PinName en, PinName sf)
{
    pin_inv = inv;
    pin_in1 = in1;
    pin_in2 = in2;
    pin_d1  = d1;
    pin_d2  = d2;
    pin_en  = en;
    pin_sf  = sf;

    period = 50;
    speed = 0;
    pwm = NULL;

    disable();
    set_mode(SIGN_MAGNITUDE_COASTING);
}

void mc33926::setup_lock_antiphase()
{
    DigitalOut  in1(pin_in1);
    DigitalOut  in2(pin_in2);
    DigitalOut  d1(pin_d1);
    DigitalOut  d2(pin_d2);

    in1 = d2 = 1;
    in2 = d1 = 0;

    /* Force Pin reconfiguration */
    if (pwm)
        delete pwm;
    pwm = new PwmOut(pin_inv);

    period_lock_antiphase();
}

float mc33926::speed_lock_antiphase()
{
    float duty;
    /* Use same sens as sign_magnitude */
    int _speed = (-1) * speed;

    if (_speed > 0)
        duty = (((_speed * 50 / MAX_SPEED) + 50) / 100.0f);
    else if (_speed < 0)
        duty = ((50 - ((_speed * -50 / MAX_SPEED))) / 100.0f);
    else
        duty = 0.5;
        
    pwm->write(duty);
    
    return duty;
}

void mc33926::period_lock_antiphase()
{
    pwm->period_us(period);
    speed_lock_antiphase();
}

void mc33926::setup_sign_magnitude_braking()
{
    DigitalOut in2(pin_in2);
    DigitalOut d1(pin_d1);
    DigitalOut d2(pin_d2);
    
    in2 = d1 = 0;
    d2 = 1;
    
    /* Force Pin reconfiguration */
    if (pwm)
        delete pwm;
    pwm = new PwmOut(pin_in1);
    
    period_sign_magnitude();
}

float mc33926::speed_sign_magnitude()
{
    float duty;
    DigitalOut inv(pin_inv);
    
    if (speed > 0) {
        inv = 0;
        duty = (speed * 100 / MAX_SPEED) / 100.0f;
    } else if (speed < 0) {
        inv = 1;
        duty = (speed * -100 / MAX_SPEED) / 100.0f;
    } else {
        duty = 0;
    }
    
    pwm->write(duty);
    return duty;
}

void mc33926::period_sign_magnitude()
{
    pwm->period_us(period);
    speed_sign_magnitude();
}

void mc33926::setup_sign_magnitude_coasting()
{
    DigitalOut in1(pin_in1);
    DigitalOut in2(pin_in2);
    DigitalOut d1(pin_d1);
    
    in2 = d1 = 0;
    in1 = 1;
    
    /* Force Pin reconfiguration */
    if (pwm)
        delete pwm;
    pwm = new PwmOut(pin_d2);
    
    period_sign_magnitude();
}

void mc33926::set_period(int _period)
{
    period = _period;

    switch(mode) {
        case LOCK_ANTIPHASE:
            period_lock_antiphase();
            break;
        case SIGN_MAGNITUDE_BRAKING:
        case SIGN_MAGNITUDE_COASTING:
            period_sign_magnitude();
            break;
    }
}

float mc33926::set_speed(int _speed)
{
    if (_speed > MAX_SPEED)
        speed = MAX_SPEED;
    else if (_speed < -MAX_SPEED)
        speed = -MAX_SPEED;
    else
        speed = _speed;

    switch(mode) {
        case LOCK_ANTIPHASE:
            return speed_lock_antiphase();
        case SIGN_MAGNITUDE_BRAKING:
        case SIGN_MAGNITUDE_COASTING:
            return speed_sign_magnitude();
    }
}

void mc33926::set_mode(int _mode)
{
    mode = _mode;

    switch(mode) {
        case LOCK_ANTIPHASE:
            setup_lock_antiphase();
            break;
        case SIGN_MAGNITUDE_BRAKING:
            setup_sign_magnitude_braking();
        case SIGN_MAGNITUDE_COASTING:
            setup_sign_magnitude_coasting();
            break;
    }
}

void mc33926::enable()
{
    DigitalOut en(pin_en);

    if (pin_en != NC)
        en = 1;
}

void mc33926::disable()
{
    DigitalOut en(pin_en);

    if (pin_en != NC)
        en = 0;
}

int mc33926::get_speed()
{
    return speed;
}

int mc33926::get_mode()
{
    return mode;
}


int mc33926::get_period()
{
    return period;
}