Introduction to GPIO interrupts

        The GPIO pins can detect interrupt in digital form. When pin state is high, it will activate interrupt on the processor. These interrupt will be handled by using Nested Vector Interrupt Controller. For every GPIO port, it uses an individual interrupt handler. Interrupt generated on the same GPIO port but different GPIO pins can be identified by using the software. Tiva Launchpad supports tail changing operations on interrupt.  

Experiment 3: Using Tiva Launchpad Generate an interrupt on GPIO pins using a switch. Continuously toggle the state of onboard GREEN LED for a duration of 2 sec. When switch SW1 is pressed generate an interrupt on the microcontroller and turn ON RED LED for the 5-sec duration. Perform this experiment on an operating frequency of 16MHz.

      For this experiment, tactile switch SW1 is used to generate an interrupt that is connected to PF_4. When an interrupt is generated pin PF_1 will change their state to HIGH for the 5-sec duration. When interrupt is not activated microcontroller will continuously toggle the state of GREEN LED for the 2-sec duration.


Generation of 16MHz clock frequency:

        For this experiment, required 16MHz clock which is directly taken from external 16MHz crystal and passing through main OSC. No need to increase frequency value further so instead of using PLL passing this signal through OSC. At the end, the SYS_DIV_1 factor is used and 16MHz is obtained at the output.

API representation: SysCtlClockSet ( SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);


Delay count: 

No. of counts: (Delay required * System clock ) ÷ 3

For 5 sec delay  = ( 5 * 16 MHz ) ÷ 3

                          = 26666666

For 2 sec delay = ( 2 * 16 MHz ) ÷ 3

                          = 10666666


Algorithm:

1. Set system clock frequency to 16MHz.

2. Enable GPIO port F

3. Set PF_1 and PF_3 as an output for RED and GREEN LED respectively.

4. Set PF_4 as input for switch SW_1

5. Configure GPIO pad for 8mA strength and weak-up configuration.

6. Set the detection type of GPIO interrupt.

7. Declared interrupt handler for GPIO port F

8. Enable interrupt on GPIO pin PF_4

9. Interrupt generated ?

    Yes =  a. Call interrupt handler

               b. Clear interrupt register

               c. Set PF_1 HIGH for 5 sec duration

    No  =  a. Set PF_3 High for 2 sec

               b. Set PF_3 Low for sec 



API used for this experiment:

1. Set clock frequency:
API syntax: SysCtlClockSet ( Clock_Configuration_Parameter)
Explanation: Generating a 16MHz clock from external crystal. 
API used: SysCtlClockSet ( SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHz )

2. Enable GPIO peripherals:
API syntax: SysCtlPeripheralEnable ( Peripheral_Name)
Explanation: For this experiment, we required a GPIO port F block. SYSCTL_PERIPH_GPIOF function will be used to enable GPIO port F.
API used: SysCtlPeripheralEnable ( SYSCTL_PERIPH_GPIOF )

3. Configure GPIO pin as an output
API syntax: GPIOPinTypeGPIOOutput ( GPIO_Port, GPIO_Pin )
Explanation: For on-board LED we required two GPIO pins from port F so we need to configure PF_1, PF_3 these three pins as output.
API used: 
GPIOPinTypeGPIOOutput ( GPIO_PORTF_BASE, GPIO_PIN_1 | GPIO_PIN_3)

4. Set GPIO pin as input
API syantax: GPIOPinTypeGPIOInput ( GPIO_Port, GPIO_Pin )
Explanation: For SW1 we need to set pin PF_4 as output
API used: GPIOPinTypeGPIOInput ( GPIO_PORTF_BASE, GPIO_PIN_4)

5. Configure GPIO pad to read input
API syntax: GPIOPadConfigSet ( GPIO_Port, GPIO_Pin, Drive_strength, Switch_configuration )
Explanation: This API is used to set GPIO pin drive strength current and pull-up or pull-down configuration
API used: GPIOPadConfigSet ( GPIO_PORTF_BASE ,GPIO_PIN_4 , GPIO_STRENGTH_8MA , GPIO_PIN_TYPE_STD_WPU )

6. Set type of interrupt
API syantax: GPIOIntTypeSet ( GPIO_Port, GPIO_Pin, Type_of_interrupt )
Explanation: This API is used to set trigger mechanism of interrupt. It supports rising edge, falling edge, both rising and falling edge, high level and low level detection of interrupt.
API used: GPIOPinRead ( GPIO_PORTF_BASE, GPIO_PIN_4, GPIO_FALLING_EDGE)

7. Declared register for an interrupt handler
API syntax: GPIOIntRegister ( GPIO_PORT, Interrupt_handler_function)
Explanation: his API is used to declare register for the interrupt handler. When an interrupt is interrupted then declared interrupt_handler function is called to service interrupt. 
API used: GPIOIntRegister(GPIO_PORTF_BASE,switch_sw1_interrupt)

