打印

向各位大大求教一个关于单片机while循环的问题

[复制链接]
5076|21
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jbbppa|  楼主 | 2012-6-15 10:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我在开发板上面操作的时候发现,如果我不写while(1),程序依然会循环。例如让led闪烁:
    P2=0x00;
    delay(600);
    P2=0xff;
    delay(600);
以上是main函数没有输入while循环,可是led灯会一直闪烁而不是只闪烁一次,我问技术支持,他说是因为单片机不是纯C,PC会自动一直在flash里面循环跑,加while只是为了更保险。是这样吗?
可是我又实验用按键控制led,一个按键控制一个灯,结果发现如果我不写while,按下两个按键的时候第一个灯会很暗。但是加入while(1)后,发现第一个灯的亮度基本不变,求大神解释

相关帖子

沙发
ayb_ice| | 2012-6-15 10:47 | 只看该作者
没有吃药病就好了,不等于不吃药病就一定会好的
有病不一定会死人的

使用特权

评论回复
板凳
渤海三叠浪| | 2012-6-15 11:00 | 只看该作者
楼主可以查查computer00的帖子  我记得有这方面的东西。
楼主问的问题看似简单 想解释清楚的也不大容易

天为什么是蓝的 现在我也不大能解释清楚

使用特权

评论回复
地板
hanshun1986| | 2012-6-15 11:01 | 只看该作者
2楼的说法比较通俗,呵呵,我也不明白while(1)在C编译器中到底是什么概念。

求2楼详解

使用特权

评论回复
5
渤海三叠浪| | 2012-6-15 11:05 | 只看该作者
不加while ,就是代码不断的跑呗   跑到flash的尽头了,就从一个不确定的地方又开始重新跑。

使用特权

评论回复
6
渤海三叠浪| | 2012-6-15 11:06 | 只看该作者
不加while ,就是代码不断的跑呗   跑到flash的尽头了,就从一个不确定的地方又开始重新跑。

重申一下 keil似乎是这样啊  别的我不清楚。

使用特权

评论回复
7
chenbb8| | 2012-6-15 11:07 | 只看该作者
看反汇编吧

使用特权

评论回复
8
xwj| | 2012-6-15 11:18 | 只看该作者
6楼正解。
不写while(1)程序会一直跑,由于填充的代码是0xff或者0x00,程序并不会乱跳,而是一路跑 跑到flash的尽头后又从地址0开始跑了,实际上相当于每次跑一圈后都在复位,优惠运行到这些代码了,所以你可以看到“led灯会一直闪烁而不是只闪烁一次”
但是由于后面要跑一圈才能重新回到0,所以周期其实是不对的。

使用特权

评论回复
9
hanshun1986| | 2012-6-15 11:18 | 只看该作者
反汇编是啥意思?
我汇编都不会呢,不明白哦,求解释

使用特权

评论回复
10
ayb_ice| | 2012-6-15 11:31 | 只看该作者
本帖最后由 ayb_ice 于 2012-6-15 11:51 编辑

0xffff+1=0
未用的空间一般是0或FF
0是NOP指令的编码
FF是MOV R7 A的编码所以执行执行到最后就又循环了,一般也不影响什么
标准的51如果遇到不能执行的指令其实相当于NOP操作,比如A5,所以也不会有问题

使用特权

评论回复
11
原野之狼| | 2012-6-15 12:33 | 只看该作者
答案已经浮出水面了~

使用特权

评论回复
12
jbbppa|  楼主 | 2012-6-15 16:23 | 只看该作者
感谢8L的回答,这个和卖板子的技术支持一样的答复,就是PC从0开始在flash里面一直跑到头,然后又指回0,重新开始跑!
那么关于我的第二问题,有谁可以解释清楚吗?反汇编就是点那个放大镜(debug),我的汇编不是很熟,但是个人认为灯的亮度应该没有什么影响。现象我再描述一遍,程序如下,是示例,我自己也写了个不要P04,P05的,就不发了:
#include <reg51.h>
#include <intrins.h>

