找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3311|回复: 13
打印 上一主题 下一主题
收起左侧

死循环的原因

[复制链接]
跳转到指定楼层
楼主
ID:163490 发表于 2017-2-5 18:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
使用STC89C54RD+P1口接8个LED灯,低到高位的流水灯,每次只亮一个灯。
程序如下:
  1. #include<reg52.h>

  2. void Delay(unsigned int t);

  3. void main(void)
  4. {       
  5.         unsigned char i;
  6.         P1=0xFE;
  7.        
  8.         for(i=0;i<8;i++)
  9.         {
  10.                 P1<<=1;
  11.                 Delay(50000);
  12.         }
  13. }

  14. void Delay(unsigned int t)
  15. {
  16.         while(--t);
  17. }
复制代码
实际运行结果是 无限循环,P1.0 P1.1常亮,P1.2口依次被点亮



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:7485 发表于 2017-2-5 20:51 | 只看该作者
#include<reg52.h>

void Delay(unsigned int t);

void main(void)
{      
        unsigned char i;
//        P1=0xFE;
  while(1){
          P1=0x01;      
        for(i=0;i<7;i++)
        {
                P1<<=1;
                Delay(50000);
        }
}
}
void Delay(unsigned int t)
{
        while(--t);
}
回复

使用道具 举报

板凳
ID:163490 发表于 2017-2-5 21:01 | 只看该作者
电路设计的是低电平 灯才亮的

评分

参与人数 1黑币 +5 收起 理由
25786136 + 5 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

地板
ID:100391 发表于 2017-2-5 22:11 | 只看该作者
你确定你这个程序会无限循环吗?按我的理解,应该是P1.0到P1.7依次亮,最后的现象就是所有灯都亮了。而且,感觉你这个程序好像有点不规范,因为单片机做完你说写的程序就没事做了。我是一名单片机初学者,请多多指教。

评分

参与人数 1黑币 +5 收起 理由
25786136 + 5 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

5#
ID:163490 发表于 2017-2-6 00:47 | 只看该作者
感谢大家的回复,找到灯显示异常的原因了。因为开发板设计的低电平亮灯。
  1. P1<<=1
复制代码
会造成左移后的地位自动补零,导致显示异常。
修改后的代码如下:
  1. #include<reg52.h>

  2. void Delay(unsigned int t);

  3. void main(void)
  4. {       
  5.         unsigned char i;

  6.         B=0xFE;                 
  7.         for(i=8;i>0;i--)
  8.         {                                                                
  9.                 P1=B;
  10.                 B<<=1;
  11.                 B=B|0x1;
  12.                 Delay(50000);
  13.         }
  14. }


  15. void Delay(unsigned int t)
  16. {
  17.         while(--t);
  18. }
复制代码

但是把HEX文件烧录到STC89C54RD+后,仍然是死循环
DEBUG的时候未发现i的值有变化
C生成的汇编如下:
  1.                  C_STARTUP:
  2. C:0x0000    020026   LJMP     STARTUP1(C:0026)
  3.                  main:
  4. C:0x0003    75F0FE   MOV      B(0xF0),#0xFE
  5. C:0x0006    750808   MOV      0x08,#0x08
  6. C:0x0009    85F090   MOV      P1(0x90),B(0xF0)
  7. C:0x000C    E5F0     MOV      A,B(0xF0)
  8. C:0x000E    25E0     ADD      A,ACC(0xE0)
  9. C:0x0010    F5F0     MOV      B(0xF0),A
  10. C:0x0012    43F001   ORL      B(0xF0),#0x01
  11. C:0x0015    7F50     MOV      R7,#0x50
  12. C:0x0017    7EC3     MOV      R6,#0xC3
  13. C:0x0019    120032   LCALL    Delay(C:0032)
  14. C:0x001C    1508     DEC      0x08
  15. C:0x001E    E508     MOV      A,0x08
  16. C:0x0020    D3       SETB     C
  17. C:0x0021    9400     SUBB     A,#0x00
  18. C:0x0023    50E4     JNC      C:0009
  19. C:0x0025    22       RET      
  20.                  STARTUP1:
  21. C:0x0026    787F     MOV      R0,#0x7F
  22. C:0x0028    E4       CLR      A
  23.                  IDATALOOP:
  24. C:0x0029    F6       MOV      @R0,A
  25. C:0x002A    D8FD     DJNZ     R0,IDATALOOP(C:0029)
  26. C:0x002C    758108   MOV      SP(0x81),#0x08
  27. C:0x002F    020003   LJMP     main(C:0003)
  28.                  Delay:
  29. C:0x0032    EF       MOV      A,R7
  30. C:0x0033    1F       DEC      R7
  31. C:0x0034    7001     JNZ      C:0037
  32. C:0x0036    1E       DEC      R6
  33. C:0x0037    14       DEC      A
  34. C:0x0038    4E       ORL      A,R6
  35. C:0x0039    70F7     JNZ      Delay(C:0032)
  36. C:0x003B    22       RET      
