流水灯控制原理、设计过程

  1. 流水灯控制原理、设计过程

本次实验采用锁存器74HC753与译码器74HC138以及一个或非门来实现流水灯控制。

原理图(添加了一点点说明)如下:

首先,要理解怎么使小灯点亮。

如图所示,小灯右端连接着电源(VCC),只有在左端为低电平的时候,小灯才会亮,也就是锁存器Q端输出为低电平的时候才会使小灯亮。

要使Q端输出低电平:(1)使锁存器控制端LE=1,/OE=0,锁存器此时状态为:D端输入与Q端输出一致,在P端输入低电平,Q端就能输出低电平。(2)使锁存器控制端LE=0,/OE=0,锁存器此时状态为锁定,Q端输出保持为之前的输出,不论P端怎么改变。

显然,D端输入受P0控制;/OE接地,恒为0;LE受Y4C控制。所以,Y4C控制着LE,同时也控制着锁存器的状态。Y4C作为或非门的输出,输入端WR接地,恒为0,输入端Y4为译码器的输出端Y4。译码器E1、/E2、/E3称为输入使能端,只有E1=1同时/E2=0和/E3=0时,输入信号才对3-8译码功能有效。由图可知,E1=1,E2=E3=0,所以此时译码器具备译码功能。此时,Y4的输出取决于CBA,也就是P2的输入。

综上所述,要使小灯点亮,需1.CBA=001➡Y4=0➡Y4C=1➡LE=1(锁存器输入等于输出)

                            2. D端输入0,Q端输出0

                            3.CBA=000➡Y4=1➡Y4C=0➡LE=0(锁存器处于锁定状态)

                            4.小灯亮!

流水灯控制原理:

为了实现小灯L1、L2、L3......依次点亮,需在Q端Q0、Q1、Q2......依次输出低电平且其余口输出高电平,来保证只有一个小灯亮且依次亮,并且循环往复,实现流水灯效果。

P0输入控制着D端输入,也就是控制Q端哪个口为低电平,也就是控制哪个小灯亮。

P2输入控制着锁存器的运行状态,在小灯点亮后锁定一下,实现小灯亮。

设计思路:

先使第一个灯L1点亮,其他灯不亮:

P2=0x80;使电路中译码器输出Y4=0,锁存器此时输入等于输出。

P0=0xfe; 此时只有P00为低电平,其他位都为高电平,L1点亮,其他小灯不亮。

P2=0x00;使电路中译码器输出Y4=1,锁存器此时锁定,L1保持点亮。

要使灯L1灭掉,可以:

P2=0x80;

P0=0xff;

P2=0x00;

但是不需要专门让它灭掉,只需要使接下来的灯也都单独亮就好了。

接下来使第二个灯L2点亮,其他灯不亮:

P2=0x80;

P0=0xfd;

P2=0x00;

再使第三个灯L3点亮,其他灯不亮:

P2=0x80;

P0=0xfb;

P2=0x00;

.

.

.

.

.

.

在最初加个while(1)一直循环,由于计算机运算速度太快,流水灯速度过快,肉眼无法观察到,所以需要在每一个小灯亮了之后延时一会儿,也就是添加一个延时器:

for(i=0;i<=200;i++)

{

for(j=0;j<200;j++);

         }

这样做的代码是这样的:

#include "stc15f2k60s2.h"

void main()

{

int i,j;

while(1)

{

P2=0x80;

P0=0xfe;

P2=0x00;

for(i=0;i<200;i++){

for(j=0;j<200;j++);}

P2=0x80;

P0=0xfd;

P2=0x00;

for(i=0;i<200;i++){

for(j=0;j<200;j++);}

P2=0x80;

P0=0xfb;

P2=0x00;

for(i=0;i<200;i++){

for(j=0;j<200;j++);}

P2=0x80;

P0=0xf7;

P2=0x00;

for(i=0;i<200;i++){

for(j=0;j<200;j++);}

P2=0x80;

P0=0xef;

P2=0x00;

for(i=0;i<200;i++){

for(j=0;j<200;j++);}

P2=0x80;

P0=0xdf;

P2=0x00;

for(i=0;i<200;i++){

for(j=0;j<200;j++);}

P2=0x80;

P0=0xbf;

P2=0x00;

for(i=0;i<200;i++){

for(j=0;j<200;j++);}

P2=0x80;

P0=0x7f;

P2=0x00;

for(i=0;i<200;i++){

for(j=0;j<200;j++);}

}

}

确实是个笨方法,但是可以实现流水灯效果。

为了让代码更简洁、高级,可以运用取反“~”和移位“<<”操作来实现。

