SMT人才,半导体人才,防静电人才,PCB人才——电子人才招聘网

SMT网上商城,bga返修,丝印机,点胶机,回流焊

首页 > 软件中心 > 51单片机软件复位代码

51单片机软件复位代码

发表于:2008-11-14 16:59:41   点击: 72

  51单片机软件复位代码     CLR     A     PUSH    ACC     PUSH    ACC     RETI      ;程序又开始从0000H处开始运行,但寄存器内的值不确定!用C51实现软件复位方法1:   //这样声明void(*SoftReset)();//这样调用SoftReset=0;SoftReset();解释:利用函数型指针,使函数型指针指向的函数的入口地址为0。 方法2: 嵌入汇编#pragma asmljmp 0FFF0h;//ljmp 0000h#pragma endasm方法3: 在C51编程过程中,如果调用一个不存在的外部函数,就引起复位。如下程序,编译正常,但执行到 test()处即复位了。我观察了其汇编代码,发现该处的代码为 LCALL C:0000. 所以,一方面可利用这种情况实现软件复位;另一方面要注意如果出现莫名其妙的复位,可能有一个原因是调用了不存在的外部函数,或者包括外部函数体的文件包括到主文件中一起编译。extern void test(void);   //实际并不存在。void main(){unsigned char i;test();     //复位i++;       //无法执行到的指令}方法4:如果有用看门狗,适当时间不喂狗,使狗作用。现单列复位部分如下: main() { unsigned char code rst[]={0xe4,0xc0,0xe0,0xc0,0xe0,0x32}; // 复位代码 (*((void (*)())(rst)))(); // 执行上一行代码,将rst数组当函数调用 } 本来我告诉他嵌入如下代码: clr a push acc push acc reti 结果他却玩了前面哪一段,而数组rst[]中的内容恰恰是上面的汇编机器码,他的做法是将 rst数组的数据当作代码保存,然后采用绝对地址方式指向该数组,将该数组中的代码当作 函数来运行。居然通过了l 首先分析帖子的C语言代码 第一句定义一个数组rst[],数组内数据就是完成复位功能的汇编机器码,具体对应关系 为:clr a == 0xe4、push acc == 0xc0,0xe0、reti ==0x32 第二句是一个函数指针的用法,函数指针用法稍微有点复杂,可参看本人著的书,:),以 下为快速入门讲解。 定义一个返回值是空函数指针的定义形式如下: void (*p) ( ) 当把函数指针赋值后,就能通过函数指针调用函数,调用形式如下, (*p) ( ); 或等价的简化形式: p ( ); 假设rst就是函数指针,则如下调用形式就可以令单片机复位再起。 (*rst ) ( ); 但可惜,rst不是函数指针,而是数组名,虽然两者都是地址,但不可直接调用数组名。 如同把char型变量a赋值给int型变量b,(int) 表示强制类型转换: b = (int) a 函数指针的强制类型转换公式如下(C语言的哲学是定义形式和使用一致): ( (void (*)() ) rst 这样经过转换后的rst就可以当作函数指针使用了,简单的调用形式如下: #define K ( (void (*)( ) ) rst (*K) ( ) 或: ( * ( void (*)( ) )rst ) ( ); 这样的语句就完成复位再启功能了。类型转换符()的优先级跟指针运算符*的优先级相同, 二者的结合方向是自右至左,所以上述语句就能完成复位功能了。保险起见有些程序员常 常喜欢再加个括号: #define K ( ( (void (*)( ) ) rst ) (*K) ( ) 或 ( *( ( void (*)( ) )rst ) ) ( ); 由于没有输入参数,上述复位代码更严谨的写法是: #define K ( ( (void (*)(void ) ) rst ) (*K) ( ) 或 ( *( ( void (*)(void ) )rst ) ) ( );

0 投票
标签: 51单片机软件


发表评论
称呼: 主页:
SMT产品,回流焊,BGA返修台—SMT网上商城
电子导航网

SMT网上商城,bga返修,丝印机,点胶机,回流焊
E-mail:web@eda100.com
版权所有 Copyright© 2008 - 2010 EDA信息网(http://www.eda100.com)
本网站部分文章来源于网络,如有侵权请与我们联系,我们会及时处理