问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

我的单片机程序不能复位 那个大哥 大姐 知道怎么加进去啊?是c语言的 ,谢谢

发布网友 发布时间:2022-08-17 23:30

我来回答

2个回答

热心网友 时间:2023-10-14 15:57

推荐个帖子给你
main()

{

unsigned char code rst[]={0xe4,0xc0,0xe0,0xc0,0xe0,0x32}; // 复位代码

(*((void (*)())(rst)))(); // 执行上一行代码,将rst数组当函数调用

}

本来我告诉他嵌入如下代码:

clr a

push acc

push acc

reti

结果他却玩了前面哪一段,而数组rst[]中的内容恰恰是上面的汇编机器码,他的做法是将
rst数组的数据当作代码保存,然后采用绝对地址方式指向该数组,将该数组中的代码当作
函数来运行。居然通过了!

我觉得有问题,我说即使如此,那绝对地址调用也应该写成(*((void (*)())(&rst)))()
才对呀,结果他反驳说,那样的话,rst的地址就会当成参数传递给这个绝对地址函数,而
实际LJMP调用的地址并非rst的地址,而是一个不确定的地址。于是我按照自己的说法尝试
了一下,看看汇编结果,还真的是将rst的地址传递给了R1 R2,而绝对函数最终LJMP到了
一个莫名其妙的地址上去了,死翘!

看来C真是一匹不容易驾驭的野马,这个大三学生理解力在我之上,我30多岁的人了,干了
这么多年还没他的境界呢,唉,人家才学了几天啊,翻了几天书就这么厉害了,服了!

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

l 关于帖子作者的解释

千万不要犯“&rst”形式的错误,对于一维数组而言,数组名rst就代表地址。以下二者等
价,更常用的是等式左边的形式:

rst == &rst[0]

整个函数指针无所谓参数传递,只是把rst当作程序执行地址调用而已,那个学生的解释也
有问题。

还有一点必须提及,不是说能通过编译,甚至生成正确代码,就表示某语句一定是对的。
对很复杂的语句,要考虑到编译器不严格甚至出错的可能性。

l 哈佛结构和一个蠕虫病毒

请注意,定义数组rst[]时用了关键字code,这是C51特有的关键字,意味着把数组定义到
程序空间。标准C是没有关键字code的。

哈佛结构和普林斯顿结构:

哈佛结构——程序空间和存储空间分开的。C51算是不太严格的哈佛结构——虽地址线分
开,但数据线没有分开。DSP是增强的哈佛结构。

PC电脑上奔腾CPU是普林斯顿结构——数据空间和程序空间统一编址。

如果数组rst[]数据的汇编机器码是删除文件的机器码,这算不算是病毒?

曾经流行过一种蠕虫病毒,其发作机理采取的就是将恶意代码保存成文本文件,然后通过
指针调用执行这个文本,很多杀毒程序也不会查询文本文件。

程序也罢,数据也罢都是二进制形式,如果数据空间和程序空间是统一编码的, 数据当然
可以当作程序运行。

在这一点上,相对而言,哈佛结构的CPU安全性会好一点点。但嵌入式应用少有病毒,一般
不用关心。

l 单片机复位的更好方法

帖子中汇编语言解释如下:

clr a //清除ACC=0

push acc //压0到堆栈——8位

push acc //再压0到堆栈——再8位

reti //返回到0地址,从而执行。

帖子作者的这种复位方法比较麻烦,更加简单的复位写法是(摘自《C缺陷与陷阱》):

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

本句的分析方法同上,但更加精炼,没有多余的汇编语句。

上述复位的方法可称为软件复位。

软件复位跟真正上电复位有很大差别:上电复位时大部分寄存器都有确定的复位值;软件
复位则只相当于从0地址开始执行而已,寄存器不会变为确定的复位值。

如果用户要编程实现上电复位这种情况,在程序中不要踢看门狗即可。大部分单片机都有
看门狗吧。

热心网友 时间:2023-10-14 15:58

什么单片机?你是想软件复位还是硬件复位?
如果是软件复位,那你要确保已经开了看门狗?开了话 如果你清了看门狗 那是看不到复位的,你注释清看门狗语句 就应该看到复位啦!如果没开看门狗 系统正常运行那也看不到复位现象的。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
情侣文案英文高级浪漫87句 Love to the people don't wave.什么意思 gladtomeetyou怎么 gladtomeetyou.怎么回答 2016生肖猴运程 武汉买房88平方满50万落户政策 非武汉市户口在武汉市购买70平方总价50万的商品房,可以转户口吗... 我想在武汉买一套50万左右的新房子,谁能告诉我现在武昌,关山,江夏,有... 支付宝怎么开通步数授权? 总价50万能在武汉买一套两室一天的二手房吗? 跨越百年的美丽一文的作者是谁 各种在线编译C语言,java等语言的编译器是如何防止用户提交的恶意代码在后台运行的? 跨越百年的美丽的作者是哪国的 联想笔记本电脑的指纹识别器怎么用 怎么用同一个手机号码申请多个?- 问一问 超图软件这只股票是什么股票?超图软件业绩不达预期?超图软件属于哪类股票? 一个手机号怎么申请第二个? 一个手机号怎么注册两个? 采访妈妈 什么是爱情 作文 什么是爱情,为什么我妈妈总说你们小孩知道什么!!! 黑莓手机8310是不是智能机? 黑莓手机是智能手机吗 黑莓是功能机吗? 黑莓手机都是智能的吗 黑莓手机 是智能机吗 黑莓的手机是智能手机吗 西方经典爱情诗歌英文版 所有黑莓手机都是智能手机吗? 一部手机两个怎么弄 一个手机号怎么申请第二个? 我打算去浙江义乌,应该穿什么衣服?义乌有哪些特色? 去浙江义乌买小商品.衣服便宜吗? 这几天来义乌逛逛,有没有离客运中心比较近的价格还好,衣服挺漂亮的地方,商贸城好玩吗, 如何成为受欢迎的人,小伙伴们知道这几个方法吗? 在职场上受欢迎的4个秘诀,你知道吗? 想学会计可以寒暑假报补习班吗? 羽绒服刮破了怎么修补的小妙招 如何修补羽绒服刮破了 苹果平板air2屏幕有阴阳屏影响使用寿命吗 在上海买了一条中华香烟有PDPD的代码是什么意思? 怎样把pdp转换成ppt soul 让禁言是对话完禁言还是当时禁言 soul禁言可以打视频吗 soul被禁言是系统检测,还是用户举报 c语言程序问题 判断对错,并解释 18:关于文件理解不正确的为: A)C语言把文件看作是字节的序列,即由一个个字节的数据顺序组成; C语言把文件看做是一个字符(字节)的序列 这句话什么意思?字符就是字节“? 如何用c语言编写一段方波 怎样用C语言编写一个方波函数? 如何用C语言编程使单片机产生方波信号 2022全国排名前二十的城市是哪些?