YSL2333

  在我对430的学习认识过程中,中断是单片机不可或缺的一部分,也是单片机性能的一种体现。MSP430的中断优先级按所在的向量的大小排列,中断向量地址越高优先级就越大,但是默认的MSP430是不能中断嵌套的,要想在执行某一中断时能够响应更高优先级的中断,需要在低优先级的中断程序中手动打开全局中断便能位,因为在进入中断服务子程序时全局中断便能位被清零,即禁止响应其它中断。

 

  首先我们应当先认识单片机的中断优先级这一特性,在430的手册里是这样说的“The nearer a module is to the CPU/NMIRS, the higher the priority”,翻译过来就是说离CPU/NMIRS越近,优先级就越高,也就是在下图中最上面的离CPU最近,其优先级也就最高,其次下面中断向量从上到下依次降低。如果看不出来,还可以对中断向量的地址值进行判断,430的中断向量表从地址值0xFFC0开始至0XFFFF结束,一共有32个表项(每个中断向量对应2byte),0XFFCO对应的中断向量的优先级是最低的,0XFFFE对应的中断向量的优先级是最高的,也就是从0xFFCO开始至0xFFFF,32个中断优先级由低至高,其中最高的0xFFFE为系统重置向量。这样就很容易弄清楚各中断的优先级了。

MSP430的中断可分为三大类:

1、系统重置(POR和PUC)

2、不可屏蔽中断(NMI):不可屏蔽中断的中断向量为0xFFFC,NMI中断的使能位不是由通用中断使能GIE来控制,而是由特殊的标志位来控制(NMIIE, ACCVIE, OFIE),当一个NMI中断发生,所有的NMI中断使能都自动复位。程序从储存在NMI中断向量(0FFFCH)开始执行,用户软件必须在NMI中断中对允许的NMI中断重新使能。当多个中断同时响应时应当按中断的优先级进行响应。

3、可屏蔽中断:可屏蔽中断的中断来源于具有中断能力的外围模块,包括看门狗定时器工作在定时器模式时溢出产生的中断。每一个中断都可以被自己的中断控制位屏蔽,也可以由全局中断控制位屏蔽。多个中断请求发生时,响应最高优先级中断。响应中断时,MSP430会将不可屏蔽中断控制位SR.GIE复位。因此,一旦响应了中断,即使有优先级更高的可屏蔽中断出现,也不会中断当前正在响应的中断,去响应另外的中断。但SR.GIE复位不影响不可屏蔽中断,所以仍可以接受不可屏蔽中断的中断请求。

 

优先级顺序从高到低为:
    PORT2_VECTOR (1 * 2u) /* 0xFFE2 Port 2 */
    PORT1_VECTOR (4 * 2u) /* 0xFFE8 Port 1 */
    TIMERA1_VECTOR (5 * 2u) /* 0xFFEA Timer A CC1-2, TA */
    TIMERA0_VECTOR (6 * 2u) /* 0xFFEC Timer A CC0 */
    ADC_VECTOR (7 * 2u) /* 0xFFEE ADC */
    USART0TX_VECTOR (8 * 2u) /* 0xFFF0 USART 0 Transmit */
    USART0RX_VECTOR (9 * 2u) /* 0xFFF2 USART 0 Receive */
    WDT_VECTOR (10 * 2u) /* 0xFFF4 Watchdog Timer */
    COMPARATORA_VECTOR (11 * 2u) /* 0xFFF6 Comparator A */
   TIMERB1_VECTOR (12 * 2u) /* 0xFFF8 Timer B CC1-2, TB */
   TIMERB0_VECTOR (13 * 2u) /* 0xFFFA Timer B CC0 */
   NMI_VECTOR (14 * 2u) /* 0xFFFC Non-maska××e */
   RESET_VECTOR (15 * 2u) /* 0xFFFE Reset [Highest Priority] */

 

MSP430中断的响应过程:

首先,当然是中断发生对应的标志为置1。这个时候的过程我详述下,其实是翻译的用户手册但是还是了解下好。

1. CPU会执行完当期的指令。

2. 指向下一条指令的PC被压栈。

3. 状态寄存器SR压栈。

4. 选择最好优先级的中断进行服务。

