中断是单片机中一个很实用的经典操作,在各项项目中使用有事半功倍的效果。通过对中断服务函数的相关设置和中断触发方式的调整可以使程序更加高效简洁,本文针对MSP430中中断进行简单概述。
中断的基本思想和原理简单来说就是在执行某指令时突然被打断执行新的操作,在执行完后退回被打断的指令继续执行。通俗的说可以理解为:“你在房间写作业突然有人敲门,你开门后继续回去写作业”这一过程,敲门即可以理解为中断触发信号,开门可以理解为中断事件。今天使用简单的按键出发中断控制LED灯亮灭来进行演示,首先依然是对应引脚的配置:
WDTCTL=WDTPW+WDTHOLD;//关闭看门狗
P1DIR |=BIT0;//将P1.0设置为输出
P1DIR &=~BIT1;//将P1.1设置为输入
P1OUT |=BIT0;//将p1.0初始化为高电平
P1REN |=BIT1;//使能上拉
P1OUT |=BIT1;//将p1.1初始化为高电平
在配置好输入输出引脚,设置好初始状态后即可开始配置中断
中断初始化
本次案例中我们采用P1.1板载按键作为中断触发源,因此我们对其进行相对应的中断配置 ,使用到的寄存器分别为PxIE中断使能寄存器,PxIES中断标志寄存器,PxIFG中断触发沿选择寄存器,对应的设置为:
0 | 1 | |
PxIE | 关闭使能 | 开启使能 |
PxIES | 上升沿触发 | 下降沿触发 |
PxIFG | 没有中断请求 | 有中断请求 |
根据上图我们可以参照设置对应的中断触发方式为:
P1IE |=BIT1;//中断使能
P1IES |=BIT1;//设置为下降沿触发
P1IFG &=~BIT1;//清空中断标志
_BIS_SR(GIE);//开启中断使能
我们将触发方式设置为下降沿触发,清空中断标志位后开启中断使能,从而实现对中断触发方式的简单设置,其他终端设置方法也以此类推。
中断服务函数
任何中断都离不开中断服务函数,中断服务函数代表了进入中断后执行的操作等,是实现中断操作的核心之一。MSP430的中断服务函数组成如下:
#pragma vector=PORT1_VECTOR
__interrupt void P1_1ISR(void)
{
P1IFG &=~BIT1;//清空中断标志
P1OUT ^=BIT0;//电平翻转
}
需要注意的是interrupt前的横线为英文输入法下的两次 ‘_’,请书写后检查,否则会产生编译错误无法生成对应的输出文件。通过编写中断函数,即可实现相应的中断操作,同时本次调试过程中出现过少许按键抖动,大家可以自行加入消抖程序进行优化
中断嵌套
在MSP430中不可像STC51,STM32等单片机一样实现执行低优先级中断时及时响应高优先级中断,但是430中我们可以采用中断嵌套的方式来对此问题进行解决。MSP430产生中断响应以后自动关闭总中断,这时更高优先级的中断都不会响应,要中断嵌套的话,就必须在中断中打开总中断。
简易中断嵌套函数(用两组呼吸灯演示中断嵌套)
#include <msp430.h>
volatile int a,b;
void delay(volatile unsigned int t)
{
while(t--);
}
void main(void)
{
WDTCTL=WDTPW+WDTHOLD;//关闭看门狗
P1DIR |=BIT0;//将P1.0设置为输出
P1OUT |=BIT0;//将p1.0初始化为高电平
P4DIR |=BIT7;
P4OUT |=BIT7;
P1REN |=BIT1;//使能上拉
P1DIR &=~BIT1;//将P1.1设置为输入
P1OUT |=BIT1;//将p1.1初始化为高电平
P1IE |=BIT1;//中断使能
P1IES |=BIT1;//设置为下降沿触发
P1IFG &=~BIT1;//清空中断标志
P2IE |=BIT1;
P2IES |=BIT1;
P2IFG &=~BIT1;
_BIS_SR(GIE);//开启中断使能
}
#pragma vector=PORT1_VECTOR
__interrupt void P1_1ISR(void)
{
P1IFG &=~BIT1;//清空中断标志
for(a=10;a>0;a--)
{
P1OUT ^=BIT0;//电平翻转
delay(50000);
P2IE |=BIT1;
P2IES |=BIT1;
P2IFG &=~BIT1;
_EINT();
}
}
#pragma vector=PORT2_VECTOR
__interrupt void P2_1ISR(void)
{
P2IFG &=~BIT1;
for(b=5;b>0;b--)
{
P4OUT ^=BIT7;
delay(50000);
}
}
msp430的指令中,DINT和EINT分别指关和开所有中断, 以上程序效果为,当按下板载P1.1开关时,P1.0板载LED闪烁,当闪烁过程中检测到P2.1按下,P4.7LED闪烁,闪烁结束后继续执行P1.0闪烁。达到了中断执行中响应其他中断的效果。同时单独按下P2.1也会执行对应的闪烁程序,学识浅薄以上代码仅供参考如有更好的写法请告知。
对于多个中断源共用一个中断向量,如P1/P2口中断一定要手动清标志位,,如果在这种中断打开总中断前没有清标志,就会有相同的中断不断嵌入,而导致堆栈溢出引起复位,所以在这类中断中必须先清标志再打开中断开关。