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@3:98a9369ed390, 2014-12-23 (annotated)
- Committer:
- kenjiArai
- Date:
- Tue Dec 23 23:28:54 2014 +0000
- Revision:
- 3:98a9369ed390
- Parent:
- 1:a9b58bc85be0
- Child:
- 4:323a62f5fff3
change explanation e.g. 1.0 -> 1.0f
Who changed what in which revision?
User | Revision | Line number | New 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 | 3:98a9369ed390 | 86 | if (speed == 0.0f ){ |
kenjiArai | 0:05db098cf4f8 | 87 | pwm_rate = DRV8830_V_MIN; |
kenjiArai | 0:05db098cf4f8 | 88 | direction = DRV8830_FREE; |
kenjiArai | 3:98a9369ed390 | 89 | } else if (speed > 0.0f){ |
kenjiArai | 0:05db098cf4f8 | 90 | pwm_rate = (uint8_t)(DRV8830_V_RANGE * speed) + DRV8830_V_MIN; |
kenjiArai | 0:05db098cf4f8 | 91 | direction = DRV8830_CW; |
kenjiArai | 3:98a9369ed390 | 92 | } else if (speed < 0.0f){ |
kenjiArai | 3:98a9369ed390 | 93 | speed *= -1.0f; |
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 |