TI ARM LaunchPad GPIO Input Tutorial

The TI Tiva Launchpad boards are an excellent way to get started working with ARM microcontrollers. With the Tivaware software suite, they’re not too much harder than an Arduino to program, either. I’ve found the tutorials from TI and elsewhere online to be very helpful. Unfortunately, the TI tutorials go over GPIO outputs, which are pretty simple, but they totally skip inputs! For someone totally unsure where to look for the correct documentation, I feel this is a major oversight. Fortunately, I’ve been able to figure it out with the help of some 3rd party tutorials. Here’s my take on how to use GPIO inputs, with references back to the TI material so you can get an idea of where to look for functionality in the main documentation.

 

I’ll explain the setup and put the code at the end of this post, along with some links.

 

Setup

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
int main(void)
{
  SysCtlClockSet(SYSCTL_SYSDIV_4|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);	// set up the clock
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);	// enable port F
  GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);	// enable outputs on the launchpad LED pins

 

As usual, we need to include the appropriate headers for the board and set up the clock. We also need to enable port F. Then, we set up GPIO F1, F2 and F3 as outputs. This is where the LaunchPad’s red, green and blue LEDs are connected. Also note that some pins need to be unlocked with a code from the datasheet before you can use them. That’s because they’re normally used for one of the programming interfaces. There are examples of this in the Tiva tutorials from TI. Take a look at my tutorial on how to unlock GPIOs.

 

GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_4);	// make F4 an input

GPIOPadConfigSet(GPIO_PORTF_BASE,GPIO_PIN_4,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU);	// enable F4's pullup, the drive strength won't affect the input

 

Here’s where we start getting to the input side of things. We need to enable port F4 as an input. Pretty simple, but it doesn’t end there. To make it work correctly, we’ll configure the pin to have an internal pullup resistor. WPU stands for ‘weak pullup resistor’ – you could change this to WPD for a pulldown. The details of this function can be found on page 264 here.

 

By giving the pin an internal pullup, we know that when the button is pressed, the input will be grounded (from the LaunchPad datasheet). Otherwise, it’ll be pulled up to 3.3v. That’s the key to making inputs work, but let’s peek at the rest of the code.

 

Loop

 

while(1)
  {
    uint32_t pinVal=0;	// variable to hold the pinRead
    pinVal= GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4);	// read F4

 

Pretty standard microcontroller stuff, we’ve got a while(1) loop. This will run indefinitely. Next, we create a 32-bit integer to take the value of GPIOPinRead. This function returns a 32 bit value, but we only need bits 1-8, which will be set if any of the pins on the bus is high. GPIOPinRead takes the base port and the specific pin as arguments.

 

If

 

if( (pinVal & GPIO_PIN_4)==0){	// AND to strip out anything but the value read from F4
      GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 2);	// turn on one LED
    }
    
    else{
      GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 4);	// turn on a different LED
    }

 

Next we have an if statement. It’s pretty easy to see what’s being done here. If the pin is high, we turn on GPIO F2 (that’s the else condition). Otherwise, our input is low (button pressed) and we’ll turn on pin F1.

 

There’s a little bit going on in the if statement though. We’re taking the value from GPIOPinRead, which will have a 0 or a 1 in the position of any pins we read. We logical AND it with the GPIO_PIN_4 variable, which will strip away anything except the value in Pin 4’s position. If pin 4 was high, we will get a result of 1. If pin 4 was low, we get a 0. This is because we AND the value on the input, in the input’s place, with a 1 in the input’s place.

 

What’s the delay for?

 

//   SysCtlDelay(7000000); // uncomment me if you need debouncing

  }
}

 

There is an optional delay at the bottom of the code. This is for very simple debouncing of the button. Essentially, when you push a button, it doesn’t immediately connect one way or the other. It’ll actually bounce around between connected and disconnected. This is a physical phenomenon due to springiness. It’s very fast, but not too fast for a micro to keep up with. In some applications, like if you were making each button press increment a counter, you would likely see more than one increment of the counter for each button press, due to the button bouncing a little bit. If you’re just using a button to turn on an LED with no latching, button bounce isn’t something to worry about.

 

Button bounce

 

By waiting around for a few ms after reading the button, we physically give it time to settle into wherever it wants to be. Debouncing could be a whole series of blog posts, as you can deal with it in multiple ways through hardware or software. If you find you need it, delays are the most simple way to deal with it, though they’re probably not the best.

 

Complete code

Here’s the complete code for this tutorial. It’s all commented and should be easy to figure out. The project containing this code was actually the Lab 2 code from TI’s set of tutorials. The includes and build options are the same, you just need to put in a few lines to enable and work with the inputs.

 

/* Richard Arthurs 2015
Tivaware input tutorial
Free to use for any purpose (following Tivaware license)
TI ARM LaunchPad GPIO Input Tutorial
*/ #include <stdint.h> #include <stdbool.h> #include "inc/hw_types.h" #include "inc/hw_memmap.h" #include "driverlib/sysctl.h" #include "driverlib/gpio.h" int main(void) { SysCtlClockSet(SYSCTL_SYSDIV_4|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN); // set up the clock SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); // enable port F GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3); // enable outputs on the launchpad LED pins GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_4); // make F4 an input GPIOPadConfigSet(GPIO_PORTF_BASE,GPIO_PIN_4,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU); // enable F4's pullup, the drive strength won't affect the input while(1) { uint32_t pinVal=0; // variable to hold the pinRead pinVal= GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4); // read F4 if( (pinVal & GPIO_PIN_4)==0){ // AND to strip out anything but the value read from F4 GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 2); // turn on one LED } else{ GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 4); // turn on a different LED } // SysCtlDelay(7000000); // uncomment me if you need debouncing } }

