DRV8830/Texas Instruments H-Bridge Voltage-Controlled Motor Driver library for Brushed DC Motor

Dependents:   NucleoF401_motor_test_simple Frequency_Counter_w_GPS_1PPS Nucleo_ACM1602_I2C_DC_Angle Frequency_Cntr_1PPS_F746ZG

DRV8830.cpp

Committer:
kenjiArai
Date:
2017-08-23
Revision:
4:323a62f5fff3
Parent:
3:98a9369ed390

File content as of revision 4:323a62f5fff3:

/*
 * mbed library program 
 *  Texas Instruments / DRV8830 H-Bridge Voltage-Controlled Motor Driver
 *      http://www.ti.com/product/drv8830
 *
 * Copyright (c) 2014,'17 Kenji Arai / JH1PJL
 *  http://www.page.sannet.ne.jp/kenjia/index.html
 *  http://mbed.org/users/kenjiArai/
 *      Created: August      6th, 2014
 *      Revised: August     23rd, 2017
 */

#include    "mbed.h"
#include    "DRV8830.h"

//  motor status
#define DRV8830_FREE            0x00
#define DRV8830_CW              0x01
#define DRV8830_CCW             0x02
#define DRV8830_BREAK           0x03

//  register address
#define DRV8830_CONTROL         0x00
#define DRV8830_FAULT           0x01

//  voltage data
#define DRV8830_V_R48           0x06
#define DRV8830_V_R56           0x07
#define DRV8830_V_R64           0x08
#define DRV8830_V_R72           0x09
    // (no definition from 0.82V to 4.74V)
#define DRV8830_V_4R82          0x3c
#define DRV8830_V_4R90          0x3d
#define DRV8830_V_4R98          0x3e
#define DRV8830_V_5R06          0x3f

#define DRV8830_V_MIN           0x06
#define DRV8830_V_MAX           0x3f
#define DRV8830_V_RANGE         (DRV8830_V_MAX - DRV8830_V_MIN)

//  fault status
#define DRV8830_F_CLEAR         0x80

// Voltage Control
#define DRV8830_FREE            0x00
#define DRV8830_POSI            0x01
#define DRV8830_NEGA            0x02
#define DRV8830_BREAK           0x03

// Voltage table
#define TBL_OFFSET              0x06
#define TBL_SIZE                58
#define TBL_MAX_VALUE           (5.06f)
#define TBL_MIN_VALUE           (0.48f)

const float voltage_table [] = {
    0.48,    0.56,    0.64,    0.72,    0.80,    0.88,    0.96,    1.04,
    1.12,    1.20,    1.29,    1.37,    1.45,    1.53,    1.61,    1.69,
    1.77,    1.85,    1.93,    2.01,    2.09,    2.17,    2.25,    2.33,
    2.41,    2.49,    2.57,    2.65,    2.73,    2.81,    2.89,    2.97,
    3.05,    3.13,    3.21,    3.29,    3.37,    3.45,    3.53,    3.61,
    3.69,    3.77,    3.86,    3.94,    4.02,    4.10,    4.18,    4.26,
    4.34,    4.42,    4.50,    4.58,    4.66,    4.74,    4.82,    4.90,
    4.98,    5.06
};

DRV8830::DRV8830 (PinName p_sda, PinName p_scl, uint8_t addr)
 : _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p)
{
    DRV8830_addr = (char)addr;
}

DRV8830::DRV8830 (I2C& p_i2c, uint8_t addr)
 : _i2c(p_i2c)
{ 
    DRV8830_addr = (char)addr;
}

void DRV8830::speed(float speed) {
uint8_t direction = 0;
uint8_t pwm_rate = 0;
uint8_t dt[2];

    if (speed == 0.0f ){
        pwm_rate = DRV8830_V_MIN;
        direction = DRV8830_FREE;
    } else if (speed > 0.0f){
        pwm_rate = (uint8_t)(DRV8830_V_RANGE * speed) + DRV8830_V_MIN;
        direction = DRV8830_CW;
    } else if (speed < 0.0f){
        speed *= -1.0f;
        pwm_rate = (uint8_t)(DRV8830_V_RANGE * speed) + DRV8830_V_MIN;
        direction = DRV8830_CCW;
    }
    if (pwm_rate > DRV8830_V_MAX){
        pwm_rate = DRV8830_V_MAX;
    } else if (pwm_rate < DRV8830_V_MIN){
        pwm_rate = DRV8830_V_MIN;
    }
    dt[0] = DRV8830_CONTROL;
    dt[1] = (pwm_rate << 2) + direction;
    _i2c.write((int)DRV8830_addr, (char *)dt, 2);
}

void DRV8830::set_voltage(float volt) {
uint8_t direction = 0;
uint8_t pwm_rate = 0;
uint8_t dt[2];

    if (volt < 0){
        direction = DRV8830_NEGA;
        volt *= -1;
    } else {
        direction = DRV8830_POSI; 
    }
    if (volt >= TBL_MAX_VALUE) {
        pwm_rate = TBL_SIZE + TBL_OFFSET - 1;
    } else {
        for (uint32_t i = 0; i < TBL_SIZE; i++){ 
            if (volt < voltage_table[i]) {
                //printf("n=%d, voltage_table[i]=%f\r\n", i, voltage_table[i]);
                if (i == 0){
                    pwm_rate = 0;
                    direction = DRV8830_FREE;
                } else {
                    pwm_rate = i + TBL_OFFSET;
                }
                break;
            }
        } 
    }
    //printf("volt=%f, pwm=0x%x, dir=%d\r\n", volt, pwm_rate, direction);
    dt[0] = DRV8830_CONTROL;
    dt[1] = (pwm_rate << 2) + direction;
    _i2c.write((int)DRV8830_addr, (char *)dt, 2);
}

uint8_t DRV8830::status() {
uint8_t dt[2];

    dt[0] = DRV8830_FAULT;
    _i2c.write((int)DRV8830_addr, (char *)dt, 1);  // write register address
    _i2c.read((int)DRV8830_addr, (char *)dt, 1);   // read register content
    return dt[0];
}

void DRV8830::reset() {
uint8_t dt[2];

    dt[0] = DRV8830_FAULT;
    dt[1] = DRV8830_F_CLEAR;
    _i2c.write((int)DRV8830_addr, (char *)dt, 2);
}