单片机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)(); 

 


  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值