打印

主程序到底会不会自己循环

[复制链接]
7685|22
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
2001myp|  楼主 | 2009-3-31 10:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
一个简单的程序
void main(void)    
{
P0=0xff;
delay(20,20);
P0=0x00;
delay(20,20);    
}
我用51芯片烧录后,在一块学习板上调试时间,发现P0输出的是一个连续方波,然后我把芯片放到我自己焊的板子上,就是个最小系统,发现只在上电后输出一个周期,我就觉得奇怪了,到底主程序会不会自动循环,为什么学习板上的可以,我的就不行,后来我干脆自己加了个无限循环,结果OK了

void main(void)    
{while(1)
{P0=0xff;
delay(20,20);
P0=0x00;
delay(20,20);}    
}

改成上面的就可以了,为什么呢,菜鸟期待高手指教

相关帖子

沙发
芯行天下| | 2009-3-31 11:01 | 只看该作者

第一个不行,第二个可以循环

第一个不可以循环,第二个可以循环。

你说的第一个情况也有可能,不知你用的是什么单片机(51的应该没有这种功能)。比如430,它的看门狗是开着的,自已会复位,这样程序就相当于一个循环了,但那样时间会比较长的。

使用特权

评论回复
板凳
wangkj| | 2009-3-31 11:04 | 只看该作者

空区是0xffff看你单片机对这个指令的理解。

有的翻译为nop,就会nop到最后,然后跑到0(地址翻转),如果翻译为非法,
则进入非法指令中断。
有的51就是翻译为nop,但不同厂家实现的方法不同,可能有的51就不是。所以,
看你运气。

使用特权

评论回复
地板
computer00| | 2009-3-31 11:12 | 只看该作者

这个还要看你当前的RAM堆栈状态的

在main函数背后,被放置一条RET指令,在这之前是没有CALL指令调用函数的,所以堆栈情况未知,
在执行RET指令时,RET到哪里去了就要看你的堆栈情况了。如果运气好,堆栈中那两个字节数值
刚好为0,那么就RET到0地址去了,相当于复位。你可以在keil上单步执行一下,看它RET时,
到哪去了,查看RAM也可以知道被RET到哪去了。

使用特权

评论回复
5
jiyiche| | 2009-3-31 12:52 | 只看该作者

应该是被复位了

第一个主程序本身是不会自己循环的。
会输出方波可能真被复位了,原因上面都说的很详细了,我也算学习了,呵呵

使用特权

评论回复
6
songbangyan| | 2009-3-31 15:26 | 只看该作者

看门狗的作用

你学习板上那个单片机估计是带有看门狗的。所以看门狗默认复位了。

使用特权

评论回复
7
bjc125| | 2009-3-31 17:23 | 只看该作者

恩第二个可以

使用特权

评论回复
8
liuforever| | 2009-3-31 19:25 | 只看该作者

小问题,大学问呀!!

又长见识了呀!!

使用特权

评论回复
9
渤海三叠浪| | 2009-3-31 22:08 | 只看该作者

看看keil 我用keil

-----------------------------------------------
借用4楼computer00的"运气"二个字用用!!!
是这样的,一般情况下,程序比较短的话,“运气”就好!
程序比较长的话,“运气”就比较差!!!!

至于说能“运气”到位置00,那估计就得中大彩票!!!!!
反正我没中过!!!我中过5元的!!!

好了 
我说一下我的看法,和圈圈说得几乎雷同,纯属巧合..................






在看有些C语言的书说里面,我们发现:主函数里面 会有return 0 语句,这说明了主函数返回0给了操作系统(或者成为主机),就是这种结构
int main(void) ( ) 
{
.....................
     return 0;
}
这就是所谓的ANSIC规定的两种最标准的main函数结构其中的一个。

但是 有一点我们都很清楚 :C语言并非为嵌入式而发明 所以对于所谓的ANSIC规定的两大标准结构,keil给我们的例子并没有采纳。
而是采用了 
void main (void)
{
}
的结构。
这个例子告诉我们:对于我们平时用的这些单片机而言,是没有必要返回主机的。(哈哈单片机有没有所谓的主机我也不清楚!!)于是就弄个while(1) 也就是死循环就OK了。



那么main函数不写while(1)会怎么样呢??看运气喽。
换个角度说,结果也是可知的,o(∩_∩)o...哈哈。结果有两种,可能执行结果看起来是正确的,也可能执行结果看起来是错误的。


