堆栈的问题

miko2007   2008-3-12 15:01 楼主
哪位高手帮我解答一下用F149芯片运行程序出现下面的问题:
Wed Mar 12 14:54:19 2008: The stack pointer for stack 'Stack' (currently Memory:0x9AE) is outside the stack range (Memory:0x9B0 to Memory:0xA00)

回复评论 (8)

如果你的stack是默认设置的
可能是你的RAM使用超过149芯片的RAM
也可能是你的局部变量超过2K了
尽量减少全局变量、局部变量、函数的嵌套不要太多
点赞  2008-3-12 15:35
能麻烦你帮我看下下面的程序,谢谢了。
就是运行下面的程序出现上面的程序:
#include <msp430x14x.h>

char nADC_Flag;
int nADC_Count;
int ADC_BUF[40];

void Init_CLK(void);
void Init_ADC(void);
void Init_TimerA(void);

void Init_ADC(void)
{
//设置P6.0为模拟输入通道
P6SEL = 0X01;
//设置ENC为0,从而修改ADC12寄存器的值
ADC12CTL0 &= ~(ENC);
//设置参考电压分别为××SS和××CC,输入通道为A0
ADC12MCTL0 = INCH_0 + EOS;
//转换的起始地址为:ADCMEM0
ADC12CTL1 = 0X00;
ADC12CTL1 += CSTARTADD_0;
//采样脉冲由采用定时器产生
ADC12CTL1 += SHP;
//转换模式为:多通道、多次转换
ADC12CTL1 += CONSEQ_1;
//内部时钟源
ADC12CTL1 += ADC12SSEL_0;
//时钟分频为1
ADC12CTL1 += ADC12DIV_0;

ADC12CTL0 += 8 * 0x100;
ADC12CTL0 += MSC;
ADC12CTL0 += ADC12ON;

ADC12IE = 0;
//关闭各个通道的转换中断
ADC12IE |= 0X00;
//使能ADC转换
ADC12CTL0 |= ENC;
return;
}
void Init_TimerA(void)
{
// 选择SMCLK,清除TAR
TACTL = TASSEL1 + TACLR;
// 1/8 SMCLK
TACTL += ID1;
TACTL += ID0;
// CCR0 中断允许
CCTL0 = CCIE;

// 时间间隔为 500us
CCR0 = 500;
// 增记数模式
TACTL |= MC0;
return;
}
void Init_CLK(void)
{
unsigned int i;
BCSCTL1 = 0X00; //将寄存器的内容清零
//XT2震荡器开启
//LFTX1工作在低频模式
//ACLK的分频因子为1

do
{
IFG1 &= ~OFIFG; // 清除OSCFault标志
for (i = 0x20; i > 0; i--);
}
while ((IFG1 & OFIFG) == OFIFG); // 如果OSCFault =1

BCSCTL2 = 0X00; //将寄存器的内容清零
BCSCTL2 += SELM1; //MCLK的时钟源为TX2CLK,分频因子为1
BCSCTL2 += SELS; //SMCLK的时钟源为TX2CLK,分频因子为1
}

interrupt [TIMERA0_VECTOR] void TimerA_ISR(void)
{
int results;
// 关闭转换
ADC12CTL0 &= ~ENC;
// 读出转换结果
results = ADC12MEM0;
ADC_BUF[nADC_Count] = results;
// 计数器加1
nADC_Count += 1;
// 采集完40个点
if(nADC_Count == 40)
{
// 设置标志
nADC_Flag = 1;
// 计数器清0
nADC_Count = 0;
}
// 开启转换
ADC12CTL0 |= ENC + ADC12SC;
}

void main(void)
{
int ADC_BUF_Temp[40];
int i;
// 关闭看门狗
WDTCTL = WDTPW + WDTHOLD;
// 关闭中断
_DINT();

// 初始化
Init_CLK();
Init_ADC();
Init_TimerA();

// 打开中断
_EINT();
// 循环处理
for(;;)
{
if(nADC_Flag == 1)
{
nADC_Flag = 0;
for(i = 0;i < 40;i++)
{
ADC_BUF_Temp[i] = ADC_BUF[i];
}
}
}
}


像该句要不要加啊?
interrupt [TIMERA0_VECTOR]
点赞  2008-3-12 16:40
我运行程序怎么没出现那种错误
中断的表达式是这样的
#pragma vector = TIMERA0_VECTOR
__interrupt void TimerA_ISR(void)
我不知道你是怎么编译通过的
点赞  2008-3-12 17:12
我从新改过了,还是出现这种问题:Wed Mar 12 14:54:19 2008: The stack pointer for stack 'Stack' (currently Memory:0x9AE) is outside the stack range (Memory:0x9B0 to Memory:0xA00):
是不是IAR中药设置什么?
点赞  2008-3-13 21:19
我粗略看了一下你的程序
因为你的变量ADC_BUF_Temp没有被实际应用
只是不停地赋值
你把这变量屏蔽掉
换成这样应该就不会出现那错误了

