单片机软件复位程序c语言,剖析单片机C语言软件复位

这篇博客介绍了C语言中如何通过函数指针调用0地址来模拟单片机的硬复位效果,称为软复位。作者详细解释了函数调用的过程,包括函数名作为入口地址的概念,以及类型转换符的使用。通过(void(*)())0这样的类型转换,将0转换为无返回值函数的指针,并调用执行,从而达到复位的目的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

众所周知,单片机在上电复位,或程序正在执行时候按下复位键,PC指针就会指向0地址,程序从0地址处开始执行,这是硬件复位,我暂且称它为“硬复位”,因为下文所讲的是程序在运行过程通过调用执行一段代码跳转到0地址处开始执行,这样也可以实现类似单片机硬复位一样的效果,但却是通过软件来实现的,并不是真正意义上的复位,所以称之为“软复位”。

程序如下:

(*(void(*)())0);

如果你看完这条语句还没有蒙,那你已经完全没必要继续在这个贴上浪费时间了,可以直接关掉这个页面,如果感觉有点蒙,可以选择继续~~

首先需要说明几个概念:

1.函数的调用:函数的调用可以通过函数名调用(这个使用的最普遍),也可以通过函数指针调用(即指向函数的指针变量调用)。如

int a,b,c;

int max(int,int);

int (*p)(int,int);

p=max;

如果要调用max函数,可以使用c=max(a,b);也可以使用c=(*p)(a,b);

通过max(a,b)就调用了max函数,这是为什么呢?这不过是一种简写,这样写你看有没有感觉:(*max)(a,b); max是什么,*max是什么?对于这一点函数和数组是一样的,数组名表示数组的首地址,函数名也就表示该函数的入口地址,*是什么,指针运算符,来取地址间接访问,*max就表示取max函数的入口地址,也即调用执行这个函数了,为什么在这儿加括号?因为函数运算符()的优先级高于单目运算符*,如果不加,那么它就等同于*(max(a,b)),这个是什么意思?交给你吧,我们继续~

2.类型转换符

如果我们知道了如何声明一个给定类型的变量,那么就很容易得到该类型的类型转换符:只需要将声明中的变量名和声明末尾的分号去掉,再将剩余的部分用一个括号封装起来就行了。比如: int i;

float j; (int)j; 把变量名 i和末尾的分号去掉,再加个括号就是(int),就是把浮点型的j强制转换为int型;再如void(*h)();定义了一个指向返回值为空的函数的指针,(void(*)())就是“指向返回值为空的函数的指针”的类型转换符。

到了这里,我们就可以写个类型转换符,将0转换为指向无返回值(或返回值为空)的函数的指针:

首先将0变为一个函数的入口地址,可以写成(void(*)())0,这个表达式就是将0强制转换为指向无返回值的函数的指针,好了,根据1中所述的函数调用方法我们可以尝试调用这个函数指针,(*(void(*)())0)();这条语句也就是执行入口地址为0的函数了,这也正是上面所讲的复位语句。

----详见《C陷阱与缺陷》之“语法陷阱”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值