Simple Digital Input

In this tutorial i will explain how to read a digital input. The digital input will be controlled by a button. The idea is to toggle a LED when you press the button. The button is going to be the one in the launchpad, SW1 the one in the left, which is connected to PF4.

I assume that the person reading this as alredy read Blinky with TivaWare and Understanding the TIVA GPIO.

This example was made using IAR Workbech free version with 32Kb code limit.

Let's get started shall we?

The first step as always is set the system clock, in here to 80Mhz.

SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);

Now enable the clock on the GPIO peripheral.

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

Setting it to input:

GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_4);

Remember in blinky how it was to setup the pin to output? Now it's similar but istead of GPIOPinTypeGPIOOutput, it's GPIOPinTypeGPIOInput

Since the button needs some sort of pull-up let's use the MCU internal pull ups:

GPIOPadConfigSet(GPIO_PORTF_BASE,GPIO_PIN_4,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU);

The 3rd parameter doesn't matter if it's an input, what matters is the 4th. That sets it so the pin has a weak pull-up. GPIO_PIN_TYPE_STD_WPD would set it to a weak pull-down. For more information you can check 15.2.3.16 on the Peripheral Driver Library Guide.

Now that the input configuration is all done. But first we also need to configure PF1 to output so we can control the LED. Since we alredy enabled the system clock to the GPIOF we don't need to do it again. Simply configure the pin as a output:

GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1);

To read a input:

GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4);

It's pretty straight forward how to use this function. Just the GPIO base and the pin you want to read from. It returns a 32bit value. This is due to being able to read all the 8 pins at the same time if you want. Bits 31-8 from the return packet should be ignored. If GPIO_PIN_4 is high then the return value would be equal to GPIO_PIN_4 (GPIO_PIN_4 is actualy a value defined in the included files with the value 0x00000010). Example: If the PF4 input is 1 then, (value & GPIO_PIN_4) = GPIO_PIN_4. If the input is 0 then equal 0.

Now to toggle the LED with the button:

uint32_t value=0; uint8_t state=0; while(1){ value= GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4); if( (value & GPIO_PIN_4)==0) state^=GPIO_PIN_1; GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1, state); SysCtlDelay(7000000); }

A variable is created to store the return value of GPIOPinRead and then checked if it's 0 or not.The button when pressed, connected the pin to the GND so it gives 0. We use a variable "state" because in GPIOPinWrite we need to use GPIO_PIN_1 to set the pin HIGH. So we XOR the state with GPIO_PIN_1 so it toggles the "state" every time the button is pressed.

The SysCtlDelay of about 0.25s is a rude way to avoid bouncing. The button being mechanical doesn't give a perfect 1 and 0 signal, instead, to the "eyes" of the digital pin, it bounces between 1 and 0 when you press it before stabilizing

I hope you liked this tutorial in basic inputs

And here is the code with defines to help change the pins.

/* This code was made using TivaWare 2.1.0.12573. TivaWare rights to it are all own byTexas Instruments This code shows how to toggle the RED LED (PF1) of the TM4C123 Launchpadwith the left button at PF4, using Tivaware. Luís Afonso*/#include <stdint.h>#include <stdbool.h>#include "inc/hw_types.h"#include "inc/hw_gpio.h"#include "driverlib/pin_map.h"#include "driverlib/sysctl.c"#include "driverlib/sysctl.h"#include "driverlib/gpio.c"#include "driverlib/gpio.h"/* These defines help if you want to change the LED pin or the Button pin. Remember if you change to a diferent GPIO you need to enable the system clock on it*/#define LED_PERIPH SYSCTL_PERIPH_GPIOF#define LED_BASE GPIO_PORTF_BASE#define RED_LED GPIO_PIN_1#define Button_PERIPH SYSCTL_PERIPH_GPIOF#define ButtonBase GPIO_PORTF_BASE#define Button GPIO_PIN_4int main(void){ //Set the clock to 80Mhz SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ); /* No need to enable the button peripheral since it's the same as the LED in this case */ SysCtlPeripheralEnable(LED_PERIPH); SysCtlDelay(3); /* Configure the switch on the left of the launchpad, GPIO_PIN_4 to a input with internal pull-up. */ GPIOPinTypeGPIOInput(ButtonBase, Button); GPIOPadConfigSet(ButtonBase ,Button,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU); /* Configures the Red LED, GPIO_PIN_1, to output */ GPIOPinTypeGPIOOutput(LED_BASE, RED_LED); /* A variable is created to store the return value of GPIOPinRead and then checked if it's 0 or not.The button when pressed, connected the pin to the GND so it gives 0. We use a variable "state" because in GPIOPinWrite we need to use GPIO_PIN_1 to set the pin HIGH. So we XOR the state with GPIO_PIN_1 so it toggles the "state" every time the button is pressed. The SysCtlDelay of about 0.25s is a rude way to avoid bouncing. The button being mechanical doesn't give a perfect 1 and 0 signal, instead, to the "eyes" of the digital pin, it bounces between 1 and 0 when you press it before stabilizing*/ uint32_t value=0; uint8_t state=0; while(1){ value= GPIOPinRead(ButtonBase,Button); if( (value & GPIO_PIN_4)==0) state^=RED_LED; GPIOPinWrite(LED_BASE,RED_LED, state); SysCtlDelay(7000000); } }