# Accessing individual I/O pin on MSP430

Im porting some software from Microchip PIC (using the HI-Tech C Compiler) to TI MSP430, and in the existing code they access the pins directly with something like:

RA1 = 1;


Is there a similar way to do this with the MSP430? Or do I have to write to the entire input/output register each time? If it is not possible has any one came up with a good equivalent? I am using Code Composer Studio v5.3 and the compiler that comes with that.

• TI's MSPWare has got helper functions for controlling the GPIO (although not for all MSP430 sub-families). – Nick Alexeev Sep 21 '15 at 0:21
• [moderator note: This comment have arrive to this thread as a result of a merge.] What's wrong with chapter 8 of the family manual?? Perhaps you should provide an example question of one very specific "manipulation" you'd like to understand how to do. That might go a long way in avoiding forcing us to write and reproduce an entire chapter for you. – jonk Oct 5 '16 at 3:16

In the MSP430, accessing individual pins is commonly written using defines and bitwise operators:

P2OUT &= ~BIT1;    /* Pin P2.1 = 0 */
P2OUT |= BIT1;     /* Pin P2.1 = 1 */
P2OUT ^= BIT1;     /* Toggle Pin P2.1 */


Be sure to include the proper header file for your specific chip that contains the port and pin (BIT#) defines.

• Ok, it looks like for each time I see something like RA1 = 1; Im going to have to set the output register each time. – Dean Jan 31 '13 at 13:40
• @Dean Pretty much. The defines just make it easier to read. I occasionally see code online using P2OUT.BIT1 = 1; but I don't know if that works or not. In my experience with the MSP430, I've always used bitwise operations to access individual pins. It seems the more common way of doing things. – embedded.kyle Jan 31 '13 at 13:44
• If you're using CCS, it should be enough to include msp430.h; the compiler will automatically detect which micro you're on. – Renan Jan 31 '13 at 16:42

TI Discussion board had a very informative discussion about the same thing.

In short, this is defined by the generic msp430.h header used in CCS (which is linked to the specific target chip msp430xxxx.h on compile). It does not have support for PxOUT.BITy style assignments.

IAR's io430.h does have support for that, but the consensus is that msp430.h is the better header (as the msp430xxxx.h headers are written by TI employees, io430.h is written by IAR employees)

PxOUT |= BITy style is the best way to set a single bit. PxOUT &= ~BITy style is the best way to clear a single bit.

• Nitpick: PxOUT &= ~BITy clears a bit. PxOUT |= BITy sets a bit. – Turbo J Jan 31 '13 at 18:41

TI themselves does it like this in one of their examples for the Code Composer Studio (CCS) and IAR compilers:

void main(void)
{
WDTCTL = WDTPW + WDTHOLD;             // Stop watchdog timer
P1DIR |= 0x01;                        // Set P1.0 to output direction

for (;;)
{
volatile unsigned int i;

P1OUT ^= 0x01;                      // Toggle P1.0 using exclusive-OR

i = 50000;                          // Delay
do (i--);
while (i != 0);
}
}


The following code is a workaround for individual pin access using Code Composer (with a little tweak can be ported on any compiler). The example is a modified version of the Code Composer Basic Example Blink the LED. In this example instead of writing the usual statement LED=1 to turn on the LED you will write LED(HI).

//***************************************************************************
//
// MSP432 main.c template - P1.0 port toggle
//
//***************************************************************************

#include "msp.h"

#define LO             0x00
#define HI             0x01

#define BIT_0           0x01
#define BIT_1           0x02
#define BIT_2           0x04
#define BIT_3           0x08
#define BIT_4           0x10
#define BIT_5           0x20
#define BIT_6           0x40
#define BIT_7           0x80

#define LED_BIT          BIT_0

#define LED_PORT         P1OUT

#define LED(x) (x==HI)?(LED_PORT |= LED_BIT):(LED_PORT &= ~LED_BIT)

void main(void)
{
volatile uint32_t i;

WDTCTL = WDTPW | WDTHOLD;           // Stop watchdog timer

// The following code toggles P1.0 port
P1DIR |= BIT0;                      // Configure P1.0 as output

while(1)
{

LED(HI);
_delay_cycles(100000);
LED(LO);
_delay_cycles(100000);
}
}


[moderator note: This comment have arrive to this thread as a result of a merge.]

[author note: the original question where I posted this answer stated that no code example could be found]

Erm okay, it took me around 30 seconds to find this:

TI website for MSP430F2274

Tools and Software for MSP430F2274

Example code for MSP430F22x4

And finally there is a folder called C and in that you find some files called msp430x22x4_p1_0x.c which contain code examples on how to use the Port 1 in C. There is even a readme to tell you which file is used for what.

And to make this answer not completely useless:

#include <msp430.h>

int main(void)
{
WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
P1DIR |= BIT0;                            // Set P1.0 to output direction

while (1)
{
if ((BIT2 & P1IN) == BIT2)
{
P1OUT |= BIT0;                        // if P1.2 set, set P1.0
}
else
{
P1OUT &= ~(BIT0);                       // else reset
}
}
}


(Heavily based on msp430x22x4_p1_01.c by A. Dannenberg / W. Goh, the complete copyright statement is too big for this answer, but is contained in the linked Code Example file)

• To be complete (as an example) I think you need to also quote the macros (where the memory map 'magic' comes into play), so some fragments of the header file. Not sure if its worth the effort through... – Sean Houlihane Oct 5 '16 at 9:16
• @SeanHoulihane well yeah I could *(uint16_t*)(0x1234U) = 0x20U but nah the compiler will have the header files, so the code should be something like this. – Arsenal Oct 5 '16 at 11:48

The MSP430 can set or clear individual bits via the BIS or BIC (BIt Set) instructions.

So I would certainly expect P2OUT.BIT1 = 1; to work in C (at least in mspgcc; the equivalent Ada code does)

procedure Blinky is
LED : Boolean renames p1out_bits(0);
begin
-- Initialise registers etc simplified out
loop
LED := True;
Delay_MS(200);
LED := False;
Delay_MS(800);
end loop;