if(nADC_Flag == 1)
{
nADC_Flag = 0;
P1OUT = ADC_BUF[0];
/* for(i = 0;i < 40;i++)
{
ADC_BUF_Temp[i] = ADC_BUF[i];
}*/
}

而且编程的时候最好警告和错误都没有再仿真
不然仿真就有可能出现意想不到的错误
点赞  2008-3-14 09:15
版主,不好 意思。
经过修改,还是同样的问题。不知版主能不能帮我运行一下,把整个程序贴上好吗?
谢谢了 !
点赞  2008-3-15 14:08
程序如下:
#include <msp430x14x.h>

char nADC_Flag;
int nADC_Count;
int ADC_BUF[40];

void Init_CLK(void);
void Init_ADC(void);
void Init_TimerA(void);


void main()
{
// int ADC_BUF_Temp[40];
// int i;
// 关闭看门狗
WDTCTL = WDTPW + WDTHOLD;
// 关闭中断
_DINT();

// 初始化
Init_CLK();
Init_ADC();
Init_TimerA();

// 打开中断
_EINT();
// 循环处理
while(1)
{
if(nADC_Flag == 1)
{
nADC_Flag = 0;
P1OUT = ADC_BUF[0];
/* for(i = 0;i < 40;i++)
{
ADC_BUF_Temp[i] = ADC_BUF[i];
}*/
}
}
}

void Init_ADC(void)
{
//设置P6.0为模拟输入通道
P6SEL = 0X01;
//设置ENC为0,从而修改ADC12寄存器的值
ADC12CTL0 &= ~(ENC);
//设置参考电压分别为××SS和××CC,输入通道为A0
ADC12MCTL0 = INCH_0 + EOS;
//转换的起始地址为:ADCMEM0
ADC12CTL1 = 0X00;
ADC12CTL1 += CSTARTADD_0;
//采样脉冲由采用定时器产生
ADC12CTL1 += SHP;
//转换模式为:多通道、多次转换
ADC12CTL1 += CONSEQ_1;
//内部时钟源
ADC12CTL1 += ADC12SSEL_0;
//时钟分频为1
ADC12CTL1 += ADC12DIV_0;

ADC12CTL0 += 8 * 0x100;
ADC12CTL0 += MSC;
ADC12CTL0 += ADC12ON;

ADC12IE = 0;
//关闭各个通道的转换中断
ADC12IE |= 0X00;
//使能ADC转换
ADC12CTL0 |= ENC;
// return;
}
void Init_TimerA(void)
{
// 选择SMCLK,清除TAR
TACTL = TASSEL1 + TACLR;
// 1/8 SMCLK
TACTL += ID1;
TACTL += ID0;
// CCR0 中断允许
CCTL0 = CCIE;

// 时间间隔为 500us
CCR0 = 500;
// 增记数模式
TACTL |= MC0;
// return;
}
void Init_CLK(void)
{
unsigned int i;
BCSCTL1 = 0X00; //将寄存器的内容清零
//XT2震荡器开启
//LFTX1工作在低频模式
//ACLK的分频因子为1

do
{
IFG1 &= ~OFIFG; // 清除OSCFault标志
for (i = 0x20; i > 0; i--);
}
while ((IFG1 & OFIFG) == OFIFG); // 如果OSCFault =1

BCSCTL2 = 0X00; //将寄存器的内容清零
BCSCTL2 += SELM1; //MCLK的时钟源为TX2CLK,分频因子为1
BCSCTL2 += SELS; //SMCLK的时钟源为TX2CLK,分频因子为1
}

#pragma vector = TIMERA0_VECTOR //P1 4
__interrupt void TimerA_ISR(void)
{
int results;
// 关闭转换
ADC12CTL0 &= ~ENC;
// 读出转换结果
results = ADC12MEM0;
ADC_BUF[nADC_Count] = results;
// 计数器加1
nADC_Count += 1;
// 采集完40个点
if(nADC_Count == 40)
{
// 设置标志
nADC_Flag = 1;
// 计数器清0
nADC_Count = 0;
}
// 开启转换
ADC12CTL0 |= ENC + ADC12SC;
}
点赞  2008-3-17 09:02
十分感谢!斑竹
点赞  2008-3-27 20:06
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复