楼主可以弄个简单的程序单步调试一下,就知道是怎么回事了。记住,弄个简单的程序。

假设内存空间比较小比如128K,调试就会发现,如果你的程序行数很短,那么 程序指针就会指向内存空间的某个位置,就是跑飞了(为什么会指向这个位置?答案:不知道)。  这时候,如果你将程序写的长一些,就可能会发生一个错误,代码error65  ,就是所谓的“彻底”跑飞了,飞到128K之外了!!!

这时候如果你换个256K内容,仿真一下,就可能发现,没有错误了。 程序指针又跑到内存空间的某个位置了!!!
================================

比较你的程序的反汇编  就会发现,如果你写了while(1)   就多了一个好像是 跳转指令,我记不太清了。  好像是个LJMP吧 还是SJMP  (哈哈 我没学汇编,这些东西 我记不太准)
-------------------------------
【圈圈说是ret  那就是ret了!!!!!!!!!!!!】
------------------------------


使用特权

评论回复
10
王紫豪| | 2009-3-31 22:33 | 只看该作者

楼上是个热心人

使用特权

评论回复
11
wangkj| | 2009-3-31 22:35 | 只看该作者

你用keil反汇编一下。

main是没有retrun指令的,结束就结束了。后面都是fffffffffffffff
只有字函数,才有return指令,具体咋整的忘了。
俺以前犯过这个错误,所以清楚。

另外,arm和51也不相同,不同编译器,编译的结果也不同。

使用特权

评论回复
12
computer00| | 2009-3-31 23:08 | 只看该作者

既然大家都这么热心,俺也来热心一下吧~~~希望能捞条裤子

啥也不多说了,看图片吧:




按照上面的分析,如果增加一个变量,那么这个变量将靠近堆栈

写一段如下的代码:

void main(void)
{
 short int x;
 x=0x3412;
}

发现执行结果与上面的例子结果是一样的,因为编译器把变量x的地址放在了0x08和0x09,
而此时SP的值为0x09。这样,当给变量赋什么值,主函数返回时,就会返回到这个值高低
字节交换的地址去。从这个看来,51更适合小端模式……不过keil是大端的。


使用特权

评论回复
13
wangkj| | 2009-4-1 08:29 | 只看该作者

00 的基础功夫真扎实,人才呀。

我只是记得跑到nop了,其他的就不记得了。应该是5,6年前弄错的。

使用特权

评论回复
14
程序匠人| | 2009-4-1 08:32 | 只看该作者

这个要裤之

使用特权

评论回复
15
pk.kong| | 2009-4-1 08:43 | 只看该作者

大才也。热心人真多。

使用特权

评论回复
16
computer00| | 2009-4-1 09:37 | 只看该作者

哈哈~~~谢谢裤子~~~

之所以会出现这个问题,是keil C51编译器生成的代码跳转到main函数时,用的是直接JMP跳转,
而keil的CARM编译器则不一样,它用的是函数调用(类似call的指令),这时堆栈的内容是确定的,
就是初始化代码中调用main函数指令接下来的地址(这个地址通常放置一条死循环语句),当main函数
返回时,就返回到了初始化代码部分运行,如果那里放置的是一条死循环语句,程序就停在那里了。

使用特权

评论回复
17
三块石头| | 2009-4-1 16:05 | 只看该作者

楼主的问题

因为PC上编程,是在操作系统下运行的,操作系统负责回收程序运行需要的资源,清理后事,那么return 0也就是交给操作系统不管了;但是单片机(一般)没有操作系统,那么就不能执行完程序不管不顾,要“有始有终”,“终”的方式就是找个死循环套进去。如果单片机(ARM)编程也有OS,(比如ucos),那么他的os一般也是死循环。

使用特权

评论回复
18
cliffliu| | 2009-4-2 16:07 | 只看该作者

看过编译器的启动文件后就会很清楚了

编译器要控制用户写的程序,必然会调用用户的main函数,如果main函数返回了,一般的编译器会进入一个死循环,但是如果WDT开启后,情况又不一样了

使用特权

评论回复
19
myic200610| | 2009-4-2 22:28 | 只看该作者

RE

学习了!

使用特权

评论回复
20
eleclike| | 2009-4-3 13:14 | 只看该作者

开眼见了

前段时间也遇到这个类似的问题,一直搞不懂,现在算是开眼见了,学习了,多谢各位详解。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

59

主题

210

帖子

0

粉丝