MSP432P401R基础使用
三、外部中断
MSP432P401R并不是每一个IO口都可以中断,必须参考msp432p401r第17页
port interrupt:端口中断
只有P1到P7所有IO口可以做外部中断
(一)代码
1.gpio.h
- (1)开启外部中断
GPIO_enableInterrupt(GPIO_PORT_Px,GPIO_PINx);
- 配置触发方式
GPIO_interruptEdgeSelect(GPIO_PORT_P1,GPIO_PIN4,Edge);
Edge有效值:
GPIO_HIGH_TO_LOW_TRANSITION//下降沿(从高到低)
GPIO_LOW_TO_HIGH_TRANSITION//上升沿(从低到高)
- 获取GPIO中断状态
GPIO_getEnabledInterruptStatus(GPIO_PORT_Px);
- 清除GPIO中断标志位
GPIO_clearInterruptFlag(GPIO_PORT_Px,GPIO_PINx);
配合使用
status=GPIO_getEnabledInterruptStatus(GPIO_PORT_Px);
GPIO_clearInterruptFlag(GPIO_PORT_Px,status);
2.interrupt.h
- 开启总中断
Interrupt_enableMaster(void);
- 开启端口中断
Interrupt_enableInterrupt(interruptNumber);
interruptNumber有效值:
INT_PORT1
INT_PORT2
INT_PORT3
INT_PORT4
INT_PORT5
INT_PORT6
(二)一般配置步骤
-
配置GPIO输入
GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1); //P1.1 GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN4); //P1.4
-
清除中断标志位
GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1); GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN4);
-
配置触发方式
GPIO_interruptEdgeSelect(GPIO_PORT_P1, GPIO_PIN1, GPIO_HIGH_TO_LOW_TRANSITION); GPIO_interruptEdgeSelect(GPIO_PORT_P1, GPIO_PIN4, GPIO_HIGH_TO_LOW_TRANSITION);
-
开启外部中断
GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1); GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN4);
-
开启端口中断
Interrupt_enableInterrupt(INT_PORT1);
-
开启总中断
Interrupt_enableMaster();
-
编写中断服务函数
void PORT1_IRQHandler(void)
{
uint16_t status;
status = GPIO_getEnabledInterruptStatus(GPIO_PORT_P1);
GPIO_clearInterruptFlag(GPIO_PORT_P1, status);
delay_ms(10);//按键消抖
if (status & GPIO_PIN1) //对应P1.1
{
if (KEY1 == 0)
{
LED_RED_On(); //点亮红灯
}
}
if (status & GPIO_PIN4) //对应P1.4
{
if (KEY2 == 0)
{
LED_RED_Tog();//翻转红灯
}
}
}
(三)中断优先级管理
详情见技术手册(slau356)82页
-
等级越低,中断优先级越高,也就是说等级0的优先级最高。
-
支持动态调整优先级
-
将优先级分为组优先级和子优先级,组优先级高的是可以打断组优先级低的,组优先级一样时就不会被打断,如果发生了两个组优先级一样的中断,则子优先级高的会先执行,另一个挂起
-
注意,这里的子优先级是硬件优先级,是已经设置好了的,不能更改
详情见msp432p401r第117页,中断号(NVIC INTERRUPT INPUT)越小,子优先级越高
例子:
系统有两个中断,中断A和中断B,中断号分别为1和2。
当不进行中断优先级配置时,组优先级一致,中断号即为中断优先级,中断号小的中断优先级高,所以中断优先级为A>B。假如此时系统正在执行中断B,而中断A发生了,系统会如何处理呢?因为它们组优先级一样,故中断A不能打断中断B,系统会先挂起中断A,待中断B执行完后,再执行中断A;
倘若将中断A的组优先级设置为1,中断B的组优先级设置为2,此时系统正在执行中断B,而中断A发生了,系统会如何处理呢?因为组优先级小的优先级高,所以中断优先级是A>B,故系统打断中断B,执行中断A,待中断A执行完后,再继续执行中断B。
总结:
- 组优先级高的能打断组优先级低的
- 在组优先级一样的情况下,子优先级高的不能打断子优先级低的
1.代码
- 设置组优先级
Interrupt_setPriority(interruptNuber,level);
level:x<<5,x∈[0,7]
只使用高3位,配置时左移5位。
(四)外部中断实验
exti.h
#ifndef __EXTI_H
#define __EXIT_H
#include "driverlib.h"
void EXTIX_Init(void);//外部中断初始化
#endif
exti.c
#include "driverlib.h"
#include "exti.h"
void EXTIX_Init(void)
{
//1.配置GPIO输入
GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1); //P1.1
GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN4); //P1.4
//2.清除中断标志位
GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1);
GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN4);
//3.配置触发方式
GPIO_interruptEdgeSelect(GPIO_PORT_P1, GPIO_PIN1, GPIO_HIGH_TO_LOW_TRANSITION);
GPIO_interruptEdgeSelect(GPIO_PORT_P1, GPIO_PIN4, GPIO_HIGH_TO_LOW_TRANSITION);
//4.5 配置组优先级
Interrupt_setPriority(INT_PORT1, 1 << 5);
Interrupt_setPriority(INT_PORT1, 2 << 5);
//4.开启外部中断
GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1);
GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN4);
//5.开启端口中断
Interrupt_enableInterrupt(INT_PORT1);
//6.开启总中断
Interrupt_enableMaster();
}
main.h
#include "driverlib.h"
/* Standard Includes */
#include <stdint.h>
#include <stdbool.h>
#include "led.h"
#include "key.h"
#include "delay.h"
#include "exti.h"
int main(void)
{
/* Stop Watchdog */
MAP_WDT_A_holdTimer();
LED_Init();
EXTIX_Init();
delay_init();
while (1)
{
}
}
//7.编写中断服务函数
void PORT1_IRQHandler(void)
{
uint16_t status;
status = GPIO_getEnabledInterruptStatus(GPIO_PORT_P1);
GPIO_clearInterruptFlag(GPIO_PORT_P1, status);
delay_ms(10);//按键消抖
if (status & GPIO_PIN1) //对应P1.1
{
if (KEY1 == 0)
{
LED_RED_On(); //点亮红灯
}
}
if (status & GPIO_PIN4) //对应P1.4
{
if (KEY2 == 0)
{
LED_RED_Tog();//翻转红灯
}
}
}