Jump to content
43oh

Launchpad TB6612FNG Motor Driver


Recommended Posts

I've created a simple program to use the Toshiba TB6612FNG motor driver (http://www.sparkfun.com/products/9457) with the MSP430. Currently, I have it configured for use on the MSP430G2553 on the Launchpad. It uses PWM output from TA0 for the left motor driver and TA1 for the right motor drive. This code is set for 50% duty cycle. 20% is the lowest speed, 100% is the fastest. Anything less than 20% duty cycle just causes the motors to whine. Of course that may vary based on motor selection and power input. The on-board button at P1.3 is used to start and stop the function for now.

Make sure to follow the data sheet for connections. http://www.semicon.toshiba.co.jp/docs/datasheet/en/LinearIC/TB6612FNG_en_datasheet_080509.pdf Vcc connects to the Launchpad's vcc pin and Vm connects to the motor's power source.

 

/****************************************************************/
/* Greg Whitmore												*/
/* greg@gwdeveloper.net											*/
/* www.gwdeveloper.net											*/
/****************************************************************/
/* released under the "Use at your own risk" license			*/
/* use it how you want, where you want and have fun				*/
/* debugging the code.											*/
/* MSP430G2553													*/
/****************************************************************/

#include 

// TB6612FNG defines
#define AIN1 BIT1		// P1.1
#define AIN2 BIT0		// P1.0
#define BIN1 BIT0		// P2.0
#define BIN2 BIT1		// P2.1
#define STANDBY BIT6	// P1.6

// button status
unsigned char buttonOn;

// prototype drive functions
void forward(void);
void reverse(void);
void full_brake(void);
void stop(void);

void main(void)
{
   WDTCTL = WDTPW + WDTTMSEL + WDTSSEL + WDTIS1;	// WDT as interval timer for debouncing of P1.3 button
   												// interval mode, low speed clock, /512

// enable button on P1.3 with interrupt
   P1OUT = BIT3;
   P1REN = BIT3;
   P1IES = BIT3;
   P1IE = BIT3;
   P1IFG = 0;		// clear P1 interrupt flags

   // rest of gpio for motor output
   P1SEL = BIT2;							// select TimerA0.1 PWMA output
   P1DIR = BIT0 + BIT1 + BIT2 + BIT6;		// set P1 output bits for AIN1, AIN2 and STANDBY

   P2SEL = BIT2;							// select TimerA1.1 PWMB output
   P2SEL &= ~(BIT6 + BIT7);				// turn off xtal
   P2DIR = BIT0 + BIT1 + BIT2;				// set P2 output bits for BIN1, BIN2

   BCSCTL2 = SELM_0 + DIVM_0 + DIVS_0;    
   DCOCTL = 0x00;					// clear DCO bits
   BCSCTL1 = CALBC1_1MHZ;			// Set DCO to calibrated 1MHz
   DCOCTL = CALDCO_1MHZ;
   BCSCTL1 |= XT2OFF + DIVA_0;
   BCSCTL3 = XT2S_0 + LFXT1S_2 + XCAP_1;    												

   IFG1 &= ~(WDTIFG);				// clear WDT flags
   IE1 |= WDTIE;					// enable WDT interrupt

   // left motor pwm configuration; adjust TA0CCR1 for speed, less than 20% = no motor power
   TA0CCTL1 = CM_0 + CCIS_0 + OUTMOD_7;	// no capture, PWM reset/set
TA0CCR0 = 511;
TA0CCR1 = 255;							// 50% duty cycle
   TA0CTL = TASSEL_2 + ID_0 + MC_1;		// SMCLK, /1, up mode

   // right motor pwm configuration; adjust TA1CCR1 for speed, less than 20% = no motor power
   TA1CCTL1 = CM_0 + CCIS_0 + OUTMOD_7;	// no capture, PWM reset/set
TA1CCR0 = 511;
TA1CCR1 = 255;							// 50% duty cycle
   TA1CTL = TASSEL_2 + ID_0 + MC_1;		// SMCLK, /1, up mode

   buttonOn = 0;

   __enable_interrupt();           // Set global interrupt enable


   forward();			// enable forward bits for testing, replace with reverse function
   //reverse();

   while (1)
   {
       LPM0;			// turn CPUOFF and keep it there
   }
}

// both motors forward; AIN1 low, AIN2 high, BIN1 high, BIN2 low
// use TA0.1 & TA1.1 PWM to control speed
void forward(void)
{
P1OUT |= AIN2;
   P1OUT &= ~AIN1;

   P2OUT &= ~BIN2;
   P2OUT |= BIN1;
}

// both motors reverse; AIN1 high, AIN2 low, BIN1 low, BIN2 high
// use TA0.1 & TA1.1 PWM to control speed
void reverse(void)
{
P1OUT |= AIN1;
   P1OUT &= ~AIN2;

   P2OUT &= ~BIN1;
   P2OUT |= BIN2;
}

