zhouhuanの 发表于 2018-3-18 22:38

单片机LED流水灯

最近给别人讲LED流水灯,发现了一个问题,在仿真的时候第一次第一个灯不亮,其余都正常,第二次也能从第一个开始亮,在思路上不知道哪里有问题,
代码如下:
第一次:
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char      
void delay(uint z);
void delay(uint z)
{
      uint x,y;
      for(x = z;x > 0;x--)
      for(y =         120;y > 0 ;y--);
}
void main()
{
      P0=0XFE ;
      while(1)
      {      
          P0=_crol_ (P0,1);
                delay(500);
      }
}

第二次修改 加了temp 将P0赋值给temp 就可以
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char      
uint temp;
void delay(uint z);
void delay(uint z)
{
      uint x,y;
      for(x = z;x > 0;x--)
      for(y =         120;y > 0 ;y--);
}
void main()
{
      temp=0XFE ;
      while(1)
      {
                P0=temp;
                temp=temp<<1;
                temp=temp|0x01;
      //      temp=_crol_ (temp,1);
                delay(500);
      }
}


但是有点理解不通P0不可以直接_crol_(P0,1)么 问题出在那里 望大佬指点

handleMessage 发表于 2018-3-18 22:44


好像知道了 P0开始最为一个常量 后来又作为变量使用

bbapple 发表于 2018-3-18 22:45


第一次的第一盏灯亮了之后没有delay所以看不见,p0赋值之后你就立马左移赋值了,左移之后才进行了delay所以看到了现象就是一开始就亮两盏灯。

wanglaojii 发表于 2018-3-18 22:49


P口不能成为变量。可以给P口赋一个变量。

laozhongyi 发表于 2018-3-18 22:49


p0赋值之后你就立马左移赋值了

Edisons 发表于 2018-3-18 22:52


第一种方法:一开始把最低位赋值给p0口,他已经移到下一位在while里面进行下一盏灯,如果你试一下在while(1)的上面加一个延时就可以显示第一盏灯,第二种方法:一开始就赋值p0为最高为比如0x7f就可以

_gege 发表于 2018-3-18 22:52

一般情况下第二种方法常用。。。。

Mozarts 发表于 2018-3-18 22:55

_crol_ (P0,1)是循环移动是会把溢出位自动填回去的形成有一个不亮其他全亮的样子

Listate 发表于 2018-3-18 22:55

二次是全亮吧一个一个亮起来只是时间问题
P0是寄存器你第一次是直接访问P0和修改它

夏眠毁灭者 发表于 2025-9-6 10:37

单片机 LED 流水灯通过循环控制多个 LED 按顺序点亮熄灭。先初始化 GPIO 口为输出,主循环中依次置位不同引脚,使对应 LED 亮,延时后复位该引脚,切换至下一个,循环往复。可通过移位指令简化代码,调整延时控制流水速度,实现灯光流动效果。

少女诗篇 发表于 2025-10-17 16:01

单片机 LED 流水灯通过控制 I/O 口电平变化实现:将 LED 通过限流电阻接单片机 I/O 口,编程时依次置位不同 I/O 口为低电平(或高电平,依电路而定),使对应 LED 点亮,其余熄灭,配合延时函数控制点亮时长,循环执行形成灯光依次流动的效果,是单片机入门经典案例。

作业天敌在此 发表于 2025-10-21 18:35

同意楼上,直接操作P0寄存器可能会导致一些不可预测的行为
页: [1]
查看完整版本: 单片机LED流水灯