5. 单源中断的中断标志位会被自动清零,这个地方需要小心下P1,P2这样的中断标志位不会自动清零,因为P1、P2的IO中断属于多源中断,就是说P1或者P2的8个IO对应到了一个中断向量上,单片机知道是P1或者P2发生了中断,无论是P1的哪一个IO发生的都会指向P1的中断向量,P2也是一样的,所以需要在代码中手动清零。

6. 状态寄存器SR被清零,将会终止任何低功耗状态,并且全局中断使能被关闭(GIE)。这个地方与51很是有些不同,430响应了中断后会关闭全局中断使能,不会响应任何其他的中断包括优先级高的,就是说默认状态下是没有中断嵌套的,若用到中断嵌套的话需要使用_EINT()打开全局中断。

7. 中断向量被装载到PC,开始执行中断服务函数。

以上是整个中断的接收过程,比较重要的地方我用彩色字体标出了。

中断返回就相对简单些,中断服务函数会由RETI这条指令返回,SR被弹出,单片机恢复到中断前的状态,PC也被弹出,继续执行指令。

第三,开中断和中断服务函数。

这个是让我在项目中纠结过的地方,也请各位小心。

MSP430一旦开了外设的中断,比如SPI的接收中断。

在SPI的接收中断被使能,单片机一旦发现SPI接收标志置位,就会装载中断向量,但是我们如果没有用到SPI的接收中断,会怎样呢?由于没用到,所有就没有写SPI接收中断的服务函数,此时中断向量里指向中断服务函数地址值是啥?是全0。CPU从0-01FFh取指令,只会发生一件事。PUC,上电清零。接着PC会装载0xFFFE中断向量的内容,也就是复位向量,程序会跳转到给IAR我们做的启动代码。程序再往下执行会执行到我们编写的代码的main()的第一句。这样悲剧就诞生了,荡机了!!!!

所以我在这希望初学430的朋友对于中断,未使用的就不要使能。使能的就一定要写中断服务函数,哪怕是空函数!

 

实现中断嵌套需要注意以下几点:
1、430默认的是关闭中断嵌套的,除非你在一个中断程序中再次开总中断EINT;

2、当进入中断程序时,只要不在中断中再次开中断,则总中断是关闭的,此时来中断不管是比当前中断的优先级高还是低都不执行;

3、若在中断A中开了总中断,则可以响应后来的中断B(不管B的优先级比A高还是低),B执行完再继续执行A。注意:进入中断B后总中断同样也会关闭,如果B中断程序执行时需响应中断C,则此时也要开总中断,若不需响应中断,则不用开中断,B执行完后跳出中断程序进入A程序时,总中断会自动打开;

4、若在中断中开了总中断,后来的中断同时有多个,则会按优先级来执行,即中断优先级只有在多个中断同时到来时才起做用!中断服务不执行抢先原则;

5、对于单源中断,只要响应中断,系统硬件自动清中断标志位,对于TA/TB定时器的比较/捕获中断,只要访问TAIV/TBIV,标志位倍被自动清除;

  对于多源中断要手动清标志位,比如P1/P2口中断,要手工清除相应的标志,如果在这种中断用"EINT();"开中断,而在打开中断前没有清标志,就会有相同的中断不断嵌入,而导致堆栈溢出引起复位,所以在这类中断中必须先清标志再打开中断开关。

 

参考原博客链接:

https://www.cnblogs.com/yibanshouxi/p/4115758.html

https://www.cnblogs.com/juju/archive/2012/04/26/2471322.html

https://www.cnblogs.com/jinsedemaitian/p/5589066.html

http://bbs.eeworld.com.cn/thread-1130871-1-1.html

https://blog.csdn.net/QAQWE/article/details/84521152

分类:

技术点:

相关文章:

  • 2021-09-07
  • 2021-07-24
  • 2021-12-20
  • 2021-09-27
  • 2022-03-01
  • 2021-06-01
  • 2021-11-21
  • 2022-12-23
猜你喜欢
  • 2022-02-07
  • 2021-08-22
  • 2022-12-23
  • 2022-01-17
  • 2021-12-07
  • 2022-12-23
  • 2021-11-30
相关资源
相似解决方案