单片机C语言任何位置跳转到任何指定地址
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
单片机C语言任何位置跳转到任何指定地址
用C语言写的程序为求模块化,一般函数数量较多,函数调用的嵌套层数也多,要从一个较深的嵌套立刻跳出到主函数,是非常困难的。
用break或者return是跳不出来的,一般的解决方法或是使用C51的库函数setjmp()和longjmp()实现长跳转,但是这两个函数在中断函数内部是无能为力的;再或是在C函数中嵌入汇编。
虽然用汇编指令可以实现程序的长距离跳转,但是这种方法的调试过程十分烦琐,而且程序的可移植性差。
对于习惯用C51编程而不想用汇编的设计者,该部分程序是一个难题。
我们可以利用keil软件的绝对地址跳转,((void(code *)(void))0x00)(); keil软件编译时会转换成jmp 0x00,就跳到指定的绝对地址了;
但这又有些不方便,我们想跳到任何我们想跳到的地方去,而程序一改动,绝对地址又会变,所以我们需要一个函数能够取得我们要跳转的绝对地址,但又不能直接读取程序计数器PC(绝对地址);
方法还是有的:因为单片机c语言调用函数或者进入中断时,都要线把PC压入堆栈去,而SP值是可以读的,因此调用函数,把堆栈里的值(PC)读出保存,作为跳转的据对地址;例程如下:ff0()
{
....................................
JmpAddr=Get_Jmp_Addr();//------------取要跳转地址
.........................................
}
long Get_Jmp_Addr(void)
{ long address;
address=*((unsigned char *)SP);
address <<= 8;
address+=*((unsigned char *)(SP-1));
return address+5;
}
ff1()
{
.........................
((void(code *)(void))JmpAddr)();
................................
}
希望对大家有帮助!!
另转其实uboot里面就有例子,不过今天看到一个TI的,也贴出来,实际差不了多少:
定义:
Uint32 gEntryPoint;
static void (*APPEntry)(void);
用法:
APPEntry = (void (*)(void)) gEntryPoint;
(*APPEntry)();。