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.

4. GPIO DATA DIRECTION REGISTOR (DIR)

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.

5. PULL UP REGISTER (PUR)

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.

6. DIGITAL ENABLE REGISTER (DEN)

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

Tm4c gpioden r.png

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
PF4 GPIO SW1
PF0 GPIO SW2
PF1 GPIO RGB LED (RED)
PF2 GPIO RGB LED (BLUE)
PF3 GPIO RGB LED (GREEN)

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"
  3.  
  4. /* It is always best practice to define some macros for the signals*/
  5.  
  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)
  15.  
  16. void Init_PortF(void);
  17.  
  18. /* This function initializes the Switches and led connected to PortF */
  19. void Init_PortF(void)
  20. {
  21.     volatile unsigned long delay;
  22.  
  23.     SYSCTL_RCGC2_R |= 0x00000020;     /* 1) activate clock for Port F */
  24.     delay = SYSCTL_RCGC2_R;           /* allow time for clock to start */
  25.  
  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.  }
  35.  
  36.  
  37. int main()
  38. {
  39.     Init_PortF();                     /* Initializing port F */
  40.  
  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