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); }