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