复制代码

回复

使用道具 举报

6#
ID:163582 发表于 2017-2-6 01:45 | 只看该作者
你这个本身就不是只亮一个,左移的时候最低位会是0,第一个和第二个没延时所以常亮

评分

参与人数 1黑币 +5 收起 理由
25786136 + 5 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

7#
ID:163589 发表于 2017-2-6 08:40 | 只看该作者
mark                                                
回复

使用道具 举报

8#
ID:163490 发表于 2017-2-6 23:20 | 只看该作者
本帖最后由 nicktf 于 2017-2-6 23:23 编辑

最后自己找到原因了。
换成XP用Keil uv2,去掉延时代码,如下
  1. #include <STC89C5xRC.H>

  2. void main(void)
  3. {      
  4.         unsigned char i;

  5.         B=0xFE;                 
  6.         for(i=8;i>0;i--)
  7.         {                                                               
  8.                 P1=B;
  9.                 B<<=1;
  10.                 B=B|0x1;
  11.         }
  12. }
复制代码


Debug后 汇编代码如下:
  1. C:0x0003    75F0FE   MOV      B(0xF0),#0xFE
  2. C:0x0006    7F08     MOV      R7,#0x08
  3. C:0x0008    85F090   MOV      P1(0x90),B(0xF0)
  4. C:0x000B    E5F0     MOV      A,B(0xF0)
  5. C:0x000D    25E0     ADD      A,ACC(0xE0)
  6. C:0x000F    F5F0     MOV      B(0xF0),A
  7. C:0x0011    43F001   ORL      B(0xF0),#0x01
  8. C:0x0014    DFF2     DJNZ     R7,C:0008
  9. C:0x0016    22       RET      
  10. C:0x0017    787F     MOV      R0,#0x7F
  11. C:0x0019    E4       CLR      A
  12. C:0x001A    F6       MOV      @R0,A
  13. C:0x001B    D8FD     DJNZ     R0,C:001A
  14. C:0x001D    758107   MOV      SP(0x81),#0x07
  15. C:0x0020    020003   LJMP     main(C:0003)
复制代码


注意看0x0017之后的代码是编译器自动加上的,不知道为啥,代码如下:
  1. MOV R0,#0x7F
  2. CLR        A
  3. MOV        @R0,A
  4. DJNZ        R0,C:001A
  5. MOV         SP(0x81),#0x07
  6. LJMP        main(C:0003)
复制代码

R0为127
A置零
零传送给地址为127的内存单元
把上面重复127次
。。。
又跳回开头的main函数入口继续执行(这里是死循环的更本原因)

最后改为汇编重新编写,代码如下:
  1. ORG 0
  2. START:MOV A,#0FEH
  3. MOV R3,#8

  4. LOOP:MOV P1,A
  5. CALL DELAY
  6. RL A
  7. DJNZ R3,LOOP

  8. DELAY:MOV R4,#20
  9. D1:MOV R5,#20
  10. D2:MOV R6,#248
  11. DJNZ R6,$
  12. DJNZ R5,D2
  13. DJNZ R4,D1
  14. RET

  15. END
复制代码

然后烧录程序,终于世界安静了,只执行了一次。8个灯从P1.0到P1.7依次点亮,目标达成。
使用12Mhz晶振,算了下延时为199660us,也就是0.199660s。
最后,弄不明白为什么编译器会自动加上那些多余的汇编代码





回复

使用道具 举报

9#
ID:163669 发表于 2017-2-6 23:27 | 只看该作者
这个错误好像我也犯过。。值得警惕
回复

使用道具 举报

10#
ID:163490 发表于 2017-2-6 23:50 | 只看该作者
1971417800 发表于 2017-2-6 23:27
这个错误好像我也犯过。。值得警惕

请问这是什么错误,又该如何解决呢?如果都用汇编写复杂度就太高了,谢谢!
回复

使用道具 举报

11#
ID:144931 发表于 2017-2-7 11:02 | 只看该作者
清没清零。。
回复

使用道具 举报

12#
ID:163789 发表于 2017-2-7 16:43 | 只看该作者
    mark
回复

使用道具 举报

13#
ID:163490 发表于 2017-2-8 18:27 | 只看该作者
不知道这种情况用C怎么解决,有大大知道么,万分感谢!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表