10194|19

5015

帖子

12

TA的资源

裸片初长成(初级)

楼主
 

MSP430的可屏蔽中断 [复制链接]

    中断很大程度上体现了一款单片机的性能,从这一点将MSP430在中断方面做得很不错,主要是提供了非常丰富的中断源,基本的有IO中断,定时器中断和一些接口中断(SPI,UART,I2C)等等。
    现在我就谈谈关于MSP430中断的一些特性,主要是在项目经历中感觉比较有用的问题,跟大家分享下。
    第一,MSP430中断的优先级。
    MSP430支持中断优先级,但是优先级的高低怎么获知呢?它的用手手册上有个很有意思的说法,我原文引用过来“The nearer a module is to the CPU/NMIRS, the higher the priority”,翻译过来就是说离CPU/NMIRS越近,优先级就越高。那我们怎么知道那个模块离CPU近啊,看datasheet给的框图?总觉得这不可能让一个做电子的人放心,比如框图在中距CPU一样进,那怎么区分呢?所以我们有另外一个更可靠的办法,IAR为每一款型号的430都提供了对应的头问题,只靠看中断向量地址就可以知道了。430的中断向量表从地址值0xFFC0开始至0XFFFF结束,一共有32个表项(每个中断向量对应2byte),0XFFCO对应的中断向量的优先级是最顶的,0XFFFE对应的中断向量的优先级是最高的,也就是从0xFFCO开始至0xFFFF,32个中断优先级由低至高。这样就很容易弄清楚各中断的优先级了。
  第二,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的朋友对于中断,未使用的就不要使能。使能的就一定要写中断服务函数,哪怕是空函数!
   以上是我在430中断使用中的一些经验,希望对各位有用!
    

最新回复

楼至帖子不错,能帮我看一下我的问题吗 void Uart_Init(void) {         P3SEL |= 0x30;                            // 选择P3.4和P3.5做UART通信端口         P3DIR = 0x10;        UCTL0|= SWRST;                         //开始设置串口            ME1 |= URXE0;                             // 使能USART0的发送和接受         U0CTL |= CHAR;                            // 选择8位字                             UTCTL0 |= SSEL0;                          //选择模块时钟源 ; // UCLK = ACLK         UBR00 = 0xA3;                             // 波特率4800         UBR10 = 0x635750;                             //         UMCTL0 = 0x00;                            // Modulation         UCTL0 &= ~SWRST;                    //设置串口 完毕         IE1 |= URXIE0; } #pragma vector=UART0RX_VECTOR __interrupt void usart0_rx (void) {                                               char ch;                        IE1 &= ~URXIE0; //ES = 0;_DINT();         if((IFG1 & URXIFG0))                 {                ch = RXBUF0;                      if ((ch == '$') && (gps_flag == 0))  //如果收到字符'$',便开始接收                            {                         rev_start = 1;                         rev_stop  = 0;                 }         rev_start = 1;                 if (rev_start == 1)  //标志位为1,开始接收                             {                         rev_buf[num++] =ch;  //字符存到数组中                                    if (ch== '\n')     //如果接收到换行                                    {                                 rev_buf[num] = '\0';                                 rev_start = 0;                                 rev_stop  = 1;                                 gps_flag = 1;                                 num = 0;                         }                 }         }                 IFG1&=~URXIFG0;            IE1 |= URXIE0;            //    _EINT();             } 就是好像进不去中断,总中断在主函数也开了,不知是啥原因  详情 回复 发表于 2012-8-13 11:07
 
点赞 关注(1)

回复
举报

978

帖子

0

TA的资源

一粒金砂(高级)

沙发
 
沙发,不错,有自己的见解
 
 

回复

2万

帖子

74

TA的资源

管理员

板凳
 
谢谢分享 :)
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
个人签名

加油!在电子行业默默贡献自己的力量!:)

 
 

回复

10

帖子

0

TA的资源

一粒金砂(中级)

4
 
学习了!~谢谢分享!~~
 
 
 

回复

6

帖子

0

TA的资源

一粒金砂(中级)

5
 
既系统又简洁,既准确又通俗,好!
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(中级)

6
 
