MHVLib
20111011
An efficiency oriented runtime library for AVR microcontrollers
|
00001 /* 00002 * Copyright (c) 2011, Make, Hack, Void Inc 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * * Redistributions of source code must retain the above copyright 00008 * notice, this list of conditions and the following disclaimer. 00009 * * Redistributions in binary form must reproduce the above copyright 00010 * notice, this list of conditions and the following disclaimer in the 00011 * documentation and/or other materials provided with the distribution. 00012 * * Neither the name of the Make, Hack, Void nor the 00013 * names of its contributors may be used to endorse or promote products 00014 * derived from this software without specific prior written permission. 00015 * 00016 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00017 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00018 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00019 * DISCLAIMED. IN NO EVENT SHALL MAKE, HACK, VOID BE LIABLE FOR ANY 00020 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00021 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00022 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00023 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00024 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00025 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 */ 00027 00028 #ifdef MHV_TIMER16_1 00029 00030 #include <MHV_SoftwareHBridge.h> 00031 00032 /* Create a new H bridge where all transistors are controlled by us 00033 * Bottom transistors are toggled between VCC & ground. 00034 * 00035 * ******************************* 00036 * UNTESTED - USE AT YOUR OWN RISK 00037 * ******************************* 00038 * 00039 * A timer is required for magnitude control. 00040 * If this is not required, a NULL may be passed 00041 * 00042 * If the H-bridge voltage is greater than VCC of the microcontroller: 00043 * * resistors R1 & R2 and diodes D1 & D2 must be installed 00044 * * Set type to MHV_SOFTWAREHBRIDGE_TYPE_PULLUP 00045 * * Top transistors are toggled between high impedance & ground 00046 * 00047 * If the H bridge voltage is less than or equal to the microcontroller voltage, 00048 * * resistors R1 & R2 can be omitted, and D1 and D2 can be shorted. 00049 * * Set type to MHV_SOFTWAREHBRIDGE_TYPE_DIRECT 00050 * * Top transistors are toggled between high impedance & ground 00051 * 00052 * The initial state is coasting 00053 */ 00054 MHV_SoftwareHBridge::MHV_SoftwareHBridge(MHV_SOFTWAREHBRIDGE_TYPE type, MHV_Timer16 *timer, uint8_t timerChannel, 00055 volatile uint8_t *dir1Top, volatile uint8_t *out1Top, volatile uint8_t *in1Top, uint8_t pin1Top, int8_t int1Top, 00056 volatile uint8_t *dir1Bottom, volatile uint8_t *out1Bottom, volatile uint8_t *in1Bottom, uint8_t pin1Bottom, int8_t int1Bottom, 00057 volatile uint8_t *dir2Top, volatile uint8_t *out2Top, volatile uint8_t *in2Top, uint8_t pin2Top, int8_t int2Top, 00058 volatile uint8_t *dir2Bottom, volatile uint8_t *out2Bottom, volatile uint8_t *in2Bottom, uint8_t pin2Bottom, int8_t int2Bottom) { 00059 _type = type; 00060 _timer = timer; 00061 _timerChannel = timerChannel; 00062 00063 _dir1Top = dir1Top; 00064 _out1Top = out1Top; 00065 _pin1Top = pin1Top; 00066 _out1Bottom = out1Bottom; 00067 _pin1Bottom = pin1Bottom; 00068 _dir2Top = dir2Top; 00069 _out2Top = out2Top; 00070 _pin2Top = pin2Top; 00071 _out2Bottom = out2Bottom; 00072 _pin2Bottom = pin2Bottom; 00073 00074 _direction = MHV_SOFTWAREHBRIDGE_DIR_COAST; 00075 } 00076 00077 /* Set up for a new timer pass 00078 * Care is taken in here to never allow the top and bottom of any side 00079 * to be on simultaneously 00080 */ 00081 void MHV_SoftwareHBridge::reset() { 00082 switch (_direction) { 00083 case MHV_SOFTWAREHBRIDGE_DIR_COAST: 00084 // Tops and bottoms are off 00085 switch (_type) { 00086 case MHV_SOFTWAREHBRIDGE_TYPE_PULLUP: 00087 mhv_setInput(_dir1Top, _out1Top, NULL, _pin1Top, -1); 00088 mhv_setInput(_dir2Top, _out2Top, NULL, _pin2Top, -1); 00089 break; 00090 case MHV_SOFTWAREHBRIDGE_TYPE_DIRECT: 00091 mhv_pinOn(NULL, _out1Top, NULL, _pin1Top, -1); 00092 mhv_pinOn(NULL, _out2Top, NULL, _pin2Top, -1); 00093 break; 00094 } 00095 mhv_pinOff(NULL, _out1Bottom, NULL, _pin1Bottom, -1); 00096 mhv_pinOff(NULL, _out2Bottom, NULL, _pin2Bottom, -1); 00097 break; 00098 case MHV_SOFTWAREHBRIDGE_DIR_FORWARD: 00099 // Top 1 is on, bottom 2 is on 00100 mhv_pinOff(NULL, _out1Bottom, NULL, _pin1Bottom, -1); 00101 switch (_type) { 00102 case MHV_SOFTWAREHBRIDGE_TYPE_PULLUP: 00103 mhv_setInput(_dir2Top, _out2Top, NULL, _pin2Top, -1); 00104 mhv_setOutput(_dir1Top, _out1Top, NULL, _pin1Top, -1); 00105 mhv_pinOff(_dir1Top, _out1Top, NULL, _pin1Top, -1); 00106 break; 00107 case MHV_SOFTWAREHBRIDGE_TYPE_DIRECT: 00108 mhv_pinOn(NULL, _out2Top, NULL, _pin2Top, -1); 00109 mhv_pinOff(NULL, _out1Top, NULL, _pin1Top, -1); 00110 break; 00111 } 00112 mhv_pinOn(NULL, _out2Bottom, NULL, _pin2Bottom, -1); 00113 break; 00114 case MHV_SOFTWAREHBRIDGE_DIR_BACKWARD: 00115 // Top 2 is on, bottom 1 is on 00116 mhv_pinOff(NULL, _out2Bottom, NULL, _pin2Bottom, -1); 00117 switch (_type) { 00118 case MHV_SOFTWAREHBRIDGE_TYPE_PULLUP: 00119 mhv_setInput(_dir1Top, _out1Top, NULL, _pin1Top, -1); 00120 mhv_setOutput(_dir2Top, _out2Top, NULL, _pin2Top, -1); 00121 mhv_pinOff(_dir2Top, _out2Top, NULL, _pin2Top, -1); 00122 break; 00123 case MHV_SOFTWAREHBRIDGE_TYPE_DIRECT: 00124 mhv_pinOn(NULL, _out1Top, NULL, _pin1Top, -1); 00125 mhv_pinOff(NULL, _out2Top, NULL, _pin2Top, -1); 00126 break; 00127 } 00128 mhv_pinOn(NULL, _out1Bottom, NULL, _pin1Bottom, -1); 00129 break; 00130 case MHV_SOFTWAREHBRIDGE_DIR_BRAKE: 00131 // Bottoms are on 00132 switch (_type) { 00133 case MHV_SOFTWAREHBRIDGE_TYPE_PULLUP: 00134 mhv_setInput(_dir1Top, _out1Top, NULL, _pin1Top, -1); 00135 mhv_setInput(_dir2Top, _out2Top, NULL, _pin2Top, -1); 00136 break; 00137 case MHV_SOFTWAREHBRIDGE_TYPE_DIRECT: 00138 mhv_pinOn(NULL, _out1Top, NULL, _pin1Top, -1); 00139 mhv_pinOn(NULL, _out2Top, NULL, _pin2Top, -1); 00140 break; 00141 } 00142 mhv_pinOn(NULL, _out1Bottom, NULL, _pin1Bottom, -1); 00143 mhv_pinOn(NULL, _out2Bottom, NULL, _pin2Bottom, -1); 00144 break; 00145 } 00146 } 00147 00148 /* Set the H bridge to coasting after the end of a timer cycle for PWM 00149 * This should be called from the trigger of the associated timer 00150 */ 00151 void MHV_SoftwareHBridge::update() { 00152 // Set to coasting until the next reset 00153 switch (_type) { 00154 case MHV_SOFTWAREHBRIDGE_TYPE_PULLUP: 00155 mhv_setInput(_dir1Top, _out1Top, NULL, _pin1Top, -1); 00156 mhv_setInput(_dir2Top, _out2Top, NULL, _pin2Top, -1); 00157 break; 00158 case MHV_SOFTWAREHBRIDGE_TYPE_DIRECT: 00159 mhv_pinOn(NULL, _out1Top, NULL, _pin1Top, -1); 00160 mhv_pinOn(NULL, _out2Top, NULL, _pin2Top, -1); 00161 break; 00162 } 00163 mhv_pinOff(NULL, _out1Bottom, NULL, _pin1Bottom, -1); 00164 mhv_pinOff(NULL, _out2Bottom, NULL, _pin2Bottom, -1); 00165 } 00166 00167 /* Set the direction and magnitude of the H bridge 00168 * Requires a timer to be specified 00169 * param: direction the direction of the bridge 00170 * param: magnitude the magnitude of the direction (from 0 to TOP of the timer) 00171 */ 00172 void MHV_SoftwareHBridge::set(MHV_SOFTWAREHBRIDGE_DIRECTION direction, uint16_t magnitude) { 00173 _direction = direction; 00174 00175 if (MHV_SOFTWAREHBRIDGE_DIR_COAST == direction || 00176 MHV_SOFTWAREHBRIDGE_DIR_BRAKE == direction) { 00177 reset(); 00178 } 00179 00180 _timer->setOutput(_timerChannel, magnitude); 00181 } 00182 00183 /* Set the direction of the H bridge 00184 * Does not require a timer to be specified 00185 * param: direction the direction of the H bridge 00186 */ 00187 void MHV_SoftwareHBridge::set(MHV_SOFTWAREHBRIDGE_DIRECTION direction) { 00188 _direction = direction; 00189 reset(); 00190 } 00191 00192 #endif // MHV_TIMER16_1