分享

单片机C语言任何位置跳转到任何指定地址

 guitarhua 2018-03-27

用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)(); 

  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多