// both motors brake; all high
void full_brake(void)
{
P1OUT |= AIN1;
   P1OUT |= AIN2;

   P2OUT |= BIN1;
   P2OUT |= BIN2;
}

// both motors stop; all low
void stop(void)
{
P1OUT &= ~AIN1;
   P1OUT &= ~AIN2;

   P2OUT &= ~BIN1;
   P2OUT &= ~BIN2;
}

#pragma vector=PORT1_VECTOR
__interrupt void button_push_isr(void)
{
   P1IFG &= ~BIT3;			// clear P1.3 button flag
   P1IE &= ~BIT3;			// clear P1.3 interrupt

   IFG1 &= ~WDTIFG;
   WDTCTL = (WDTCTL & 7) + WDTCNTCL + WDTPW + WDTTMSEL;
   IE1 |= WDTIE;

// use button to toggle motors on/off for testing
   if (buttonOn == 1) {
       buttonOn = 0;
       P1OUT &= ~STANDBY; // motor driver disable
   }
   else {
       buttonOn = 1;
       P1OUT |= STANDBY; // motor driver enable
   }
}

#pragma vector=WDT_VECTOR
__interrupt void watchdog_isr(void)
{
   IE1 &= ~WDTIE;

   P1IFG &= ~BIT3;			// clear P1.3 button flag
   P1IE |= BIT3;			// re-enable P1.3 interrupt
}

We're going to use this as part of our line-follower project. http://www.43oh.com/forum/viewtopic.php?f=9&t=1701

Link to post
Share on other sites
  • 4 weeks later...

I picked it because of price. Only $8.95 on a breakout board with the needed circuitry. It has plenty of power for the small motors included with the Magician Robot Chassis too. Works well enough that I'm considering using it to make a simple Robotics Booster Pack.

 

Features:

 

Power supply voltage: VM=15V max, VCC=2.7-5.5V

Output current: Iout=1.2A(average) / 3.2A (peak)

Standby control to save power

CW/CCW/short brake/stop motor control modes

Built-in thermal shutdown circuit and low voltage detecting circuit

All pins of the TB6612FNG broken out to 0.1" spaced pins

Filtering capacitors on both supply lines

Link to post
Share on other sites

Thanks GW, What do you think of the TI DRV8833? I realize it needs a couple of components to work, but it is really cheap...

By the way, thanks for sharing that code. I was stumbling around trying to figure out a way to make it work for me, and this will handle the PWM part as well as the "mode" switches. I have some success with your suggestions for the ADC component as well. They should work perfectly together for me.

 

KB

Link to post
Share on other sites
  • 2 weeks later...

Hi GW,

 

I started messing around and got my motor driver to work using an adaptation of your code. I am trying to get 4 channels to deliver PWM output. Using your code, i have 2 channels working fine, but i needed to hook them up to P1.2 and P2.2 to get the desired signals. I have 2 questions please: 1) do i understand correctly that to use the PwM function of the MSP it will occupy three pins each, for example P1&2 BITS 0,1, and 2) PWM can not be controlled via "P1OUT BIT2"? Can you assign timer to multiple pins to deliver the same timer pulse to each. I have been trying to understand this for almost a year now.

 

Thanks. KB

Link to post
Share on other sites

KB, hardware wise you should be able to output 3 PWM channels on the 20 pin MSP430G2553 since it has 2 TimerA peripherals but no pin access for TA0.2. The 3 channels could be output on TA0.1, TA1.1 and TA1.2. You have P1.2 and P2.2 correct, TA1.2 is output on P2.4 and P2.5. If you really need 4 hardware PWM channels, you'll need to go to the 28pin version of the G2553. It has TA0.2 available on P3.0 and P3.6.

 

That aside, you only need to use the timer pins you want to output the PWM on. For eg, to use TA0.1, you output your PWM on P1.2 but you can use P1.1 and P1.0 as GPIO or their other functions. Unless, you're wanting to output those TimerA signals.

 

Also, somewhere on the web, I've seen 'bit-banging' pwm for the msp430 to get more channels out of the LP.

 

Hope that all makes sense.

Link to post
Share on other sites
  • 2 weeks later...

You could save IO pins on the msp by connecting the pwm pins the following way :

 

TA0 ---------------> AIN1

|------o> AIN2

 

TA0 is directly connected to AIN1 and is also connected to AIN2 through an inverter (or one NPN). Ths way, a duty cycle of 50% stop the motor, 0% makes it full speed one direction and 100% full speed the other direction.

Link to post
Share on other sites

Sorry for the bad ASCII schematic. In fact the output pin of your uc is connected directly to AIN1 and to AIN2 through an inverter (the dot on my ascii schematic). I personnaly use a single NPN transistor to make the inverter. You are right that it decreases the speed resolution, and it makes it not linear. But this method not only saves pins, it is also said to give better torque performance. I have tested this design with the MSP430g2231 + L293D for a balancing bot and it works well (even if the bot cannot keep balance at the time ...).

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...