tm4c123gxl库函数调包侠养成(三)——————外部中断与按键

一、中断概述
如果指针是c语言的灵魂,那么中断就是单片机的灵魂。
----所谓中断,相信凡是接触过单片机的人都有印象吧,笔者将其理解为“打断”,即放弃当前中断点的事,跳去干另一件事,干完后回来继续从当前中断点执行之后的代码。
----中断最大的特点,就是响应及时,这里拿按键输入,如果用检测是否输入的方法,把所有代码都写在主函数里,那么一遍只能执行一次检测,这样的话,有的时候因为代码冗长,你按键按下的时候可能不在按键检测的那一段代码,造成按下不响应的现象。而采用中断,通过一个事件来触发中断,中断一旦触发,会立即停止并执行相应中断内容,这样响应的速度会快很多。
----中断服务函数内的代码不能过多,如果用的是定时器中断,每多少秒产生一次中断,在中断服务函数中,如果代码过多,会导致一部分代码没被执行就被下一个中断打断了,这一点一定要注意,两个中断之间的间隔时间也要注意。
二、相关函数
1、GPIOIntEnable(GPIO_PORTF_BASE, GPIO_PIN_4);
确定是哪个io口产生中断
2、GPIOIntTypeSet(GPIO_PORTF_BASE, GPIO_PIN_4, GPIO_FALLING_EDGE);
确定是哪个io口的哪种中断触发方式
第三个参数:配置中断触发方式
GPIO_FALLING_EDGE 下降沿触发,即电平由高电平向低电平跳变的过程
GPIO_RISING_EDGE 上升沿触发,即电平由低电平向高电平跳变的过程
GPIO_BOTH_EDGES 双边沿触发
GPIO_LOW_LEVEL 低电平触发
GPIO_HIGH_LEVEL 高电平触发

3、GPIOIntRegister(GPIO_PORTF_BASE, IntHandler_GPIOF);
注册中断;
笔者理解中断注册是把中断和对应的中断服务函数连接起来的过程。
第二个参数是中断服务函数的名称;
中断服务函数是中断出发后会去执行的函数,一般都是void IntHandler_GPIOF(void)的形式。

4、IntEnable(INT_GPIOF);
使能中断;
注意,io口的中断是以一个大的基地址为单位,即f口中任何一个脚发生中断,都会跳去同一个中断服务函数。

5、IntMasterEnable();
使能总中断。

6、 ui32IntStatus = GPIOIntStatus(GPIO_PORTF_BASE, true);
获得指定的中断状态并返回;
第二个参数,笔者不是很懂,但用true就完事

7、 GPIOIntClear(GPIO_PORTF_BASE, GPIO_PIN_4);
清除指定的中断源。
因为在中断触发之后,会产生相应的中断源,中断源会导致函数到中断服务函数中,若在中断服务函数中不清除中断源,则会导致中断一直被触发。
三、代码逻辑
1、配置io口为输入,并相应的上拉下拉
2、确定是哪个io口的中断GPIOIntEnable
3、配置该io口的中断触发方式GPIOIntTypeSet
4、中断注册,与中断服务函数连接起来GPIOIntRegister
5、使能相应的中断IntEnable
6、使能总中断IntMasterEnable
7、编写中断服务函数

四、相关代码

#include <stdint.h>
#include <stdbool.h>
#include “inc/hw_memmap.h”
#include “inc/hw_ints.h”
#include “driverlib/gpio.h”
#include “driverlib/pin_map.h”
#include “driverlib/sysctl.h”
#include “driverlib/interrupt.h”

 volatile bool bKeyIntFlag = false;
    
    

    void IntHandler_GPIOF(void)//中断服务函数
    {
        uint32_t ui32IntStatus;
    
 

   ui32IntStatus = GPIOIntStatus(GPIO_PORTF_BASE, true);//获取状态

        GPIOIntClear(GPIO_PORTF_BASE, GPIO_PIN_4);//清除指定的中断源

        if((ui32IntStatus & GPIO_PIN_4) == GPIO_PIN_4)//这里可以判断是哪个io口的中断
        {
  
            bKeyIntFlag = true;

        }
    }
    

    void main(void)
    {

        SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
                           SYSCTL_XTAL_16MHZ);
    

        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

        while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF))
            ;
    

        GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1);
    

        GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0x0);
    

        GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_4);

        GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_4, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
    

        GPIOIntEnable(GPIO_PORTF_BASE, GPIO_PIN_4);
    

        GPIOIntTypeSet(GPIO_PORTF_BASE, GPIO_PIN_4, GPIO_FALLING_EDGE);
    

        GPIOIntRegister(GPIO_PORTF_BASE, IntHandler_GPIOF);
    



    IntEnable(INT_GPIOF);


    IntMasterEnable();

while(1)
{
if(true == bKeyIntFlag) {
bKeyIntFlag = false;

GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_PIN_1);

SysCtlDelay(1000*(SysCtlClockGet()/3000));

GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0x0);

}

}

}

发布了10 篇原创文章 · 获赞 14 · 访问量 5505

猜你喜欢

转载自blog.csdn.net/qq_43725844/article/details/89093405