I’ve been using msp430 in many prototypes in which connection through different versions may differ. For example, in version 0.1 a LED could be connected to port 1 bit 0, but in the next version (version 0.2), the LED connection could change to a different bit or even a different port, e.g. Port 3 bit 7. It implies that I have to change registers from Port 1 to registers from Port3, and replace uses of bit 0 with bit 7.

A nice post explaining the use of I/O ports on MSP430 could be found here, but for resuming, there are basically 4 registers we have to use to handle a LED.

PxDIR: Configure the pin as output (1) or input(0)
PxOUT: Set output value, if the pin is configured as output. If input, selects pull-up or pull-down resistor
PxIN: Get the values of the pins.

Now, we have to configure the pin as output using PxDIR and set the desired value using PxOUT. There are three types of coding this: Using fixed registers, using conditional registers, or using conditional port. For these examples, we will use a led on port 1, bit 0, and toggle it every 20000 cycles.

Fixed registers: In this code register names are hard-coded, so any change on port or bit, implies to change all usages of those. (4 changes for this file)

#include "msp430.h"

void main(){
  WDTCTL = WDTPW | WDTHOLD;
  P1DIR |= BIT0; /* Modify here to change port/bit assignment */

  while(1){
    P1OUT ^= BIT0;  /* Modify here to change port/bit assignment */
    __delay_cycles(20000);
  }
}

Conditional registers: In this code, register names are used in preprocessor definitions, one for each register to use and another one for the bit. Note that if we decide to change pin assignment for the LED, we should make these changes in each #define directive, but not in the main function. (3 changes)

#include "msp430.h"

#define LED_PDIR  P1DIR  /* Modify here to change port/bit assignment */
#define LED_POUT  P1OUT  /* Modify here to change port/bit assignment */
#define LED_BIT   BIT0   /* Modify here to change port/bit assignment */

void main(){
  WDTCTL = WDTPW | WDTHOLD;
  LED_PDIR |= LED_BIT;

  while(1){
    LED_POUT ^= LED_BIT;
    __delay_cycles(20000);
  }
}

Conditional port: Here, some preprocessor techniques are used to generate registers names just by passing port number. There is a special case for generating PxOUT because OUT is already defined in the msp430 header file. In this example, just 2 changes are needed for assign different port and pin to the LED.

#include "msp430.h"
#define LED_PORT      P1    /* Modify here to change port/bit assignment */
#define LED_BIT       BIT0  /* Modify here to change port/bit assignment */
#define _concat(x,y)  x##y
#define concat(x,y)   _concat(x,y)
#define concat_out(x) _concat(x,OUT)
#define LED_POUT      concat_out(LED_PORT)
#define LED_PDIR      concat(LED_PORT,DIR)

void main(){
  WDTCTL = WDTPW | WDTHOLD;
  LED_PDIR |= LED_BIT;

  while(1){
    LED_POUT ^= LED_BIT;
    __delay_cycles(20000);
  }
}

Note that in case that PxIN, PxREN, PxSEL, PxIFG, PxIV etc are needed/used, the third approach could be easily replicated for those.

 

 

Advertisements