4680|8

7

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

[MSP430launch pad]中断中全局变量莫名其妙被改变 [复制链接]

本帖最后由 魔方奇才 于 2014-7-22 18:35 编辑

/*
*  ======== ADC10 Interrupt Service Routine ========
*/
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR_HOOK(void)
{
        unsigned int temp;
        float Rpt,T;
        unsigned char i;
        ADC10CTL0 &= ~ADC10IFG;
        temp = ADC10MEM;
        Rpt = (0.02659*temp+95.2381)/(0.9524-temp*1.3297*0.00001);                          //参考电压为2.5V时的转换公式
        T = (sqrt(0.39083*0.39083+0.000231*(100-Rpt))-0.39083)/(-0.0001155);
                i=T;
                LCD_pos(6,1);
                write_num( i );                                                           //温度显示
                i = T*10;
                i %= 10;
                write_string(".");
                write_data(0x30+i);
                i=0;
}



我在调试后发现经过ADC10的终端服务程序后,全局变量POINT的值被莫名奇妙的改了,当我注释掉ADC中断服务里面的代码后,正常运行,我怀疑是和math.h的两个函数有关,在此程序中并未涉及到关于POINT的语句,求解问题出在何处,下面是全部的程序代码:
#include
#include
#include"lcd12864.h"
#define START  BIT3            //开始
#define STOP    BIT4           //停止
#define ADD     BIT5                        //加一
#define DEC      BIT6                        //减一
#define SELECT BIT7                        //选择
unsigned int T_set;
unsigned char POINT=0,aa;


void Init(void);
void UI(void);
void KEYIE(void);
void BCSINIT(void);
void ADC10INIT(void);
void GPIOINIT(void);
void TIMERINIT(void);
void SYSTEMINIT(void);
void WDTINIT(void);

int main(void)
{
    Init();
        while(1)
        {
                ADC10CTL0 |= ADC10SC;
                delay_ms(1000);
                aa=POINT;
        }
}
void Init()
{
        WDTINIT();
        GPIOINIT();
        BCSINIT();
        ADC10INIT();
        TIMERINIT();
        SYSTEMINIT();
        LCD_Init();
        UI();
        KEYIE();
}
void WDTINIT(void)
{
        WDTCTL = WDTPW | WDTHOLD;
}
void SYSTEMINIT(void)
{
        /* Clear oscillator fault flag with software delay */
            do
            {
                // Clear OSC fault flag
                IFG1 &= ~OFIFG;

                // 50us delay
                __delay_cycles(50);
            } while (IFG1 & OFIFG);
            __bis_SR_register(GIE);
}
void TIMERINIT(void)
{
        TA0CCTL1 = CM_0 | CCIS_0 | OUTMOD_7;
        TA0CCR0 = 999;
        TA0CCR1 = 499;
        TA0CTL = TASSEL_2 | ID_0 | MC_0;                                //MC_0=刚开始时不打开计时器
}
void GPIOINIT(void)
{
            P1OUT = 0;
            P1SEL = BIT2;
            P1DIR = BIT0 | BIT2 | BIT5 | BIT6 | BIT7;
            P1IES = 0;
            P1IFG = 0;
            P2OUT = BIT3 | BIT4 | BIT5 | BIT6 | BIT7;
            P2SEL &= ~(BIT6 | BIT7);
            P2DIR = 0;
            P2REN = BIT3 | BIT4 | BIT5 | BIT6 | BIT7;
            P2IES = BIT3 | BIT4 | BIT5 | BIT6 | BIT7;
            P2IFG = 0;
}
void ADC10INIT(void)
{
        ADC10CTL0 &= ~ENC;
        ADC10CTL0 = ADC10IE | ADC10ON | REFON | REF2_5V | ADC10SHT_3 | SREF_1;
        ADC10CTL1 = CONSEQ_0 | ADC10SSEL_1 | ADC10DIV_7 | SHS_0 | INCH_1;
        ADC10AE0 = 0x2;
        __delay_cycles(30000);
        ADC10CTL0 |= ENC;
}

void UI()
{
        LCD_write(1,2,"温度的测量与控制");
        LCD_flash(1);
        write_com(0x01);
        LCD_write(1,1,"当前温度:");
        LCD_write(1,2,"设置温度:");
        LCD_write(1,3,"设置时间:");
        LCD_write(7,1,".");
        LCD_write(7,1,".");
        LCD_write(8,1,"℃");
        LCD_write(8,2,"℃");
        LCD_write(8,3," s");
        //LCD_write(1,4,"");                                           //预留最后一行
}

void KEYIE()
{
        //P2IES = 0xf8;
        P2IFG = 0;
        P2IE = 0XF8;                        //        开启P2.3~P2.7的按键中断
}

