Configuring GPIO Pins in TM4C123GH6PM( TIVA C-Series Launch Pad)
In the previous project we have learnt how to use code composer studio to build our project for TM4C123G series microcontrollers. Today we are going to see how to configure GPIO peripherals of this micro controller to use the pins as input and output. We will be using the on board RGB LEDS which are connected to PORTF pin1, pin2 & pin3 as outputs and SW1 & SW2 which are connected to PORTF pin0 and pin4 as inputs in TIVA C-Series Launch Pad.
Create a new project in Code Composer Studio and open the "main.c" file in the project. The first step of any microcontroller programming is to configure and set the clock source for the CPU and for all the onboard peripherals. First we will be configuring the system clock as follows;
#include "driverlib/sysctl.h"
After enabling clock and setiing the the values of LOCK and Commit registers, now we can configure the GPIO pins as Inputs and outputs using GPIOPinTyptGPIOOutput() & GPIOPinTyptGPIOInput() functions as follows :
By default all the pins are set in PUSH - PULL modewith out any pull up or pull down. But for pins which are set in input mode must be configured either in PullUp or PullDown mode. This is done as shown below :
The different pad configurations available are mentioned in the device technical reference guide. Now that we set the pin configurations correctly, it's time to read and write data to the pins.
Setting a Bit : GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, GPIO_PIN_3);
#include "inc/hw_gpio.h"
By combining all the above steps we finalise our program which consatantly blinks the GREEn LED and if SW1 is pressed RED LED glows and if SW2 is pressed BLUE LED glows. Here for the switches we will be implementing -ve logic as the other side of switches are connected to ground. When switch is pressed the pin will be directly connected to ground. That is the reason why the pull is enabled on input pins. 0 - True & 1 - False.
if((GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_4) & GPIO_PIN_4) == 0)
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_PIN_1);
else if((GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_0) & GPIO_PIN_0) == 0)
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);
else{
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0);
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);
}
Create a new project in Code Composer Studio and open the "main.c" file in the project. The first step of any microcontroller programming is to configure and set the clock source for the CPU and for all the onboard peripherals. First we will be configuring the system clock as follows;
SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN)
In order for this API to work we have to add the following header files in the program:
#include "inc/hw_memmap.h"
#include "driverlib/pin_map.h"#include "driverlib/sysctl.h"
The above function enables the PLL and sets the system clock divison value as 2.5. The launch pad has externel crystal of 16MHz on board. We select this crystal as oscillator source for the PLL. The output from PLL is by default 200MHz. Now we will divide 200MHz clock output with 2.5 to get desired clock out put of 80MHz wich is the maximum clock frequency. We should also tell the peripherial which is the main oscillator source and what is the frequency of main oscillator. The microcontroller can choose main oscillator from 4-different sources. Some of them are External crystal oscillator, Internal calibrated RC Oscillator(16MHz), Internal oscillator divided by 4. SYSCTL_OSC_MAIN is the macro which tells that the oscillator source is the main oscillator and SYSCTL_XTAL_16MHZ is the macro which tells the frequency of the selected oscillator source. After calling this fuction the system clock is set to operate at 80MHz frequency.
Now that we have set the clock configuration, we need to enable the gating pulses to the GPIO peripheral. This is done as folows:
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); //Enable the Clock for GPIOF
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF)){} //Wait until the GPIOF peripheral is ready
The SysCtrlPeripheralEnable() function enables the clock for the given peripheral base (in this case GPIOF) and the second statement waits for the peripheral to stabilise or settle.
NOTE : For the GPIO pins which have special and non-maskable alternate functions like Non-Maskable Interrupt(NMI), those pins can not be read, written or re-configured by using above two statements. in order to use such pins we have to write the LOCK value to GPIO->LOCK register and enable the bits whose corresponding pins are to be configured in GPIO->CR register.
As mentioned above, we have some non-maskable special functions on GPIOF. so we will be reconfiguring the port to use the pins PIN0, PIN1, PIN2, PIN3 & PIN4 as GPIO's. We donot have any API's to directly modify the LOCK and COMMIt registers directly as mentioned in the documentation but this can be done as follows :
HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = 0x4C4F434B;
HWREG(GPIO_PORTF_BASE + GPIO_O_CR) = (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4);
In order for the above fuctions to work, we have to include the following header files :
#include "inc/hw_types.h"
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, (GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3));
GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, (GPIO_PIN_0 | GPIO_PIN_4));By default all the pins are set in PUSH - PULL modewith out any pull up or pull down. But for pins which are set in input mode must be configured either in PullUp or PullDown mode. This is done as shown below :
GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_0, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_4, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);The different pad configurations available are mentioned in the device technical reference guide. Now that we set the pin configurations correctly, it's time to read and write data to the pins.
Setting a Bit : GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, GPIO_PIN_3);
Clearing a bit : GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, 0);
Reading a bit : GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_4);
For the GPIO API's to compile successfully with out any errors include the following header files :
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"By combining all the above steps we finalise our program which consatantly blinks the GREEn LED and if SW1 is pressed RED LED glows and if SW2 is pressed BLUE LED glows. Here for the switches we will be implementing -ve logic as the other side of switches are connected to ground. When switch is pressed the pin will be directly connected to ground. That is the reason why the pull is enabled on input pins. 0 - True & 1 - False.
/**
* main.c
*/
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_gpio.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
void _delay_ms(unsigned int ms){
int i, j;
for(i = 0; i < ms; i++)
for(j = 0; j < 78000;j++);
}
int main(void)
{
// Configure the device to run at 80 MHz from the PLL using a 16 MHz crystal as the input.
SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF)){} //Enable peripheral Clock for GPIOF
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, (GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3)); //Set GPIOF Pins 1 - 3 as output
GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, (GPIO_PIN_0 | GPIO_PIN_4)); //Set GPIOF Pins 0 & 4 as input
GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_0, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_4, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
while(1){
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, GPIO_PIN_3);
_delay_ms(200);
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, 0);
_delay_ms(200);if((GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_4) & GPIO_PIN_4) == 0)
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_PIN_1);
else if((GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_0) & GPIO_PIN_0) == 0)
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);
else{
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0);
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);
}
}
}
Build and debug the program on the board using Code Composer Studio and feel free to ask me if you have any problems.
This is a basic example of using GPIO peripheral and the whole process of reading input from pin is done in polling method. In my next tutorial, we will implement GPIO interrupts along with the use of systick timer for delay generation.
Comments
Post a Comment