MSP430F149——中断及案例

中断

MSP430F149内部有三种类型中断:系统复位中断,不可屏蔽中断,可屏蔽中断

中断过程
①完成当前正在执行的指令﹔
②把PC寄存器内容入栈;
③把SR寄存器内容入栈;
④如果同时有多个中断,则选择优先级最高的中断;
⑤如果中断是单源中断,则中断标志位自动复位;如果中断是多源中断,则需要中断服务程序复位;
⑥SR清零,结束低功耗模式。由于GIE被清除,其他的中断被屏蔽。因此,中断不能被嵌套;
7.中断向量被装入PC寄存器,并从该地址开始执行中断服务程序。

中断向量表
在这里插入图片描述

系统复位中断

POR PUC

不可屏蔽中断

外部管脚NMI的触发(也就是所说的复位模式)
标志位:OFIFG
Flash非法访问
标志位:ACCVIFG
振荡器不稳定
标志位:NMIIFG

可屏蔽中断

状态寄存器SR中的下标为3的GIE位为总中断允许控制位,这是区分是否屏蔽的主要依据

16个外部中断

特点

多元中断:2组8个中断(必须软件清零标志位)
只有边缘跳变中断

引脚配置

(以引脚P2.1为例)

P2DIR |= BIT1;   //配置P2.1方向为输入模式
P2IE  |= BIT1;  //配置P2.1的中断使能
P2IES |= BIT1;   //配置P2.1为下降沿中断响应

其他寄存器可配置,可不配置。引脚功能选择为一般引脚,不是功能引脚。

中断函数配置

(以引脚P2.1为例)

#pragma vector =PORT2_VECTOR
__interrupt void tangle_make(void)
{
     //用户自定义函数
      P2IFG = 0x00;  //中断标志位软件清零
}   

定时器中断

Timer_A,Timer_B,处于定时模式的看门狗

寄存器配置
 //定时模式示例
  CCTL0 = CCIE;                              // 捕获/比较中断使能
  CCR0 = 6000;                               // 比较值为8000,即从0计数到8000产生一次中断  
  TACTL = TASSEL_2 + MC_1+TACLR;              // 使用SMCLK时钟,使用增计数模式,清零TACCR寄存器  
   
   //捕获模式示例
  TACTL  = TACLR + TASSEL_2 + ID_3 + MC_3;      //清零TACCR寄存器,使用SMCLK时钟,8分频,使用增减计数模式
  TACCTL0 = CM_2+ CCIS_0 + SCS + CAP + CCIE;   //设置为 下降沿捕获,捕获通道0,同步捕获,捕捉模式,捕获/比较中断使能
  TACCTL1 = CM_3 + CCIS_1 + SCS + CAP + CCIE;   //设置为 上升下降沿捕获,捕获通道1,同步捕获,捕捉模式,捕获/比较中断使能
   
  //PWM输出模式示例
   TACTL |= TASSEL_2 + ID_3 + MC_2 + TACLR + TAIE; //使用SMCLK时钟,8分频,使用连续计数模式,清零TACCR寄存器,定时器溢出中断
   TACCTL0= CCIE;
   CCR0 = 5000;
中断函数配置
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)             //定时器A中断服务程序
{
   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};
// SEG 数字0—9   共阳
unsigned char Seg_Wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0xff};   
// 位选

unsigned char Flag = 0;

void Port_Init()
{
   P1DIR = 0x00;   //P1端口设置为输入模式
   P1IE = 0xff;   //P1端口多元中断使能
   P1IES = 0xff;  //P1端口下降沿触发中断
   
   P3DIR = 0xff;   //P3端口设置为输出模式
   P3OUT = 0xff;  //P3端口输出高电平
   
   P5DIR = 0x07;   //P4端口设置为输出模式   P5.0=STCP  P5.1=SHCP  P5.2=DS 
   P5OUT = 0xff;  //P4端口输出高电平
   
}

void Clock_Init()
{
   unsigned char i;
   BCSCTL1 = RSEL0 + RSEL1 + RSEL2;          // 采用最高频率7   ACLK = XT2
   BCSCTL1&=~XT2OFF; //打开XT2振荡器
   do
   {
      IFG1 &= ~OFIFG; // 清除振荡器失效标志
      for (i = 255; i > 0; i--); // 延时,等待XT2起振
   }
    while ((IFG1 & OFIFG) != 0); // 判断XT2是否起振
   
   BCSCTL2 |= SELS+SELM_2;                          // SMCLK = MCLK = XT2   
}


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;                   // SHCP=1;  上升沿
     P5OUT&=0xfD;

     Data<<=1;                      //从高位开始取数据 
   } 
    P5OUT|=0x01;                    //STCP=1;
    P5OUT&=0xfe;                   // STCP=0;

}



void main(void)
{   
   WDTCTL = WDTPW + WDTHOLD;               //关闭看门狗
   
   Port_Init();
   Clock_Init();
   //_BIS_SR(LPM0_bits + GIE);                   // _BIS_SR(LPM0_bits + GIE) 具有同时打开全局中断和进入LPM0;  等同于:_EINT();  LPM0;
                                              // 如果只使用定时器之类的功能时,可以使用低功耗模式,而不使用while(1)
   _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)             //外部中断P1中断服务程序
{
    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;
    
}

  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值