这几天在做一个东西,一个普通按键,一个复位按键。由于某些原因,硬复位按键有时候不方便引出来,为了通用起见,打起了软复位的主意。 
说是软复位,其实说是想让单片机跳到0地址开始执行。在不使用汇编的情况下,想办法用C语言实现。 
记得好像是<<C专家编程>>里提供过一种方法,有点印像,但是记不起来了。反正就是使用函数指针。琢磨了一会,于是有了以下文字: 
首先是函数指针。声明一个函数指针的语法如下:- void (*p)(void);        // 声明了一个函数指针p, 指向无返回值无参数的函数
 
 
  
[color=rgb(51, 102, 153) !important]复制代码 
下面定义一个函数: 
[color=rgb(51, 102, 153) !important]复制代码 
使得函数指针p指向foo: 
[color=rgb(51, 102, 153) !important]复制代码 
然后就可以使用函数指针调用函数了: 
[color=rgb(51, 102, 153) !important]复制代码 
所以,理所当然的,我们想到这个办法: 
[color=rgb(51, 102, 153) !important]复制代码 
这们应该可以行得通,但是类型不匹配,编译器可能会有警告。 
 
ps:后来我试了一下,编译器居然没有警告。想了一下,明白了,应该是编译器将NULL定义为0,所以这一句就相当于: 
[color=rgb(51, 102, 153) !important]复制代码 
所以没有报错。 
然后使用任意一个非0值给p赋值,警告就出现了。 
 
自然我们会想到强制类型转换。但函数指针的类型是什么呢? 
先看看普通变量:- char i;         // 变量类型为 char
 - int *p;         // 变量类型为 char *
 - const char *j;  // 变量类型为 const *
 
 
  
[color=rgb(51, 102, 153) !important]复制代码 
很明显,将变量声明时的变量类型去掉,就是变量类型了。 
所以我们声明的那个函数指针的类型应该为: 
[color=rgb(51, 102, 153) !important]复制代码 
强制转换: 
我们知道将一个int型的变量bar强制转换为char可以使用如下方式: 
[color=rgb(51, 102, 153) !important]复制代码 
函数指针一样。下面我们将0强制转换为函数指针类型: 
[color=rgb(51, 102, 153) !important]复制代码 
然后:- p = (void (*)(void))0;
 - (*p)();
 
 
  
[color=rgb(51, 102, 153) !important]复制代码 
完成。 
 
等等,好像还不美! 
 
注意函数指针调用函数的方式: 
[color=rgb(51, 102, 153) !important]复制代码 
*p什么意思?取p的内容。 
那p的内容是什么东西? 
很明显 p = (void (*)(void))0。 
那我们把p换成(void (*)(void))0看看。 
于是有: 
[color=rgb(51, 102, 153) !important]复制代码 
完成,连指针变量都省了。 
在Keil中试了一下,编译后汇编语句就一条: 
[color=rgb(51, 102, 153) !important]复制代码 
实际试了一下,可以完成单片机复位,但会不会有什么问题? 
 
 |  
  
 
 
 
 
 |   
 |  
  
 |