Apr 13

MSP430 Power Fet Booster Pack Basic IO code

This is just a quick post going over some basic IO functionality utilizing a booster pack I designed for the launch pad. I am toggling all of the IO pins of interest for my booster pack to make sure this new board I built up works correctly. I decided to post this because it is simple and easy to understand. There is also code for interrupt service routines that may help a few of you out.

The first code block is basic clock configuration. Here I use preset constants from the 2553 header file to configure the clock registers. I then source MCLK (main instruction clock) and SMCLK (sub-main clock) from the DCO. I divide SMCLK by 8 so that I don't have to count as high in my TA0 module since SMCLK will be clocking that peripheral.

	// Configure Submain clock for TimerA
	BCSCTL2 &= ~SELM0;	// MCLK comes from DCO
	BCSCTL2 &= ~SELS;	// Sub main clock comes from DCO
	BCSCTL2 |= DIVS0 + DIVS1;	// SMCLK = 1 MHz (DC0/8)

Next, I setup the ability to see and interrupt on a falling edge from the pushbutton on the launchpad. This, I think, was worth while writing up because it can be a bit confusing. Watch the video if this write-up doesn't explain it well enough. From the schematics you can see that the pushbutton connects ground to P1.3. If the button is pressed you get P1.3 connected directly to ground, but the problems arise when the button is not pushed. If it isn't, than P1.3 is floating. In hardware design you never want anything to float and this is where we get into pull-ups. Pull-ups (in hardware) are just resistors that pull something up to Vcc. So for this example, in hardware, you would have a resistor connecting P1.3 to Vcc. This would force that pin to be high (logic one, Vcc voltage level) when the button isn't pushed and shorted to ground (which effectively overrides the pullup) when the button is pressed. Now, since this isn't done in "hardware" we must do it in software.

The register of interest is the P1REN register. This register enables pullups/pulldowns (pull downs are the same except they would pull the pin to ground) for a specific pin. When PxREN is enabled, PxOUT then determines whether the pin is pulled up or pulled down. This may seem confusing at first, but remember that when using this pull up pull down stuff the pin of interest will have to be an input. This allows PxOUT to have the above additional functionality. The rest of the configuration is normal. Set the direction and interrupt capability. P1IES configures what edge or transition the chip will be looking for. Since P1.3 is held at Vcc and then connected to ground when the button is pressed we will get a falling edge. This is specified by P1IES.

	// Enable push button (P1.3)
	P1REN |= BIT3;		// Pull-up required for launchpad push button
	P1OUT |= BIT3;		// clear output pin 1.3
	P1DIR &=~ BIT3;		// P1.3 = input
	P1IES |= BIT3;		// interrupt on high to low transition
	P1IFG &=~ BIT3;		// clear inerrupt flag
	P1IE |= BIT3;		// Enable interrupt.

Next, we configure all of the IO of interest to digital outputs. This is pretty self explanitory.

	// Enable IO for LEDs on power fet booster pack
	P1OUT &=~ BIT5;	// 1.5
	P1DIR |= BIT5;
	P2OUT &=~ (BIT2 + BIT3 + BIT4);	// 2.2, 2.3, 2.4
	P2DIR |= (BIT2 + BIT3 + BIT4);

	// Enable launchpad leds
	P1OUT &=~ (BIT0 + BIT6);
	P1DIR |= (BIT0 + BIT6);

	// Enable J6 FET pins
	P2DIR |= BIT0;
	P2OUT &=~ BIT0;

	// Enable J5 FET pins
	P2DIR |= BIT5;
	P2OUT &=~ BIT5;

Last, configure TimerA. These concepts have been covered in other videos so I would recommend looking through the code and if that doesn't make sense check out my tech blog. These peripherals are explained in pretty good detail there.

	// Configure TimerA0
	/*	TimerA0 is setup to run at 125Khz by dividing the 1Mhz SMCLK down to
	 * 125kHz.
	TA0CTL |= TASSEL1;	// Sets TimerA0 to use SMCLK as Timer clock
	TA0CTL |= ID0 + ID1;	// Divide Timer clock by 8 to yield 125khz
	TA0CTL |= MC1;	// set timer to continuous mode.

	TA0CCTL0 |= CCIE;	// enable CCR0 interrupt
	TA0CCTL0 &=~ CCIFG;	// clear CCR0 interrupt flag
	TA0CCR0 = 5000;		// interrupt 25x / sec

The last section is the interrupt service routine. The only thing that happens here is the toggling of the IO set above. Other than that, don't forget to append the CCR0 count value since the Timer is running in continuous mode.

/* ***************************************************
* Timer0 CCR0
* ISR runs every 40mS
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer0_A0_ISR(void)

	P1OUT ^= BIT0;	// Launchpad LED 1
	P1OUT ^= BIT6;  // launchpad LED 2

	// D2 -> D5
	P1OUT ^= BIT5;	// D2
	P2OUT ^= (BIT2 + BIT3 + BIT4);	// 2.2, 2.3, 2.4

	// J5, J6
	P2OUT ^= BIT5;
	P2OUT ^= BIT0;

	TA0CCR0 += 5000;

Thats all the code for this post. Feel free to comment and or contact me with any questions.