中断基础

What

  简单来说,单片机出了点事,需要离开程序原有的执行路径,去处理那件更重要的事,等这件事结束后再回到原有的路径。
中断一共有三种类型:

  • 系统复位(POR/PUC)
  • 不可屏蔽中断 NMI:不能由通用中断使能位 (GIE) 屏蔽
  • 可屏蔽中断:可由通用中断使能位 (GIE) 屏蔽

其具体内容可见于用户指南28~37页。在其中需要注意以下内容:
  中断服务程序里,不能长时间执行程序。
  NMI是一个多源中断,一个中断向量对应多个中断标志,所以用户需要线判断中断为何种中断标志,然后手动清除中断标志。
  单源中断标志系统可以自动清除(eg.串口通信中的接收中断和发送中断),多源中断标志需要用户手动清除(eg.上文的NMI)。
  中断程序执行时,SR(状态寄存器被清除,这将终止任何低功耗模式1);如果GIE位被清除,之后的中断被禁用;如果中断程序在执行的时候,GIE置位,那在此中断执行时可以停下执行其他中断,无论哪个中断优先级更高
  中断向量实际就是保存中断函数入口地址的存储单元空间。

How

  使用各种中断功能时,基本步骤大概为:使能相应中断;配置中断检测标志;选择相应的操作模式以实现低功耗;编写中断处理函数。

举例

将基础I/O章节的Task用中断实现

#include <msp430.h>

int main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // 关闭看门狗定时器
  P1DIR |= BIT0;                            // 设置P1.0为输出
  P1IE |=  BIT3;                            // 使能P1.3中断 
  P1IES |= BIT3;                            // P1.3为下降沿中断
  P1REN |= BIT3;			   // 使能SW2为上下拉 (P1.3)
  P1OUT |= BIT3;			   // 设置SW2为上拉 (P1.3)
  P1IFG &= ~BIT3;                           // P1.3 IFG 中断标志位清除
    	  	  	  	  	  	  	  	  	    //BIT3 on Port 1 can be used as Switch2

											
  _BIS_SR(LPM4_bits + GIE);                 // 进入LPM4模式,并使能中断
}

// Port 1 interrupt service routine
#pragma vector=PORT1_VECTOR//#pragma vector 是固定在程序中的格式,后面接的是中端向量地址
__interrupt void Port_1(void)//__interrupt 这个关键字用来指
								//定一个函数应该被看成一个中断函数。当你使用
								//interrupt 关键字时,编译器会按ISR 函数要求的寄存
								//器保存规则去保存寄存器,然后生成一些特殊的返回代码序列(return sequence) 。
{
  P1OUT ^= BIT0;                            // 改变P1.0输出电平
  P1IFG &= ~BIT3;                           // P1.3 IFG 中断标志位清除
}

该程序有一个缺点:未进行按键消抖,宏观上按下一次按键后LED1的状态不确定。

Task

在以上程序基础上增加消抖程序,怎么“消”都行,只看最后效果。
经过学渣改变后的程序如下:

#include <msp430.h>

void Delay_ms(unsigned cnt)
{
  unsigned int i,j;
  for(j=0;j<cnt;j++)
  {
    i=1000/6;
    while(i--);
  }
}

int main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // 关闭看门狗定时器
  P1DIR |= BIT0;                            // 设置P1.0为输出
  P1IE |=  BIT3;                            // 使能P1.3中断 
  P1IES |= BIT3;                            // P1.3为下降沿中断
  P1REN |= BIT3;			   // 使能SW2为上下拉 (P1.3)
  P1OUT |= BIT3;			   // 设置SW2为上拉 (P1.3)
  //P1OUT &= ~BIT3;			   // 使能SW2为下拉 (P1.3)
  P1IFG &= ~BIT3;                           // P1.3 IFG 中断标志位清除
    	  	  	  	  	  	  	  	  	    //BIT3 on Port 1 can be used as Switch2

											
  _BIS_SR(LPM4_bits + GIE);                 // 进入LPM4模式,并使能中断
}

// Port 1 interrupt service routine
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
  Delay_ms(10); //延时10ms进行按键消抖
  if(!(BIT3 & P1IN))    //如果P1.3为低电平表示按键被按下,LED1状态翻转
  {
     P1OUT ^= BIT0;
  }
  while(!(BIT3 & P1IN));        //中断程序持续直到检测到按键未被按下
  P1IFG &= ~BIT3;                           // P1.3 IFG 中断标志位清除
}

该程序虽然进行了按键消抖,但在中断程序中较长时间占用了CPU资源。其实还有其他方法可以实现,例如利用定时器定时间间隔检测按键状态后再进入中断。

sao话一下

如果你喜欢上一匹马,不要试图追上它,你肯定追不上。你应该试着去种草种花,等到草长莺飞的季节,这匹马自然会回来找你。 如果这匹马就是不回来找你呢? 没关系,你有了花和草,有了独特的魅力和资本,这匹马不来,别的马会来。
——《余香》


  1. 参考用户指南38~40页,简要概括为用户可以根据需要选择需要工作的模块,禁用暂时无用的模块从而降低功耗。 ↩︎

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值