中断
MSP430F149内部有三种类型中断:系统复位中断,不可屏蔽中断,可屏蔽中断
中断过程 ①完成当前正在执行的指令﹔ ②把PC寄存器内容入栈; ③把SR寄存器内容入栈; ④如果同时有多个中断,则选择优先级最高的中断; ⑤如果中断是单源中断,则中断标志位自动复位;如果中断是多源中断,则需要中断服务程序复位; ⑥SR清零,结束低功耗模式。由于GIE被清除,其他的中断被屏蔽。因此,中断不能被嵌套; 7.中断向量被装入PC寄存器,并从该地址开始执行中断服务程序。
中断向量表
系统复位中断
POR PUC
不可屏蔽中断
外部管脚NMI的触发(也就是所说的复位模式) 标志位:OFIFG Flash非法访问 标志位:ACCVIFG 振荡器不稳定 标志位:NMIIFG
可屏蔽中断
状态寄存器SR中的下标为3的GIE位为总中断允许控制位,这是区分是否屏蔽的主要依据
16个外部中断
特点
多元中断:2组8个中断(必须软件清零标志位) 只有边缘跳变中断
引脚配置
(以引脚P2.1为例)
P2DIR
|= BIT1
;
P2IE
|= BIT1
;
P2IES
|= BIT1
;
其他寄存器可配置,可不配置。引脚功能选择为一般引脚,不是功能引脚。
中断函数配置
(以引脚P2.1为例)
#pragma vector =PORT2_VECTOR
__interrupt
void tangle_make(void)
{
P2IFG
= 0x00;
}
定时器中断
Timer_A,Timer_B,处于定时模式的看门狗
寄存器配置
CCTL0
= CCIE
;
CCR0
= 6000;
TACTL
= TASSEL_2
+ MC_1
+TACLR
;
TACTL
= TACLR
+ TASSEL_2
+ ID_3
+ MC_3
;
TACCTL0
= CM_2
+ CCIS_0
+ SCS
+ CAP
+ CCIE
;
TACCTL1
= CM_3
+ CCIS_1
+ SCS
+ CAP
+ CCIE
;
TACTL
|= TASSEL_2
+ ID_3
+ MC_2
+ TACLR
+ TAIE
;
TACCTL0
= CCIE
;
CCR0
= 5000;
中断函数配置
#pragma vector=TIMERA0_VECTOR
__interrupt
void Timer_A
(void)
{
switch(TAIV
)
{
case 2:
******
break;
case 4:
******
break;
case 10:
******
break;
}
}
使用独立按键作为外部中断控制LED灯,并在数码管显示
#include <msp430x14x.h>
unsigned char Seg_code
[]={0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80};
unsigned char Seg_Wei
[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0xff};
unsigned char Flag
= 0;
void Port_Init()
{
P1DIR
= 0x00;
P1IE
= 0xff;
P1IES
= 0xff;
P3DIR
= 0xff;
P3OUT
= 0xff;
P5DIR
= 0x07;
P5OUT
= 0xff;
}
void Clock_Init()
{
unsigned char i
;
BCSCTL1
= RSEL0
+ RSEL1
+ RSEL2
;
BCSCTL1
&=~XT2OFF
;
do
{
IFG1
&= ~OFIFG
;
for (i
= 255; i
> 0; i
--);
}
while ((IFG1
& OFIFG
) != 0);
BCSCTL2
|= SELS
+SELM_2
;
}
void WR_595(unsigned char Data
)
{
unsigned char i
;
for(i
=0;i
<8;i
++)
{
if(Data
&0x80)
P5OUT
|=0x04;
else
P5OUT
&=0xfB;
P5OUT
|=0x02;
P5OUT
&=0xfD;
Data
<<=1;
}
P5OUT
|=0x01;
P5OUT
&=0xfe;
}
void main(void)
{
WDTCTL
= WDTPW
+ WDTHOLD
;
Port_Init();
Clock_Init();
_EINT();
while(1)
{
switch(Flag
)
{
case 1:
{
P3OUT
= 0xfe;
WR_595(Seg_Wei
[0]);
WR_595(Seg_code
[0]);
break;
}
case 2:
{
P3OUT
= 0xfd;
WR_595(Seg_Wei
[1]);
WR_595(Seg_code
[1]);
break;
}
case 3:
{
P3OUT
= 0xfb;
WR_595(Seg_Wei
[2]);
WR_595(Seg_code
[2]);
break;
}
case 4:
{
P3OUT
= 0xf7;
WR_595(Seg_Wei
[3]);
WR_595(Seg_code
[3]);
break;
}
case 5:
{
P3OUT
= 0xef;
WR_595(Seg_Wei
[4]);
WR_595(Seg_code
[4]);
break;
}
case 6:
{
P3OUT
= 0xdf;
WR_595(Seg_Wei
[5]);
WR_595(Seg_code
[5]);
break;
}
case 7:
{
P3OUT
= 0xbf;
WR_595(Seg_Wei
[6]);
WR_595(Seg_code
[6]);
break;
}
case 8:
{
P3OUT
= 0x7f;
WR_595(Seg_Wei
[7]);
WR_595(Seg_code
[7]);
break;
}
}
Flag
= 0;
P5OUT
&=0xfe;
P5OUT
|=0x01;
while(Flag
== 0);
}
}
#pragma vector=PORT1_VECTOR
__interrupt
void PORT_1
(void)
{
switch(P1IFG
)
{
case 0x01:
Flag
= 1;
break;
case 0x02:
Flag
= 2;
break;
case 0x04:
Flag
= 3;
break;
case 0x08:
Flag
= 4;
break;
case 0x10:
Flag
= 5;
break;
case 0x20:
Flag
= 6;
break;
case 0x40:
Flag
= 7;
break;
case 0x80:
Flag
= 8;
break;
}
P1IFG
= 0x00;
}