8. Enable interrupt
API syntax: GPIOIntEnable ( GPIO_PORT, GPIO_Pin)
Explanation: This API is used to enable an interrupt on particular pin of GPIO port.
API used: GPIOIntEnable(GPIO_PORTF_BASE, GPIO_INT_PIN_4)

9. Clear interrupt flag
API syntax: GPIOIntClear ( GPIO_PORT, GPIO_Pin)
Explanation: This API is used to clear interrupt generated on a particular flag.
API used: GPIOIntClear(GPIO_PORTF_BASE, GPIO_PIN_4)

10. Assign a value to GPIO pin
API syntax: GPIOPinWrite ( GPIO_PORT, GPIO_PIN, Pin_Value)
Explanation: To turn on LEDs we are passing hexadecimal value from this API. Register value for RED: 0x02, GREEN: 0x08, Blue: 0x04. To turn off LED we need to pass 0x00 for a particular pin.
API used:
GPIOPinWrite ( GPIO_PORTF_BASE, GPIO_PIN_1, 0x02) // Turn ON red LED
GPIOPinWrite ( GPIO_PORTF_BASE, GPIO_PIN_1, 0x00) // Turn OFF red LED

11. Generate Delay:
API syntax: SysCtlDelay (Number_of_counts)
Explanation: Pass the number of counts from this API to generate a delay.
API used: SysCtlDelay ( 10666666 ) // 2 Second delay.


Program Explanation:

Include header files:

    Include stdint and stdbool header files for declaration of integer and boolean data types. hw_memmap is used to declared memory mapping of peripherals. debug.h is used to include a debugger for the debugging process. gpio.h is used to declared GPIO pins values and addresses. sysctl,h header files are used to declared system control APIs.

Declared interrupt handler function:

           Declared interrupt handler function for interrupt. When an interrupt is generated then the processor start to execute switchh_sw1_interrupt function. Initially clear the interrupt flag and then turn ON RED LED. Generate delay for 5 seconds and then turn OFF the RED LED.

Initialization of peripherals:
        Start the main loop with int main. Initially declared system clock frequency to 16MHz directly taking from external 16MHz crystal. Enable GPIO port F for a switch and LED. Declared PF_1 and PF_3 pin as output for RED and GREEN LED's and PF_$ as output for switch SW1. Configure input pin for sensing 8mA current and standard week pull up configuration. 

Interrupt configuration:
        First declared interrupt on GPIO port F pin PF_4 using GPIOIntTypeSet function. These API is used to set interrupt on the specified pin. Using GPIOIntRegister declared interrupt handler function for GPIO port F and then enable interrupt.

Main repeating while loop:
           In continuous while loop toggle state of GREEN LED continuously for 2-sec delay.

Interrupt Handler Setup:
1. Expand project from project explorer and open "tm4c123gh6pm_startup_ccs.c" file.
2. Declared interrupt handler function below other fault handling functions. Add line "extern void switch_sw1_interrupt (void)" for the declared interrupt handler.
3. Find GPIO port F comment and replace corresponding "IntDefaultHandler" function with "switch_sw1_interrupt function".

Final code:
#include <stdint.h>
#include <stdbool.h>

#include "inc/hw_memmap.h"
#include "driverlib/debug.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"

void switch_sw1_interrupt()
{
     GPIOIntClear(GPIO_PORTF_BASE, GPIO_PIN_4);
     GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0x02);
     SysCtlDelay(26666666);
     GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0x00);
}

int main(void)
{
     SysCtlClockSet (SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_XTAL_16MHZ |                                               SYSCTL_OSC_MAIN);
      SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

      GPIOPinTypeGPIOOutput ( GPIO_PORTF_BASE , GPIO_PIN_1 | GPIO_PIN_3);
      GPIOPinTypeGPIOInput ( GPIO_PORTF_BASE , GPIO_PIN_4 );
      GPIOPadConfigSet ( GPIO_PORTF_BASE , GPIO_PIN_4 , GPIO_STRENGTH_8MA ,                                                          GPIO_PIN_TYPE_STD_WPU );

    GPIOIntTypeSet ( GPIO_PORTF_BASE , GPIO_PIN_4 , GPIO_FALLING_EDGE);
    GPIOIntRegister(GPIO_PORTF_BASE,switch_sw1_interrupt);
    GPIOIntEnable(GPIO_PORTF_BASE, GPIO_INT_PIN_4);

    while(1)
    {
        GPIOPinWrite (GPIO_PORTF_BASE, GPIO_PIN_3, 0x08);
        SysCtlDelay(10666666);
        GPIOPinWrite (GPIO_PORTF_BASE, GPIO_PIN_3, 0x00);
        SysCtlDelay(10666666);
    }
}



    
Reference: TM4C123GH6PM microcontroller datasheet
                          TivaWare Peripheral driver library guide

Comments