MSP432 LaunchPad pushbutton initialization

1.2k views Asked by At

I am struggling to initialize the LEDs and pushbuttons on my MSP432p401R LaunchPad.

The problem:

Write a code that reads input of the two pushbuttons S1 & S2 (P1.1 & P1.4) and changes the state of the LED correspondingly: none - off S1 - RED S2 - GREEN both - BLUE

here's some code:

#define RED         BIT0        // Red LED connected to Port 1.0
#define GREEN       BIT1
#define BLUE        BIT2
#define S1          BIT1
#define S2          BIT4
#define SBOTH       (BIT1 | BIT4)
#define PB1_PRESSED()   ((P1->IN & S1) == 0)
#define PB2_PRESSED()   ((P1->IN & S2) == 0)
#define BOTH_PRESSED()  ((P1->IN & SBOTH) == 0)



P2->OUT |= OFF;     // turn off LEDs   
P2->DIR |= (RED | GREEN | BLUE);     // set LEDs for output
P2->REN |= (RED | GREEN | BLUE);   // turn on resistors

My if statements look like this:

if (BOTH_PRESSED())
        {
            P2->REN |= BLUE;
            P2->OUT |= BLUE;
        }

what am I doing wrong in the initialization?

2

There are 2 answers

0
TheMulittle On

I´m looking through documentation and will point some details that you might be missing. Could you provide what is the current behavior of the LED? Is only one color being activated (red, green, blue) lightened, no color is activated or a mixture between the RGB components is activated?

1. You need to enable pull up resistors for both P1.1 and P1.4

Going to schematics of the launchpad and looking for the button connections to the microcontroller we can see in Figure 29 Schematics (2 of 6) that the buttons connected to P1.1 and P1.4 are both grounded:

Therefore you should enable the pull up resistor at both I/Os as per Table 12.1 of MSP432P4xx SimpleLink™ Microcontrollers Technical Reference Manual section 12.2.4:

The consequence of this topology wherein the push button is grounded and there is a pull up resistor is negative logic: If the button is pressed, the input is being grounded, thus the MCU reads a 0; If the button is not pressed, the input is getting signal from VCC via pull resistor, thus the MCU reads a 1; In summary: pressed button = 0, open button = 1.

2. You don´t need to enable resistors for the LED outputs

Going back to schematics of the launchpad at Figure 29, in there we can see that the LEDs connect to P2.0, P2.1 and P2.2 already have a resistor in the anodes and I don´t see the need of having pull up or pull down resistors. You should be just fine without the resistors:

3. You might need to enable the high drive strength at output ports

Since the LEDs are arranged in a common cathode manner, the MSP432 I/O pins will need to drive the current for lightening it (as opposed of what would happen in a common anode configuration). Therefore, you will need to activate the high strength driver for pins P2.0, P2.1 and P2.2. Going again back to MSP432P4xx SimpleLink™ Microcontrollers Technical Reference Manual at section 12.2.5 Output Drive Strength Selection Registers (PxDS), we can see that we need to set BIT0, BIT1 and BIT2 in the P2DS register in order to allow them to use the high strength IO driver

0
Brighton Sikarskie On

TheMulittle made a good post explaining a lot. I will give 3 code examples of how to use the buttons

Turn on LED when button is pressed


// This program will turn off a red LED when a button is pressed

#include "msp.h"
#include <stdint.h>

int main(void) {
  // configure P1.0 and P1.1 as GPIO
  P1->SEL0 &= ~0x03;
  P1->SEL1 &= ~0x03;

  // set P1.0 as output and P1.1 as input
  P1->DIR |= 0x1;  // set P1.0 as output
  P1->DIR &= ~0x2; // set P1.1 as input

  // enable pull-up/pull-down resistors for P1.1
  P1->REN |= 0x2;

  // enable pull-up resistor for P1.1
  P1->OUT |= 0x2;

  while (1) {
    // check if the button connected to P1.1 is pressed
    if ((P1->IN & 0x2) == 0x2) {
      // if the button is not pressed, turn on the red LED connected to P1.0
      P1->OUT |= 0x1;
    } else {
      // if the button is pressed, turn off the red LED connected to P1.0
      P1->OUT &= ~0x1;
    }
  }
}

Turn off a LED when button is pressed

// This program will turn off a red LED when a button is pressed

#include "msp.h"
#include <stdint.h>

int main(void) {
  // configure P1.0 and P1.1 as GPIO
  P1->SEL0 &= ~(BIT0 | BIT1);
  P1->SEL1 &= ~(BIT0 | BIT1);

  // set P1.0 as output and P1.1 as input
  P1->DIR |= BIT0;  // set P1.0 as output
  P1->DIR &= ~BIT1; // set P1.1 as input

  // enable pull-up/pull-down resistors for P1.1
  P1->REN |= BIT1;

  // enable pull-up resistor for P1.1
  P1->OUT |= BIT1;

  while (1) {
    // check if the button connected to P1.1 is pressed
    if ((P1->IN & BIT1) == BIT1) {
      // if the button is not pressed, turn on the red LED connected to P1.0
      P1->OUT |= BIT0;
    } else {
      // if the button is pressed, turn off the red LED connected to P1.0
      P1->OUT &= ~BIT0;
    }
  }
}

Detect Button Presses (also a cool uart function)

void uart_init(void) {
  EUSCI_A0->CTLW0 |= 0X1;
  EUSCI_A0->MCTLW  = 0X0;
  EUSCI_A0->CTLW0 |= 0x80;
  EUSCI_A0->BRW    = 0x34;
  EUSCI_A0->CTLW0 &= ~0x01;
  P1->SEL0        |= 0x0C;
  P1->SEL1        &= ~0x0C;
}

void uart_send_str(const char *str) {
  uint32_t i = 0;
  while (str[i] != '\0') {
    EUSCI_A0->TXBUF = str[i];
    while ((EUSCI_A0->IFG & 0x02) == 0) {}
    i++;
  }
}

// Use the other code examples with this function:
void digital_input(void) {
  bool button1 = (P1->IN & BIT1) == 0;
  bool button2 = (P1->IN & BIT4) == 0;
  if (button1 && button2) {
    uart_send_str("Buttons 1 and 2 are pressed\r\n");
  } else if (button1) {
    uart_send_str("Buttons 1 is pressed\r\n");
  } else if (button2) {
    uart_send_str("Button 2 is pressed\r\n");
  } else {
    uart_send_str("No Buttons are pressed\r\n");
  }
}