From EdWiki
Jump to: navigation, search

Programming the GPIO in TM4C123

In this article we are going to write our first program for accessing GPIO of TM4C123GH6PM.

Accessing GPIO of this microcontroller includes much more steps as this microcontroller provides a lot of feature in a single board, hence requires lots of configuration.

For accessing and configuring the microcontroller pins, we have to load some values in the registers, associated with that particular pin.

1. Run Mode Clock Gating Control Register 2 (RCGC2)

The first step to initialize the pin is to enable the clock for that port. Microcontroller disables the clock for the port to save the power and resources. For enabling the clock we deal with RCGC2.
Tm4c rcgc2 r.png

This register is 32 bit wide because of 32 bit microcontroller. For enabling the clock we deal only with the last 8 bits. Since our micro controller provides only 6 ports we are going to deal with only 6 bits from last. So in this project we are going to use PORTF hence writing 1 at bit 5 will result to enable the clock for port F.

SYSCTL_RCGC2_R |= 0x00000020;             /* enable clock for PortF */

This step requires waiting for few clocks. There must be a delay of 3 system clocks after the GPIO module clock is enabled before any GPIO module registers are accessed.

2. LOCK register

After enabling the clock some ports are still locked. For unlocking them we would have to write this register with the magic number. I found this magic number which is 32 bit wide in the datasheet and it is 0x4C4F434B.
Tm4c gpiolock r.png

Now we have unlocked the PORT but we are not allowed to write any changes to that port. This introduces us to GPIO CR register.

3. GPIO COMMIT register (CR)

Enabling by writing 1 to the respective bit field of this register allows us to write the data to that port.

Tm4c gpiocr r.png

Here we are going to use PF4, PF3, PF2, PF1, and PF0 so writing the 0b000111111 or 0x1F to the CR register will allow us to change PF0-PF5 pins.

Here we have unlocked and got access to our desired port. Now let’s use it.

But wait, controller doesn’t know that which pin is going to be the input and output. So let the controller know which pin is going to be input and output by writing the direction register.


This register tells the microcontroller that which pin is going to be the input (by making the bit 0) and which is going to be output (by making the bit 1) to their respective field in the DIR register.

It's 8 bit wide. We are going to use PF0-PF5 so we will move 0b00001110 (0x0E) to the DIR register.

Tm4c gpiodir r.png

Notice that, we are going to use on board SW1 and SW2. Since they give input 1 when they are not pressed and 0 when they just got pressed. So this will require pull-up register at PF0 and PF4 to keep input line high (pulling up), when switches are not pressed. We can pull the lines high or low by writing 1 or 0 to the PUR register.


This microcontroller has in built pull-up register to use so we are going to use those pull-up register which are connected from switches at PF0 and PF4.

Tm4c gpiopur r.png

Instead of using pull-up we are also allowed for using pull-down register by writing 1 to the PDR register instead of PUR. In this case PF0 and PF4 are required to be 1. So the value which would be assigned in PUR is 0x11.

After setting all of required bits of different registers, we are able to read or write the bits of microcontroller by enabling those pins as digital IO. So we will switch them as digital IO by setting the value of DEN register.


Digital enable register is shown below Writing 0x1F in DEN will enable PF4 to PF0 as digital input output.

Tm4c gpioden r.png


The GPIODATA register is the data register. Values written in the GPIODATA register are transferred onto the GPIO port pins if the respective pins have been configured as outputs through the GPIO Direction (GPIODIR) register.

Tm4c gpiodata r.png
  • In order to write to GPIODATA, the corresponding bits in the mask, resulting from the address bus bits [9:2], must be set. Otherwise, the bit values remain unchanged by the write.
  • Similarly, the values read from this register are determined for each bit by the mask bit derived from the address used to access the data register, bits [9:2]. Bits that are set in the address mask cause the corresponding bits in GPIODATA to be read, and bits that are clear in the address mask cause the corresponding bits in GPIODATA to be read as 0, regardless of their value.
  • A read from GPIODATA returns the last bit value written if the respective pins are configured as outputs, or it returns the value on the corresponding input pin when these are configured as inputs.
  • All bits are cleared by a reset.
Tm4c gpiodata addrmask r.png
Tm4c gpiodata mask r.png
  • Writing to address 0x40004038 means that bits 1, 2 and 3 of Port A must be changed.
  • If we want to read and write all 8 bits of a port, it means that we need to sum all these 8 offset constants, which makes the offset address of 0x3FC (001111111100 in binary).

