AVR单片机程序调用堆栈控制使用心得

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

A VR单片机程序调用堆栈控制使用心得

堆栈指针(SP)是一个指示堆栈顶部地址的16位寄存器。在ICCA VR中,它被用作指向硬件堆栈的堆栈指针。A VR单片机上电复位后,SP指针的初始值为0x0000,由于A VR 单片机的堆栈是向下生长的(从高地址向低地址生长),所以系统程序一开始必须对堆栈指针SP进行初始化,即将SP的值设为数据存储空间的最高地址。ICCA VR编译器在链接C 程序文件的时候,会自动在程序头链入startup文件。startup文件里面的程序将会去做初始化SP指针的工作。

Startup文件没有办法通过手动编程来修改,只能通过编译器ICCA VR设置来修改,修改堆栈的设置通过下面的两个步骤来实现:

默认的Return Stack Size大小是16。

在程序设计中出现的问题:

void main()

{

displayboat(1);

}

void displayboat(char i)

{ int td;

boat[i].x=(char)(120+boat[i].log*showk);

boat[i].y=(char)(120+boat[i].lang*showk);

td=(int)(boat[i].d+boat[i].turn);

showboat(boat[i].x,boat[i].y,td,i);

boat[i].x5=2*boat[i].x1-boat[i].x;

boat[i].y5=2*boat[i].y1-boat[i].y;

showboat(boat[i].x,boat[i].y,boat[i].d,i);

boat[i].x4=2*boat[i].x1-boat[i].x;

boat[i].y4=2*boat[i].y1-boat[i].y;

linex(boat[1].x1,boat[1].y1,boat[1].x2,boat[1].y2,7);

linex(boat[1].x1,boat[1].y1,boat[1].x3,boat[1].y3,7);

linex(boat[1].x2,boat[1].y2,boat[1].x3,boat[1].y3,7);

linex(boat[1].x,boat[1].y,boat[1].x4,boat[1].y4,7);

xuline(boat[1].x,boat[1].y,boat[1].x5,boat[1].y5,7); }

程序调用displayboat计算几个作标值,并通过linex和xuline两个直线函数将这些点连起来,但是该程序在运行的时候出现错误,在displayboat里面的linex和xuline两个子函数没有正确运行,画的直线乱跑,通过修改成以下程序后:

void main()

{

displayboat(1);

linex(boat[1].x1,boat[1].y1,boat[1].x2,boat[1].y2,7);

linex(boat[1].x1,boat[1].y1,boat[1].x3,boat[1].y3,7);

linex(boat[1].x2,boat[1].y2,boat[1].x3,boat[1].y3,7);

linex(boat[1].x,boat[1].y,boat[1].x4,boat[1].y4,7);

xuline(boat[1].x,boat[1].y,boat[1].x5,boat[1].y5,7);

}

void displayboat(char i)

{

int td;

boat[i].x=(char)(120+boat[i].log*showk);

boat[i].y=(char)(120+boat[i].lang*showk);

td=(int)(boat[i].d+boat[i].turn);

showboat(boat[i].x,boat[i].y,td,i);

boat[i].x5=2*boat[i].x1-boat[i].x;

boat[i].y5=2*boat[i].y1-boat[i].y;

showboat(boat[i].x,boat[i].y,boat[i].d,i);

boat[i].x4=2*boat[i].x1-boat[i].x;

boat[i].y4=2*boat[i].y1-boat[i].y;

}

即把调用画直线函数调到主函数,减少了函数调用的层数,通过这样的修改程序正常运行,可以得出结果,按照默认的Return Stack Size,函数调用的堆栈不够用,会出现程序调用错误。

尝试修改Return Stack Size的值来运行修改前的函数,我试过将Return Stack Size改为32,结果程序连基本的函数运行都出错,把Return Stack Size改为18、17程序的运行结果和16类似,但是略有区别,问题还是出现在linex和xuline两个函数的调用问题上。

通过对比Return Stack Size值为16、17、18的显示结果,感觉Return Stack Size值为16的显示结果比较理想,因此尝试将Return Stack Size改为8,结果程序正常运行,linex和unline 都正常的画出直线来。

结果分析:Return Stack Size的定义出现岐义,开始的时候将Return Stack Size理解为返回堆栈的总大小,即用来存放堆栈的地址范围大小,所以有了将Return Stack Size改大的行为,后来经过尝试将Return Stack Size改小后程序正常运行,便重新理解了Return Stack Size 的含义:Return Stack Size为返回堆栈值的大小,在堆栈总大小固定的前提下,Return Stack Size越小,可以存放的堆栈指针值越多,可以调用的函数层数也相应增加了,不过这个是针对我自己的程序实践得到的经验,不一定准确。

可能存在的BUG:堆栈寻址能力下载,原来16位可以访问的空间远大于现在的8位地址,日后的程序设计上可能出现程序编译时候的地址寻址出错,如果出现程序单独运行正常

相关文档
最新文档