void BCSINIT(void)
{
        BCSCTL2 = SELM_0 | DIVM_0 | DIVS_0;
        if (CALBC1_1MHZ != 0xFF) {
                /* Follow recommended flow. First, clear all DCOx and MODx bits. Then
                 * apply new RSELx values. Finally, apply new DCOx and MODx bit values.
                 */
                DCOCTL = 0x00;
                BCSCTL1 = CALBC1_1MHZ;      /* Set DCO to 1MHz */
                DCOCTL = CALDCO_1MHZ;
            }
        BCSCTL1 |= XT2OFF | DIVA_0;
        BCSCTL3 = XT2S_0 | LFXT1S_2 | XCAP_1;
}
/*
*  ======== PORT2 Interrupt Service Routine ========
*/
#pragma vector=PORT2_VECTOR
__interrupt void PORT2_ISR_HOOK(void)
{
        P2IE &= ~0xf8;                        //关按键中断
//START键
    if(P2IFG&START)
    {
            delay_ms(5);
            if(!(P2IN&START))
            {
                    P1OUT ^= BIT0;
            }
    }
//STOP键
    if(P2IFG&STOP)
    {
            delay_ms(5);
            if(!(P2IN&STOP))
            {
                    __delay_cycles(1);
            }
    }
//ADD键
    if(P2IFG&ADD)
    {
            delay_ms(5);
            if(!(P2IN&ADD))
            {

            }
    }
//DEC键
    if(P2IFG&DEC)
    {
            delay_ms(5);
            if(!(P2IN&DEC))
            {

            }
    }
//SELECT键
    if(P2IFG&SELECT)
    {
            delay_ms(5);
            if(!(P2IN&SELECT))
            {
                    POINT++;
                    __delay_cycles(1);
            }
    }

    P2IFG = 0;
    P2IE |= 0xf8;                        //开按键中断
}

/*
*  ======== ADC10 Interrupt Service Routine ========
*/
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR_HOOK(void)
{
        unsigned int temp;
        float Rpt,T;
        unsigned char i;
        ADC10CTL0 &= ~ADC10IFG;
        temp = ADC10MEM;
        Rpt = (0.02659*temp+95.2381)/(0.9524-temp*1.3297*0.00001);                          //参考电压为2.5V时的转换公式
        T = (sqrt(0.39083*0.39083+0.000231*(100-Rpt))-0.39083)/(-0.0001155);        
                i=T;
                LCD_pos(6,1);
                write_num( i );                                                           //温度显示
                i = T*10;
                i %= 10;
                write_string(".");
                write_data(0x30+i);
                i=0;
}


最新回复

刚才我又仔细的想了一下,感觉按键中断效率更高  详情 回复 发表于 2014-7-24 22:32
 
点赞 关注

回复
举报

6040

帖子

202

TA的资源

版主

沙发
 
一切的bug需要debug

点评

刚刚发现注释掉T = (sqrt(0.39083*0.39083+0.000231*(100-Rpt))-0.39083)/(-0.0001155); 这句话后就正常了,不过不理解,还有Rpt的值Rpt = (0.02659*temp+95.2381)/(0.9524-(float)temp*1.3297*0.00001); 和我在另  详情 回复 发表于 2014-7-22 18:57
 
 

回复

7

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
lcofjp 发表于 2014-7-22 18:52
一切的bug需要debug

刚刚发现注释掉T = (sqrt(0.39083*0.39083+0.000231*(100-Rpt))-0.39083)/(-0.0001155);
这句话后就正常了,不过不理解,还有Rpt的值Rpt = (0.02659*temp+95.2381)/(0.9524-(float)temp*1.3297*0.00001);  和我在另一个工程里面算出来的不一样,这里面是2.204052e-39,根本不可能是这个值,但是由它算出的T的值却又是对的,难道中断服务程序有BUG不能进行大运算?

点评

有可能是栈溢出了,导致的全局变量被覆盖了。  详情 回复 发表于 2014-7-22 20:19
 
 
 

回复

6040

帖子

202

TA的资源

版主

4
 
魔方奇才 发表于 2014-7-22 18:57
刚刚发现注释掉T = (sqrt(0.39083*0.39083+0.000231*(100-Rpt))-0.39083)/(-0.0001155);
这句话后就正常 ...

有可能是栈溢出了,导致的全局变量被覆盖了。

点评

我也这么觉得,是不是这个小数的乘除法很占用空间???  详情 回复 发表于 2014-7-22 20:30
 
 
 

回复

7

帖子

0

TA的资源

一粒金砂(中级)

5
 
lcofjp 发表于 2014-7-22 20:19
有可能是栈溢出了,导致的全局变量被覆盖了。

我也这么觉得,是不是这个小数的乘除法很占用空间???

点评

主要是RAM太小了。  详情 回复 发表于 2014-7-22 20:44
 
 
 

回复

6040

帖子

202

TA的资源

版主

6
 
魔方奇才 发表于 2014-7-22 20:30
我也这么觉得,是不是这个小数的乘除法很占用空间???

主要是RAM太小了。

点评

昨天又搞了一晚上,发现是一个我自己写的函数write_num()出的问题,注释掉这个函数,RAM占用瞬间下降一半,GG,果断删掉了这个函数,瞬间恢复正常!!!!!  详情 回复 发表于 2014-7-23 10:44
 
 
 

回复

7

帖子

0

TA的资源

一粒金砂(中级)

7
 
lcofjp 发表于 2014-7-22 20:44
主要是RAM太小了。

昨天又搞了一晚上,发现是一个我自己写的函数write_num()出的问题,注释掉这个函数,RAM占用瞬间下降一半,GG,果断删掉了这个函数,瞬间恢复正常!!!!!
 
 
 

回复

52

帖子

0

TA的资源

一粒金砂(中级)

8
 
楼主,你好,按键的用中断写,有什么好处吗?我写按键的时候,都是一些IO输出低电平,一些IO处于高阻,通过检测PxIN来判断按键按下。希望楼主赐教!
 
 
 

回复

52

帖子

0

TA的资源

一粒金砂(中级)

9
 
刚才我又仔细的想了一下,感觉按键中断效率更高
 
 
 

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

查找数据手册?

EEWorld Datasheet 技术支持

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

 
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
快速回复 返回顶部 返回列表