由于C语言的移位,操作后“形成的空位”是“补0”的。要实现LED灯亮的移位,需要这样处理:原始操作数为0x01(二进制00000001),左移1位后为(00000010)输出时采用反码操作(~取反操作)变成(11111101),以此类推。即:

Unsigned char x=0x01;

P2=0x80;

P0=~x;

P2=0x00;

x=x<<1;

再在此基础上加入循环:

unsigned char x=0x01;

while(1)

{

   P2=0x80;

   P0=~x;

   P2=0x00;

delay(1000);

x=x<<1;

 if(x==0)

 {

    x=0x01;

 }

}

再定义一个延时器:

void delay(unsigned int k)

{

unsigned int i,j;

for(i=0;i<k;++i)

{

for(j=0;j<113;++j);

}

}

把这些组合在一起就得到了简化版:

#include "stc15f2k60s2.h"

void delay(unsigned int k)

{

unsigned int i,j;

for(i=0;i<k;++i)

{

for(j=0;j<113;++j);

}

}

void main()

{

unsigned char x=0x01;

while(1)

{

   P2=0x80;

   P0=~x;

   P2=0x00;

delay(1000);

x=x<<1;

 if(x==0)

 {

    x=0x01;

 }

}

}

至此,流水灯设计完毕,若要改变流水方向,只需更改P0端输入x以及反方向移位即可。

#include "stc15f2k60s2.h"

void delay(unsigned int k)

{

unsigned int i,j;

for(i=0;i<k;++i)

{

for(j=0;j<113;++j);

}

}

void main()

{

unsigned char x=0x80;

while(1)

{

   P2=0x80;

   P0=~x;

   P2=0x00;

delay(1000);

x=x>>1;

 if(x==0)

 {

    x=0x80;

 }

}

}

若要使流水灯左右往复流水,可以将从左到右流水和从右到左流水结合即可。

代码:

#include "stc15f2k60s2.h"

void delay(unsigned int k)

{

unsigned int i,j;

for(i=0;i<k;++i)

{

for(j=0;j<113;++j);

}

}

void main()

{

int a,b;

unsigned char x=0x80;

while(1)

{

for(a=0;a<8;a++)

{

   P2=0x80;

   P0=~x;

   P2=0x00;

delay(1000);

x=x>>1;

}

if(x==0)

{

x=0x01;

}

for(b=0;b<8;b++)

{

   P2=0x80;

   P0=~x;

   P2=0x00;

delay(1000);

x=x<<1;

if(x==0)

{

x=0x80;

}

}

}

}

间隔点亮只需将移位操作变成移两位即可。

代码:

#include "stc15f2k60s2.h"

void delay(unsigned int k)

{

unsigned int i,j;

for(i=0;i<k;++i)

{

for(j=0;j<113;++j);

}

}

void main()

{

int a;

unsigned char x=0x80;

while(1)

{

for(a=0;a<8;a++)

{

   P2=0x80;

   P0=~x;

   P2=0x00;

delay(2000);

x=x>>2;

if(x==0)

{

x=0x80;

}

}

}

}

按顺序点亮只需调整移位即可。“<<”逻辑左移。左移时,低位补0;高位移出的部分舍弃。

代码:

#include "stc15f2k60s2.h"

void delay(unsigned int k)

{

unsigned int i,j;

for(i=0;i<k;++i)

{

for(j=0;j<113;++j);

}

}

void main()

{

int a;

unsigned char x=0xfe;

while(1)

{

for(a=0;a<8;a++)

{

   P2=0x80;

   P0=x<<a;

   P2=0xff;

delay(5000);

}

}

}

实现顺序点亮再顺序熄灭:按顺序点亮如上一例子,移位操作即可。按顺序熄灭需要设置一个中间变量。全亮时,P0=0x00,熄灭第一个小灯时P0=0x8f,熄灭第二个小灯时P0=0xc0,熄灭第三个小灯时P0=0xe0......这样看比较难看出规律,看图:

代码如下:

#include "stc15f2k60s2.h"

void delay(unsigned int k)

{

unsigned int i,j;

for(i=0;i<k;++i)

{

for(j=0;j<113;++j);

}

}

void main()

{

int a;

unsigned char x,b;

while(1)

{

x=0xff;

for(a=0;a<=8;a++)

{

   P2=0x80;

   P0=x>>a;

   P2=0xff;

delay(5000);

}

x=0x80;

P2=0x80;

P0=x;

P2=0xff;

delay(5000);

b=x/2;

for(a=0;a<=8;a++)

{

x=x+b;

P2=0x80;

P0=x;

P2=0xff;

delay(5000);

b=b/2;

}

}

}

这就是几种不同模式的流水灯。

  • 16
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值