Resources

I’ll end off with some resources for learning about the ARM LaunchPad. There will definitely be more tutorials from me as well!

TI LaunchPad resources

Tivaware Reference

TI LaunchPad Workshop

AllaboutEE Input Tutorial (C++)

Luis Electronic Projects Input Tutorial

10 thoughts on “TI ARM LaunchPad GPIO Input Tutorial

  1. Hi,
    Nice tutorial.

    In this tutorials, you have mentioned GPIO F1, F2 and F3 as outputs and F4 as input.
    I didn’t get it which pin is F1, F2, F3 and F4. You mean its PF1…. or pin number #1 of Tiva board.
    Could you please clarify a bit
    Thank you

    1. Hi Dinesh,
      Sorry for the delay. Yes, PF1 is the same as F1. The ‘P’ is just short for ‘Port’ and ‘F’ is the label for the specific port (there are ports A through F, with 8 pins each).

  2. Hi Nice tutorial

    I’m new to tiva or ti micro’s in general. I was wondering how you would read all of the pins of a port say port F in one go is it possible?
    Thanks

    1. Hi Chase, you should be able to set a variable to equal the PORTA macro. It has been a while since I’ve played with the tiva, so I can’t quite remember.

  3. Hi I am new to tiva, when I compiled I got the following error

    sudha@VCHN172:~/tmc4123/Embedded/led-project$ make
    arm-none-eabi-gcc -o build/main.o src/main.c -g -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -Os -ffunction-sections -fdata-sections -MD -std=c99 -Wall -pedantic -DPART_TM4C123GH6PM -c -I/home/sudha/tmc4123/Embedded/tivaware -DTARGET_IS_BLIZZARD_RA1
    arm-none-eabi-ld -o build/a.out build/main.o build/startup_gcc.o -T TM4C123GH6PM.ld –entry ResetISR –gc-sections
    build/main.o: In function `main’:
    /home/sudha/tmc4123/Embedded/led-project/src/main.c:29: undefined reference to `GPIOPinRead’
    /home/sudha/tmc4123/Embedded/led-project/src/main.c:32: undefined reference to `GPIOPinWrite’
    Makefile:57: recipe for target ‘build/a.out’ failed
    make: *** [build/a.out] Error 1

    Here is my code
    1 #include
    2 #include
    3
    4 #include “inc/hw_types.h”
    5 #include “inc/hw_gpio.h”
    6 #include “inc/hw_memmap.h”
    7 #include “inc/hw_sysctl.h”
    8 #include “driverlib/gpio.h”
    9 #include “driverlib/rom.h”
    10 #include “driverlib/sysctl.h”
    11 #include “driverlib/pin_map.h”
    12 #include “driverlib/can.h”
    13
    14 #define LED_RED GPIO_PIN_1
    15 #define LED_BLUE GPIO_PIN_2
    16 #define LED_GREEN GPIO_PIN_3
    17 #define SW2 GPIO_PIN_0
    18 #define SW1 GPIO_PIN_4
    19
    20 int main()
    21 {
    22 ROM_SysCtlClockSet(SYSCTL_SYSDIV_4|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
    23 ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    24 ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, LED_RED|LED_BLUE|LED_GREEN);
    25 ROM_GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, SW2);
    26
    27 for (;;) {
    28 // set the red LED pin high, others low
    29 if (GPIOPinRead(GPIO_PORTF_BASE,SW2)) {
    30 ROM_GPIOPinWrite(GPIO_PORTF_BASE, LED_GREEN, LED_GREEN);
    31 } else {
    32 GPIOPinWrite(GPIO_PORTF_BASE, LED_GREEN, 0);
    33 }
    34 }
    35 }
    36

    Please help me in solving this issue

    1. Sorry for the delayed reply,

      You’re getting errors for GPIOPinWrite, meaning either you spelled the function name wrong, or your includes are not correct. Perhaps CCS isn’t correctly pointed towards the driver lib library. Alternatively, you could use the ROM version instead, as that lives permanently on the chip and doesn’t seem to be giving you errors.

  4. I am using tms320f28335, i want to tun on SSR switch by GPIO pin of board, switching frquency is 10kHz. When the program runs after 30 seconds , I want to turn the GPIO pin which with turn on SSR. How can i write code to set up GPIO which turns on after 30 seconds, thanks

    1. You could use a timer to count the initial 30 seconds, and when the timer expires, enable 10 KHz PWM on a pin. Unfortunately, I can’t help any further as I haven’t used the TMS320 devices at all. The TI forums should be helpful to you, the engineers there are very responsive.

  5. hello can i get the source code r some help to turn on and off led using switch (EK-TM4C1294XL)launch pad im new to TI nt able to understand hw it should be defined

    1. Hi Chethan, you can look at my output tutorial to find the functions that you need for an output (the pin connected to your LED). Combining that code with this tutorial should get you most of the way there. If this isn’t enough information, I suggest getting familiar with an Arduino tutorial that covers what you want to do, and then adapt that use the TivaWare functions instead of arduino ones like digitalWrite.

      Output tutorial: http://richarthurs.com/2015/05/25/ti-arm-gpio-outputs-tutorial/

Leave a Reply to Chase Cancel reply

Your email address will not be published. Required fields are marked *