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

Committer:
kenjiArai
Date:
Thu Nov 27 21:25:10 2014 +0000
Revision:
1:a9b58bc85be0
Parent:
0:05db098cf4f8
Child:
3:98a9369ed390
Fixed Buf in status() & reset().  Added new functions for voltage control.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 0:05db098cf4f8 1 /*
kenjiArai 0:05db098cf4f8 2 * mbed library program
kenjiArai 0:05db098cf4f8 3 * Texas Instruments / DRV8830 H-Bridge Voltage-Controlled Motor Driver
kenjiArai 0:05db098cf4f8 4 * http://www.ti.com/product/drv8830
kenjiArai 0:05db098cf4f8 5 *
kenjiArai 0:05db098cf4f8 6 * Copyright (c) 2014 Kenji Arai / JH1PJL
kenjiArai 0:05db098cf4f8 7 * http://www.page.sannet.ne.jp/kenjia/index.html
kenjiArai 0:05db098cf4f8 8 * http://mbed.org/users/kenjiArai/
kenjiArai 0:05db098cf4f8 9 * Created: August 6th, 2014
kenjiArai 1:a9b58bc85be0 10 * Revised: November 28th, 2014
kenjiArai 0:05db098cf4f8 11 *
kenjiArai 0:05db098cf4f8 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
kenjiArai 0:05db098cf4f8 13 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
kenjiArai 0:05db098cf4f8 14 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
kenjiArai 0:05db098cf4f8 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
kenjiArai 0:05db098cf4f8 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
kenjiArai 0:05db098cf4f8 17 */
kenjiArai 0:05db098cf4f8 18
kenjiArai 0:05db098cf4f8 19 #include "mbed.h"
kenjiArai 0:05db098cf4f8 20 #include "DRV8830.h"
kenjiArai 0:05db098cf4f8 21
kenjiArai 0:05db098cf4f8 22 // motor status
kenjiArai 0:05db098cf4f8 23 #define DRV8830_FREE 0x00
kenjiArai 0:05db098cf4f8 24 #define DRV8830_CW 0x01
kenjiArai 0:05db098cf4f8 25 #define DRV8830_CCW 0x02
kenjiArai 0:05db098cf4f8 26 #define DRV8830_BREAK 0x03
kenjiArai 0:05db098cf4f8 27
kenjiArai 0:05db098cf4f8 28 // register address
kenjiArai 0:05db098cf4f8 29 #define DRV8830_CONTROL 0x00
kenjiArai 0:05db098cf4f8 30 #define DRV8830_FAULT 0x01
kenjiArai 0:05db098cf4f8 31
kenjiArai 0:05db098cf4f8 32 // voltage data
kenjiArai 0:05db098cf4f8 33 #define DRV8830_V_R48 0x06
kenjiArai 0:05db098cf4f8 34 #define DRV8830_V_R56 0x07
kenjiArai 0:05db098cf4f8 35 #define DRV8830_V_R64 0x08
kenjiArai 0:05db098cf4f8 36 #define DRV8830_V_R72 0x09
kenjiArai 0:05db098cf4f8 37 // (no definition from 0.82V to 4.74V)
kenjiArai 0:05db098cf4f8 38 #define DRV8830_V_4R82 0x3c
kenjiArai 0:05db098cf4f8 39 #define DRV8830_V_4R90 0x3d
kenjiArai 0:05db098cf4f8 40 #define DRV8830_V_4R98 0x3e
kenjiArai 0:05db098cf4f8 41 #define DRV8830_V_5R06 0x3f
kenjiArai 0:05db098cf4f8 42
kenjiArai 0:05db098cf4f8 43 #define DRV8830_V_MIN 0x06
kenjiArai 0:05db098cf4f8 44 #define DRV8830_V_MAX 0x3f
kenjiArai 0:05db098cf4f8 45 #define DRV8830_V_RANGE (DRV8830_V_MAX - DRV8830_V_MIN)
kenjiArai 0:05db098cf4f8 46
kenjiArai 0:05db098cf4f8 47 // fault status
kenjiArai 0:05db098cf4f8 48 #define DRV8830_F_CLEAR 0x80
kenjiArai 0:05db098cf4f8 49
kenjiArai 1:a9b58bc85be0 50 // Voltage Control
kenjiArai 1:a9b58bc85be0 51 #define DRV8830_FREE 0x00
kenjiArai 1:a9b58bc85be0 52 #define DRV8830_POSI 0x01
kenjiArai 1:a9b58bc85be0 53 #define DRV8830_NEGA 0x02
kenjiArai 1:a9b58bc85be0 54 #define DRV8830_BREAK 0x03
kenjiArai 1:a9b58bc85be0 55
kenjiArai 1:a9b58bc85be0 56 // Voltage table
kenjiArai 1:a9b58bc85be0 57 #define TBL_OFFSET 0x06
kenjiArai 1:a9b58bc85be0 58 #define TBL_SIZE 58
kenjiArai 1:a9b58bc85be0 59 #define TBL_MAX_VALUE (5.06f)
kenjiArai 1:a9b58bc85be0 60 #define TBL_MIN_VALUE (0.48f)
kenjiArai 1:a9b58bc85be0 61
kenjiArai 1:a9b58bc85be0 62 const float voltage_table [] = {
kenjiArai 1:a9b58bc85be0 63 0.48, 0.56, 0.64, 0.72, 0.80, 0.88, 0.96, 1.04,
kenjiArai 1:a9b58bc85be0 64 1.12, 1.20, 1.29, 1.37, 1.45, 1.53, 1.61, 1.69,
kenjiArai 1:a9b58bc85be0 65 1.77, 1.85, 1.93, 2.01, 2.09, 2.17, 2.25, 2.33,
kenjiArai 1:a9b58bc85be0 66 2.41, 2.49, 2.57, 2.65, 2.73, 2.81, 2.89, 2.97,
kenjiArai 1:a9b58bc85be0 67 3.05, 3.13, 3.21, 3.29, 3.37, 3.45, 3.53, 3.61,
kenjiArai 1:a9b58bc85be0 68 3.69, 3.77, 3.86, 3.94, 4.02, 4.10, 4.18, 4.26,
kenjiArai 1:a9b58bc85be0 69 4.34, 4.42, 4.50, 4.58, 4.66, 4.74, 4.82, 4.90,
kenjiArai 1:a9b58bc85be0 70 4.98, 5.06
kenjiArai 1:a9b58bc85be0 71 };
kenjiArai 1:a9b58bc85be0 72
kenjiArai 0:05db098cf4f8 73 DRV8830::DRV8830 (PinName p_sda, PinName p_scl, uint8_t addr) : i2c(p_sda, p_scl){
kenjiArai 0:05db098cf4f8 74 DRV8830_addr = (char)addr;
kenjiArai 0:05db098cf4f8 75 }
kenjiArai 0:05db098cf4f8 76
kenjiArai 0:05db098cf4f8 77 DRV8830::DRV8830 (I2C& p_i2c, uint8_t addr) : i2c(p_i2c){
kenjiArai 0:05db098cf4f8 78 DRV8830_addr = (char)addr;
kenjiArai 0:05db098cf4f8 79 }
kenjiArai 0:05db098cf4f8 80
kenjiArai 0:05db098cf4f8 81 void DRV8830::speed(float speed) {
kenjiArai 0:05db098cf4f8 82 uint8_t direction = 0;
kenjiArai 0:05db098cf4f8 83 uint8_t pwm_rate = 0;
kenjiArai 0:05db098cf4f8 84 uint8_t dt[2];
kenjiArai 0:05db098cf4f8 85
kenjiArai 0:05db098cf4f8 86 if (speed == 0.0 ){
kenjiArai 0:05db098cf4f8 87 pwm_rate = DRV8830_V_MIN;
kenjiArai 0:05db098cf4f8 88 direction = DRV8830_FREE;
kenjiArai 0:05db098cf4f8 89 } else if (speed > 0.0){
kenjiArai 0:05db098cf4f8 90 pwm_rate = (uint8_t)(DRV8830_V_RANGE * speed) + DRV8830_V_MIN;
kenjiArai 0:05db098cf4f8 91 direction = DRV8830_CW;
kenjiArai 0:05db098cf4f8 92 } else if (speed < 0.0){
kenjiArai 0:05db098cf4f8 93 speed *= -1;
kenjiArai 0:05db098cf4f8 94 pwm_rate = (uint8_t)(DRV8830_V_RANGE * speed) + DRV8830_V_MIN;
kenjiArai 0:05db098cf4f8 95 direction = DRV8830_CCW;
kenjiArai 0:05db098cf4f8 96 }
kenjiArai 0:05db098cf4f8 97 if (pwm_rate > DRV8830_V_MAX){
kenjiArai 0:05db098cf4f8 98 pwm_rate = DRV8830_V_MAX;
kenjiArai 0:05db098cf4f8 99 } else if (pwm_rate < DRV8830_V_MIN){
kenjiArai 0:05db098cf4f8 100 pwm_rate = DRV8830_V_MIN;
kenjiArai 0:05db098cf4f8 101 }
kenjiArai 0:05db098cf4f8 102 dt[0] = DRV8830_CONTROL;
kenjiArai 0:05db098cf4f8 103 dt[1] = (pwm_rate << 2) + direction;
kenjiArai 0:05db098cf4f8 104 i2c.write((int)DRV8830_addr, (char *)dt, 2);
kenjiArai 0:05db098cf4f8 105 }
kenjiArai 0:05db098cf4f8 106
kenjiArai 1:a9b58bc85be0 107 void DRV8830::set_voltage(float volt) {
kenjiArai 1:a9b58bc85be0 108 uint8_t direction = 0;
kenjiArai 1:a9b58bc85be0 109 uint8_t pwm_rate = 0;
kenjiArai 1:a9b58bc85be0 110 uint8_t dt[2];
kenjiArai 1:a9b58bc85be0 111
kenjiArai 1:a9b58bc85be0 112 if (volt < 0){
kenjiArai 1:a9b58bc85be0 113 direction = DRV8830_NEGA;
kenjiArai 1:a9b58bc85be0 114 volt *= -1;
kenjiArai 1:a9b58bc85be0 115 } else {
kenjiArai 1:a9b58bc85be0 116 direction = DRV8830_POSI;
kenjiArai 1:a9b58bc85be0 117 }
kenjiArai 1:a9b58bc85be0 118 if (volt >= TBL_MAX_VALUE) {
kenjiArai 1:a9b58bc85be0 119 pwm_rate = TBL_SIZE + TBL_OFFSET - 1;
kenjiArai 1:a9b58bc85be0 120 } else {
kenjiArai 1:a9b58bc85be0 121 for (uint32_t i = 0; i < TBL_SIZE; i++){
kenjiArai 1:a9b58bc85be0 122 if (volt < voltage_table[i]) {
kenjiArai 1:a9b58bc85be0 123 //printf("n=%d, voltage_table[i]=%f\r\n", i, voltage_table[i]);
kenjiArai 1:a9b58bc85be0 124 if (i == 0){
kenjiArai 1:a9b58bc85be0 125 pwm_rate = 0;
kenjiArai 1:a9b58bc85be0 126 direction = DRV8830_FREE;
kenjiArai 1:a9b58bc85be0 127 } else {
kenjiArai 1:a9b58bc85be0 128 pwm_rate = i + TBL_OFFSET;
kenjiArai 1:a9b58bc85be0 129 }
kenjiArai 1:a9b58bc85be0 130 break;
kenjiArai 1:a9b58bc85be0 131 }
kenjiArai 1:a9b58bc85be0 132 }
kenjiArai 1:a9b58bc85be0 133 }
kenjiArai 1:a9b58bc85be0 134 //printf("volt=%f, pwm=0x%x, dir=%d\r\n", volt, pwm_rate, direction);
kenjiArai 1:a9b58bc85be0 135 dt[0] = DRV8830_CONTROL;
kenjiArai 1:a9b58bc85be0 136 dt[1] = (pwm_rate << 2) + direction;
kenjiArai 1:a9b58bc85be0 137 i2c.write((int)DRV8830_addr, (char *)dt, 2);
kenjiArai 1:a9b58bc85be0 138 }
kenjiArai 1:a9b58bc85be0 139
kenjiArai 0:05db098cf4f8 140 uint8_t DRV8830::status() {
kenjiArai 0:05db098cf4f8 141 uint8_t dt[2];
kenjiArai 0:05db098cf4f8 142
kenjiArai 0:05db098cf4f8 143 dt[0] = DRV8830_FAULT;
kenjiArai 1:a9b58bc85be0 144 i2c.write((int)DRV8830_addr, (char *)dt, 1); // write register address
kenjiArai 1:a9b58bc85be0 145 i2c.read((int)DRV8830_addr, (char *)dt, 1); // read register content
kenjiArai 0:05db098cf4f8 146 return dt[0];
kenjiArai 0:05db098cf4f8 147 }
kenjiArai 0:05db098cf4f8 148
kenjiArai 0:05db098cf4f8 149 void DRV8830::reset() {
kenjiArai 0:05db098cf4f8 150 uint8_t dt[2];
kenjiArai 0:05db098cf4f8 151
kenjiArai 0:05db098cf4f8 152 dt[0] = DRV8830_FAULT;
kenjiArai 0:05db098cf4f8 153 dt[1] = DRV8830_F_CLEAR;
kenjiArai 1:a9b58bc85be0 154 i2c.write((int)DRV8830_addr, (char *)dt, 2);
kenjiArai 0:05db098cf4f8 155 }
kenjiArai 1:a9b58bc85be0 156