中断
(一)查询与中断
1.查询:按照主函数中的语句顺序,顺序执行
(1)优点:结构简单,易于理解
(2)缺点:无法充分利用CPU资源
2.中断:程序顺序执行,遇到中断使能,跳转执行中断函数
(1)优点
(2)缺点:结构复杂,不好理解(次要)
(二)中断相关知识
1.中断分类(中断源)
(1)外部中断
(2)内部中断
- CPU内部中断,如重置,遇到突发事件处理的中断
- 相关外设中断
2.中断优先级:优先级高的先执行
3.注意:具体哪些端口可以中断需要看具体数据手册
(三)编程
1.编程流程
(1)配置所需中断功能相关寄存器,开启功能中断以及全局中断
(2)编写中断处理子程(ISR)(CPU硬件自动调用)
- 中断触发源判断(中断触发,相关标志位置1)
- 中断标志位清零
(3)在中断函数中处理相关任务
2.编程实例
(1)寄存器编程
#include <msp430.h>
/**
* main.c
*/
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
/******************
* 功能:按键实现LED开关
* 函数:按键中断函数
******************/
/*LED初始化*/
P1SEL &=~BIT0; //GPIO模式
P1DIR |= BIT0; //输出模式
/*按键中断初始化*/
P2SEL &=~BIT1; //GPIO模式
P2DIR &=~BIT1; //输入模式
P2IE |= BIT1; //中断使能
//内部配置上拉电阻
P2REN |= BIT1; //上拉电阻
P2OUT |= BIT1; //输出为高
P2IES |= BIT1; //中断边沿选择(上升沿)
P2IFG &=~BIT1; //中断标志位清零
_EINT(); //全局中断开启
return 0;
}
/*延时函数*/
void delay(unsigned char Time)
{
while(Time--);
}
/*按键中断处理子程*/
#pragma vector = PORT2_VECTOR
__interrupt void PORT2_ISR()
{
/*按键去抖*/
if(P2IFG & BIT1) //判断中断标志位,是否开启中断
{
delay(40);
if(!(P2IN & BIT1)) //判断按键是否按下
{
while(!(P2IN & BIT1)); //等待按键抬起
delay(40); //延时去抖
//功能执行语句
P1OUT ^= BIT0; //LED闪烁
}
}
P2IFG &=~BIT1;
}
(2)库函数编程
#include "msp.h"
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
/**
* main.c
*/
void main(void)
{
WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD; // stop watchdog timer
/******************
* 功能:按键实现LED闪烁
* 函数:按键中断函数
******************/
/*LED初始化*/
//P1.0作为输出模式
MAP_GPIO_setAsOutputPin(GPIO_PORT_P1,GPIO_PIN0);
/*按键中断初始化*/
//P1.4作为输入模式
MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1,GPIO_PIN4);
//按键中断使能
MAP_GPIO_enableInterrupt(GPIO_PORT_P1,GPIO_PIN4);
//按键上升沿触发
MAP_GPIO_interruptEdgeSelect(GPIO_PORT_P1,GPIO_PIN4,GPIO_LOW_TO_HIGH_TRANSITION);
//清除中断标志位
MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1,GPIO_PIN4);
MAP_Interrupt_enableInterrupt(INT_PORT1);//开启PORT1全局中断
while(1);
}
/*按键中断处理函数*/
void PORT1_IRQHandler(void)
{
uint32_t status;
status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P1); //得到产生中断的位
if(status & GPIO_PIN4) //判断中断标志位
{
MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);
}
MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, status); //清除中断标志位
}
3.总结
(1)此例只是简单的中断函数,目的是为了明白中断的大致原理
(2)中断是非常重要的在嵌入式开发中,当然还有更高效的操作系统编程,但这不是目前要了解的