sbit BEEP =  P1^5;
sbit RELAY = P1^4;

sbit  K1 = P0^0; sbit  K2 = 0x80^1;         
sbit  K3 = P0^2; sbit  K4 = 0x80^3;
sbit  K5 = P0^4; sbit  K6 = 0x80^5;

void beep();
/*********************************************************/
main()
{
   
  // while(1)
   {
             P2 = 0xff;
          
          if(K1 == 0)        P2 = 0xfe;
             
         
             if(K2 != 1)   P2 = 0xfd;
            
                     
             if(!K3)       P2 = 0xfb;
             

             if(~K4)       P2 = 0xf7;
       
          if(!K1&&!K2)  P2 = 0x00
            
                            
          if(!K5 )            beep();  
         
          if (!K6 )
            RELAY = 0;  
          else
            RELAY = 1;
         
         }
}


/**********************************************************/
void beep()
{
  unsigned char i , j;
  for (i=0;i<100;i++)
   {
  
      BEEP=!BEEP;              
      for (j = 0 ; j<250 ; j++)   
      _nop_();
   }
  BEEP=1;                    
}
程序如上,main中如果有while(1),那么我先按下K1,不松手再按下K3,两个灯都会亮,亮度相同,假设是亮度A。
但是我删除while(1)后,先按下K1,对应的LED灯发光,亮度基本也是A。然后K1不松开,再按下K3,这时K3对应的LED发光,亮度基本为A,但是这时K1对应的LED会变得很暗,这个是什么原因,求大神们指教下小弟

使用特权

评论回复
13
huailove| | 2012-6-15 18:00 | 只看该作者
楼主是个爱钻没有的牛角尖? 还是想当个无所不知的神人?

使用特权

评论回复
评论
小分子 2016-9-4 11:32 回复TA
关心下求知欲望很强的人。 
14
大道至简| | 2012-6-15 22:58 | 只看该作者
本帖最后由 大道至简 于 2012-6-15 23:16 编辑

你不写while,执行完main后复位,然后重新执行main。。。。。
are you 明白?

使用特权

评论回复
15
疯子8972| | 2012-6-15 23:39 | 只看该作者
如果空闲程序区是0x00或者0xff,程序指针会不停增加,直到回到0点,就等于上点重启了
有的编译器在startup里做了**
在main函数之后
用汇编定义了exit
就是如果跳出了main
就跳到了0,等于重启了
用户可以重写exit
做跳出main后想做的事情
比如报警或者是后台程序
不知道你明白了么   呵呵

使用特权

评论回复
16
wajajn| | 2012-6-16 09:38 | 只看该作者
sbit  K1 = P0^0; sbit  K2 = 0x80^1;    ??

使用特权

评论回复
17
sysdriver| | 2012-6-16 11:16 | 只看该作者
知道原理原因就可以了,何必没事找事,电子知识何其庞大,每个都这样,学到老都学不通单片机

使用特权

评论回复
18
wukunshan| | 2012-6-16 13:53 | 只看该作者
楼主的C51还没学透,程序逻辑的走向还搞不清楚。继续加强学习,回头再来看看你的这个问题,你就会觉得这个根本就不是问题。

使用特权

评论回复
19
joyme| | 2012-6-16 15:43 | 只看该作者
第二个问题是因为后面按键的那个灯亮(有电流)的时间长(取决于程序跑回来的时间),前面的时间太短(平均电流很小,所以很暗。
有while的话,两个灯流过电流的时间差不多,故亮度一样(跟正常亮度同)

使用特权

评论回复
评论
小分子 2016-9-4 11:31 回复TA
这个解释不错哦。 
20
jbbppa|  楼主 | 2012-6-18 10:46 | 只看该作者
感谢19L

使用特权

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

本版积分规则

2

主题

39

帖子

0

粉丝