学习了,现在正在整专断这一块儿!
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(中级)

7
 

也在学430谢谢了

好帖 ,顶一下。。。。。。
 
 
 

回复

134

帖子

0

TA的资源

一粒金砂(中级)

8
 
不错。。
 
 
 

回复

49

帖子

0

TA的资源

一粒金砂(中级)

9
 

回复 楼主 wstt 的帖子

hao tie
 
 
 

回复

31

帖子

0

TA的资源

一粒金砂(中级)

10
 
好东西
 
 
 

回复

4

帖子

0

TA的资源

一粒金砂(中级)

11
 
讲得很详细
 
 
 

回复

103

帖子

0

TA的资源

一粒金砂(高级)

12
 
学些了。
430的中断不支持嵌套。如果真的要嵌套,可以手动方式进行。原理与LZ讲述的差不多,具体实现可能需要些注意事项,否则容易跑飞。
 
 
 

回复

122

帖子

0

TA的资源

一粒金砂(高级)

13
 
很好
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(中级)

14
 
学习了,正需要,谢谢分享
 
 
 

回复

4

帖子

0

TA的资源

一粒金砂(初级)

15
 
好东西 顶下!!!!
 
 
 

回复

13

帖子

0

TA的资源

一粒金砂(中级)

16
 
写得好,学习了
 
 
 

回复

147

帖子

0

TA的资源

一粒金砂(高级)

17
 
不错不错,不写中断函数,却触发了中断,会引起复位,对我有用

点评

也是被这样的情况折腾过  详情 回复 发表于 2012-8-12 17:05
 
 
 

回复

5015

帖子

12

TA的资源

裸片初长成(初级)

18
 

回复 17楼 挨紧 的帖子

也是被这样的情况折腾过
 
 
 

回复

147

帖子

0

TA的资源

一粒金砂(高级)

19
 

430的中断向量表从地址值0xFFC0开始至0XFFFF结束,一共有32个表项

刚刚查阅了msp430的用户手册,在g2553的情况就不是从0XFFC0开始的,而是从0XFFE0开始的。原文:(8) 位于地址0FFDEh至0FFC0h的中断矢量在该器件中未使用,可在需要时用于常规程序代码。
 
 
 

回复

45

帖子

0

TA的资源

一粒金砂(中级)

20
 
楼至帖子不错,能帮我看一下我的问题吗
void Uart_Init(void)
{
        P3SEL |= 0x30;                            // 选择P3.4和P3.5做UART通信端口
        P3DIR = 0x10;
       UCTL0|= SWRST;                         //开始设置串口   
        ME1 |= URXE0;                             // 使能USART0的发送和接受
        U0CTL |= CHAR;                            // 选择8位字                    
        UTCTL0 |= SSEL0;                          //选择模块时钟源 ; // UCLK = ACLK
        UBR00 = 0xA3;                             // 波特率4800
        UBR10 = 0x635750;                             //
        UMCTL0 = 0x00;                            // Modulation
        UCTL0 &= ~SWRST;                    //设置串口 完毕
        IE1 |= URXIE0;
}
#pragma vector=UART0RX_VECTOR
__interrupt void usart0_rx (void)
{
                  
              
            char ch;
         
             IE1 &= ~URXIE0; //ES = 0;_DINT();
        if((IFG1 & URXIFG0))
       
        {
               ch = RXBUF0;     
                if ((ch == '$') && (gps_flag == 0))  //如果收到字符'$',便开始接收           
                {
                        rev_start = 1;
                        rev_stop  = 0;
                }
        rev_start = 1;
                if (rev_start == 1)  //标志位为1,开始接收            
                {
                        rev_buf[num++] =ch;  //字符存到数组中           
                        if (ch== '\n')     //如果接收到换行           
                        {
                                rev_buf[num] = '\0';
                                rev_start = 0;
                                rev_stop  = 1;
                                gps_flag = 1;
                                num = 0;
                        }
                }
        }
       
        IFG1&=~URXIFG0;
           IE1 |= URXIE0;            //    _EINT();
           
}
就是好像进不去中断,总中断在主函数也开了,不知是啥原因
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表