GPIO Inputs and Interrupt Handling β
Complete Lab Manual
For the complete experiment including learning objectives, theoretical background, and detailed explanations, download the PDF manual: Download Experiment 5 PDF
Examples β
The following examples demonstrate GPIO input configuration using polling and interrupt-based approaches.
Example 1: Reading Switch Input Using Polling β
This example continuously polls the state of SW1 (PF4) and turns on the red LED (PF1) when the button is pressed.
#include "TM4C123.h"
#define RED_LED 0x02
#define SWITCH 0x10
int main(void) {
unsigned int state;
SYSCTL->RCGCGPIO |= (1<<5); // Enable Port F
GPIOF->PUR |= SWITCH; // Enable pull-up resistor on PF4
GPIOF->DIR |= RED_LED; // Set PF1 as an output pin and PF4 as an input pin
GPIOF->DEN |= (RED_LED | SWITCH); // Enable PF1 and PF4 as a digital GPIO pins
while(1) {
state = GPIOF->DATA & SWITCH; // Read the state of the switch
if (state == 0) { // If the switch is pressed (since it's Pull-up)
GPIOF->DATA |= RED_LED; // Turn on the LED
} else { // If the switch is not pressed
GPIOF->DATA &= ~RED_LED; // Turn off the LED
}
}
}Explanation:
GPIOF->PUR |= SWITCH;enables the internal pull-up resistor on PF4.- The
while(1)loop continuously reads the switch state. - When
state == 0, the button is pressed (pull-up makes it active-low). - The LED is controlled directly in the main loop without interrupts.
Example 2: Interrupt-Driven Switch Input β
This example configures SW1 and SW2 to generate interrupts on button presses and toggles the green LED in the ISR.
#include "TM4C123.h"
#define GREEN_LED 0x08
#define SW1 0x10
#define SW2 0x01
int main(void)
{
SYSCTL->RCGCGPIO |= (1<<5); // Enable clock to GPIOF
GPIOF->LOCK = 0x4C4F434B; // unlock commit register
GPIOF->CR = 0x01; // make PORTF0 configurable
// PINS Configurations
GPIOF->DIR &= ~(SW1 | SW2); // Set SW1, SW2 as input pins
GPIOF->DIR |= GREEN_LED; // Set GREEN_LED as output pin
GPIOF->DEN |= (GREEN_LED | SW1 | SW2); // Enable digital function for GREEN_LED, SW1, SW2
GPIOF->PUR |= (SW1 | SW2); // Enable pull-up resistors on SW1, SW2
// Interrupt Configurations
GPIOF->IS &= ~(SW1 | SW2); // SW1, SW2 are edge-sensitive
GPIOF->IBE &= ~(SW1 | SW2); // SW1, SW2 are not both edges
GPIOF->IEV &= ~(SW1 | SW2); // falling edge trigger
GPIOF->ICR |= (SW1 | SW2); // clear any prior interrupt
GPIOF->IM |= (SW1 | SW2); // unmask interrupt
// Enable Interrupts
NVIC->ISER[0] |= (1<<30); // enable interrupt 30 in NVIC
// NVIC_EnableIRQ(GPIOF_IRQn); // Alternative way using CMSIS function
while(1)
{
}
}
void GPIOF_Handler(void) {
if (GPIOF->MIS & SW1) { // check if interrupt causes by PF4/SW1
GPIOF->DATA |= GREEN_LED; // turn on green LED
GPIOF->ICR |= SW1; // clear the interrupt flag
}
else if (GPIOF->MIS & SW2) { // check if interrupt causes by PF0/SW2
GPIOF->DATA &= ~GREEN_LED; // turn off green LED
GPIOF->ICR |= SW2; // clear the interrupt flag
}
}Explanation:
GPIOF->LOCK = 0x4C4F434B;unlocks Port F for PF0 configuration.GPIOF->CR = 0x01;allows changes to PF0.GPIOF->IS &= ~(SW1 | SW2);configures edge-sensitive interrupts.GPIOF->IEV &= ~(SW1 | SW2);selects falling-edge trigger (button press).GPIOF->ICR |= (SW1 | SW2);clears any prior interrupt flags before enabling.GPIOF->IM |= (SW1 | SW2);unmasks (enables) interrupts for SW1 and SW2.NVIC->ISER[0] |= (1<<30);enables GPIO Port F interrupt in NVIC.- The ISR checks
GPIOF->MISto identify which switch caused the interrupt. - Each interrupt flag must be cleared with
GPIOF->ICRto prevent re-triggering.
Tasks β
Task 1: Toggle LED Using Polling β
Modify Example 1 to toggle the green LED (PF3) with each press of SW1 (PF4). The LED should change state (ONβOFF or OFFβON) every time the button is pressed and released.
Requirements:
- Use polling to detect button presses.
- Implement software debouncing by adding a delay after detecting a press.
- Toggle the LED state instead of simply turning it on or off.
- Ensure the LED changes state only once per button press.
Task 2: LED Sequence Using Interrupts β
Modify Example 2 to cycle through LED colors using interrupts:
- Pressing SW1 (PF4) cycles through: Red β Blue β Green β Red...
- Pressing SW2 (PF0) cycles through: Yellow β Magenta β Cyan β Yellow...
Requirements:
- Use interrupt-driven input handling.
- Maintain separate state variables for each button's LED sequence.
- Update the LED color in the ISR based on the current state.
- Clear interrupt flags properly to avoid repeated triggering.
Hint: Use a global variable (e.g., sw1_state) to track the current position in the sequence. In the ISR, increment the state and use a switch-case or modulo operation to cycle through colors. Refer to the LED color table in Experiment 4 for LED color codes.