Switch and LED interfaces on the Tiva LaunchPad Evaluation Board

Tm4c led ckt.png

In our board, an RGB led and two user switches are already available. connections are as below in the table:

GPIO Pin Pin Function USB Device

Initialization of an I/O port

To initialize an I/O port for general use:

  1. Activate the clock for the port in the Run Mode Clock Gating Control Register 2 (RCGC2).
  2. Unlock the port (LOCK = 0x4C4F434B). This step is only needed for pins PC0-3, PD7 and PF0 on TM4C123GXL LaunchPad.
  3. Disable the analog function of the pin in the Analog Mode Select register (AMSEL), because we want to use the pin for digital I/O. If this pin is connected to the ADC or analog comparator, its corresponding bit in AMSEL must be set as 1. In our case, this pin is used as digital I/O, so its corresponding bit must be set as 0.
  4. Clear bits in the port control register (PCTL) to select regular digital function. Each GPIO pin needs four bits in its corresponding PCTL register. Not every pin can be configured to every alternative function.
  5. Set its direction register (DIR). A DIR bit of 0 means input, and 1 means output.
  6. Clear bits in the alternate Function Select register (AFSEL).
  7. Enable digital port in the Digital Enable register (DEN).
  • Please note that we need to add a short delay between activating the clock and setting the port registers.
  • PC0-PC3 is used for JTAG connections to the debugger on the LaunchPad. So we’d better do not use these pins normally.

Source Code

  1. #include <stdint.h>
  2. #include "inc/tm4c123gh6pm.h"
  4. /* It is always best practice to define some macros for the signals*/
  6. #define  SW1        (GPIO_PORTF_DATA_R&(1<<4))
  7. #define  SW2        (GPIO_PORTF_DATA_R&(1<<0))
  8. #define  LED_RED    (GPIO_PORTF_DATA_R=0x02)
  9. #define  LED_BLUE   (GPIO_PORTF_DATA_R=0x04)
  10. #define  LED_GREEN  (GPIO_PORTF_DATA_R=0x08)
  11. #define  LED_WHITE  (GPIO_PORTF_DATA_R=0x0E)
  12. #define  LED_DARK   (GPIO_PORTF_DATA_R=0x00)
  13. #define  LED_YELLOW (GPIO_PORTF_DATA_R=0x0A)
  14. #define  LED_SKYBLUE (GPIO_PORTF_DATA_R=0x0C)
  16. void Init_PortF(void);
  18. /* This function initializes the Switches and led connected to PortF */
  19. void Init_PortF(void)
  20. {
  21.     volatile unsigned long delay;
  23.     SYSCTL_RCGC2_R |= 0x00000020;     /* 1) activate clock for Port F */
  24.     delay = SYSCTL_RCGC2_R;           /* allow time for clock to start */
  26.     GPIO_PORTF_LOCK_R = 0x4C4F434B;   /* 2) unlock GPIO Port F */
  27.     GPIO_PORTF_CR_R = 0x1F;           /* allow changes to PF4-0 */
  28.     GPIO_PORTF_AMSEL_R = 0x00;        /* 3) disable analog on PF */
  29.     GPIO_PORTF_PCTL_R = 0x00000000;   /* 4) PCTL GPIO on PF4-0 */
  30.     GPIO_PORTF_DIR_R = 0x0E;          /* 5) PF4,PF0 in, PF3-1 out */
  31.     GPIO_PORTF_AFSEL_R = 0x00;        /* 6) disable alt funct on PF7-0 */
  32.     GPIO_PORTF_PUR_R = 0x11;          /* enable pull-up on PF0 and PF4 */
  33.     GPIO_PORTF_DEN_R = 0x1F;          /* 7) enable digital I/O on PF4-0 */
  34.  }
  37. int main()
  38. {
  39.     Init_PortF();                     /* Initializing port F */
  41.     while( 1 ) {
  42.         if( (!SW1) && (SW2) ) {       /* when switch 1 pressed */
  43.         LED_BLUE;                     /* Blue led */
  44.     } else if( (SW1) && (!SW2) ) {    /* when switch 2 pressed */
  45.         LED_GREEN;                    /* green led */
  46.     } else if( (!SW1) && (!SW2) ) {   /* when both switches pressed simultaneously */
  47.         LED_WHITE;                    /* white led */
  48.     } else
  49.         LED_RED;                      /* none of them pressed then red led */
  50.     }
  51. }

See Also

  1. How to Program GPIO of TM4C123GH6PM