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

2019-03-24 11:14发布

本帖最后由 魔方奇才 于 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 <msp430.h>
#include<math.h>
#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;
}


此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
8条回答
lcofjp
1楼-- · 2019-03-24 21:52
 精彩回答 2  元偷偷看……
魔方奇才
2楼-- · 2019-03-25 02:34
< :TI_MSP430_内容页_SA7 -->
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不能进行大运算?
lcofjp
3楼-- · 2019-03-25 05:47
魔方奇才 发表于 2014-7-22 18:57
刚刚发现注释掉T = (sqrt(0.39083*0.39083+0.000231*(100-Rpt))-0.39083)/(-0.0001155);
这句话后就正常 ...

有可能是栈溢出了,导致的全局变量被覆盖了。
魔方奇才
4楼-- · 2019-03-25 10:00
 精彩回答 2  元偷偷看……
lcofjp
5楼-- · 2019-03-25 11:50
魔方奇才 发表于 2014-7-22 20:30
我也这么觉得,是不是这个小数的乘除法很占用空间???

主要是RAM太小了。
魔方奇才
6楼-- · 2019-03-25 15:19
lcofjp 发表于 2014-7-22 20:44
主要是RAM太小了。

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

一周热门 更多>

相关问题

    相关文章