GPIO_interrupt

smallcracker 2021-01-29 00:00:00
Categories: Tags:

GPIO中断

资料来源

一、函数介绍

(1)void GPIOIntTypeSet(uint32_t ui32Port, uint8_t ui8Pins,uint32_t ui32IntType)

  1. 功能:设置指定引脚的中断触发类型.
  2. 参数:
    (1)ui32Port: GPIO口的基地址
    (2)ui8Pins: 多个bit-packed格式表示的引脚
    (3)ui32IntType: 中断触发类型(有以下类型)
1
2
3
4
5
6
#define GPIO_FALLING_EDGE       0x00000000  // Interrupt on falling edge
#define GPIO_RISING_EDGE 0x00000004 // Interrupt on rising edge
#define GPIO_BOTH_EDGES 0x00000001 // Interrupt on both edges
#define GPIO_LOW_LEVEL 0x00000002 // Interrupt on low level
#define GPIO_HIGH_LEVEL 0x00000006 // Interrupt on high level
#define GPIO_DISCRETE_INT 0x00010000 // Interrupt for individual pin

中断触发方式是啥?

就是怎样触发这个中断

主要有两种方式

沿触发和电平触发

沿触发比如说时钟中断,在被响应并被清除时,就不会触发,

电平触发比如串口中断,在被响应并清除后,从中断态返回SVC态仍可能会触发中断。

可能顾名思义就可以吧。。

(2)void GPIOIntRegister(uint32_t ui32Port, void (*pfnIntHandler)(void))

  1. 功能:注册GPIO中断的中断处理程序
  2. 参数:
    (1)ui32Port :GPIO口的基地址
    (2)pfnIntHandler: 是GPIO中断服务程序入口地址指针。
  3. 说明:
    (1)不管是什么外设触发的中断,都要先注册中断服务函数,告诉程序中断发生时去哪里,类似的函数有SysCtlIntRegisterADCIntRegister
    (2)如果不利用这些中断注册函数,也可以在启动文件中修改中断向量表进行手动注册
    (3)GPIOIntRegister只能以GPIO组为单位注册,不能精确到判断哪个引脚发生中断,因此要在中断服务函数中判断触发中断的引脚,以下为一个示例
1
2
3
4
5
6
7
8
9
//GPIOF中断服务函数
void io_interrupt(void)
{
//获取中断状态
uint32_t s = GPIOIntStatus(GPIO_PORTF_BASE, true);
//如果PF4触发中断
if((s&GPIO_PIN_4) == GPIO_PIN_4)
{...}
}

(3)void GPIOIntEnable(uint32_t ui32Port, uint32_t ui32IntFlags)

  1. 功能:使能指定引脚的中断.
  2. 参数:
    (1)ui32Port :GPIO口的基地址
    (2)ui32IntFlags: 被禁止的中断源中断屏蔽位(指示哪些引脚中断被开启,是以下参数的逻辑或)

(4)void IntEnable(uint32_t ui32Interrupt)

  1. 功能:使能一个中断
  2. 参数:
    (1)ui32Interrupt 指定的被允许的中断.
  3. 说明:这个函数是中断控制器级的中断使能控制

(5)bool IntMasterEnable(void)

  1. 功能:使能处理器中断.
  2. 参数:无
  3. 说明:
    (1)这是处理器级的中断使能控制,它决定处理器要不要处理中断控制器的请求
    (2)以上三个函数,从低级到高级对应了中断处理通路的三道“开关”,如下图所示
  4. 20190709124218959.png (767×468) (csdnimg.cn)
看来要同时有三个级别的中断使能控制。

(6)uint32_t GPIOIntStatus(uint32_t ui32Port, bool bMasked)

  1. 功能:读取指定GPIO口的中断状态
  2. 参数:
    (1)ui32Port: GPIO口的基地址.
    (2)bMasked: 指定返回屏蔽的中断状态还是原始的中断状态
  3. 说明: 如果bMasked被设置为真,则函数返回被屏蔽的中断状态,否则返回原始的中断状态。解释一下所谓“被屏蔽的中断状态”。在GPIOIntEnable这个函数中,没有写在第二个参数ui32IntFlags中的引脚是被屏蔽的(即不处理它们的中断事件)。当bMasked为真时,返回GPIOMIS寄存器值,所有被屏蔽的位都是0,否则返回GPIORIS寄存器值,被屏蔽的位也可能是1(因为虽然不处理这些引脚的中断事件,但它们的输入也可能符合中断特征)
  4. 就是输出都那个口在中断状态。

(7)void GPIOIntClear(uint32_t ui32Port, uint32_t ui32IntFlags)

  1. 功能:清除指定中断源标志

  2. 参数:
    (1)ui32Port :GPIO口的基地址
    (2)ui32IntFlags :被清除的中断源中断屏蔽位

  3. 发生中断后,对应的中断标志位置1,进入中断服务函数,在服务函数中务必清除中断标志,否则程序将不停地进入中断服务函数

二、例程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
void GPIO_INT_init(){
//使能GPIO组,这里设置的是F口
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
//设置某引脚为输入,这里设置的是PF4
GPIODirModeSet(GPIO_PORTF_BASE, GPIO_PIN_4, GPIO_DIR_MODE_IN);
//设置为推挽输入
GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_4, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
//配置中断类型为沿下降
GPIOIntTypeSet(GPIO_PORTF_BASE, GPIO_PIN_4, GPIO_FALLING_EDGE);
//注册中断函数
GPIOIntRegister(GPIO_PORTF_BASE, io_interrupt);
//开启中断
GPIOIntEnable(GPIO_PORTF_BASE, GPIO_PIN_4);
IntEnable(INT_GPIOF);
IntMasterEnable();
}

//下面是中断函数
void io_interrupt(){
//中断函数一开始要清除发生的中断标志
uint32_t s=GPIOIntStatus(GPIO_PORTF_BASE,true);
GPIOIntClear(GPIO_PORTF_BASE, s);
//然后判断读取到的是不是设置的引脚
if((s&GPIO_PIN_4)==GPIO_PIN_4)//如果读取到的是PF4
{
while(!GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_4));//等待按键松开
do_something();//做想做的事情
}
return ;
}