Proteus仿真:流水灯

实现目标

使用AT89C52的P1口,接8个LED灯,实现流水灯。具体效果如下:

  • 初始均为灭
  • 从一边到另一边,灯一个接一个亮
  • 当亮完所有灯时,全灭
  • 再反方向,一个一个亮
  • 当亮完所有灯时,全灭
  • 全灭
  • 全亮
  • 全灭
  • 全亮
  • 每隔一个灯亮(两次)
  • 重复上述步骤

Proteus仿真图

在这里插入图片描述

C51代码

#include <REG52.H>//80C52特殊功能寄存器定义

#define LED_PORT1 P1	//用P1口驱动灯,低亮,高灭

void time(unsigned int ucMs);/* 延时单位:毫秒 */
void main(void)
{
unsigned char	ucTimes;	
#define DELAY_TIME 400 //延时
	while(1)
	{
		LED_PORT1=0xff;//灭P1口灯
		time(200);
		//从左往右依次点亮LED
		for(ucTimes=0;ucTimes<8;ucTimes++){//循环点亮P1口灯
			LED_PORT1 = LED_PORT1 - (0x80>>ucTimes);//亮灯需低电平驱动
			time(DELAY_TIME);
		}

		LED_PORT1=0xff;//灭P1口灯
		time(200);
		//然后从右往左依次点亮LED
#include <REGX52.H>
		for(ucTimes=0;ucTimes<8;ucTimes++){//循环点亮P1口灯
			LED_PORT1 = LED_PORT1 - (0x01<<ucTimes);//亮灯需低电平驱动
			time(DELAY_TIME);
		}

		LED_PORT1=0xff;time(DELAY_TIME);//全灭
		LED_PORT1=0;time(DELAY_TIME);//全亮
		LED_PORT1=0xff;time(DELAY_TIME);//全灭
		LED_PORT1=0;time(DELAY_TIME);//全亮

		LED_PORT1=0x55;time(DELAY_TIME);//隔一个点亮
		LED_PORT1=0xaa;time(DELAY_TIME);//交换

		LED_PORT1=0x55;time(DELAY_TIME);//隔一个点亮
		LED_PORT1=0xaa;time(DELAY_TIME);//交换
	}
}
/*********** time C **************/
void time(unsigned int ucMs)//延时单位:ms
{
#define DELAYTIMES 239
unsigned char  ucCounter;  // 延时设定的循环次数

	while (ucMs!=0) {
		for (ucCounter=0; ucCounter<DELAYTIMES; ucCounter++){}//延时
		ucMs--;
  	}
}


个人理解

开始时,P1输出为1111 1111 (0xff),灯是低电平的时候才会亮,所有开始时8个灯均为灭
为了使第一个灯亮,那么就需要P1输出为0111 1111 (当然1111 1110 也可以, 具体看线路连接)

从左往右依次点亮LED的代码如下:

		for(ucTimes=0;ucTimes<8;ucTimes++){//循环点亮P1口灯
			LED_PORT1 = LED_PORT1 - (0x80>>ucTimes);//亮灯需低电平驱动
			time(DELAY_TIME);
		}

为什么这个代码可以实现灯依次点亮呢?

80=1000 0000(十六进制转二进制)

当ucTimes=0,0x80>>ucTimes=1000 0000
此时LED_PORT1=1111 1111
1111 1111 - 1000 000 = 0111 1111
LED_PORT1= 0111 1111
第一个灯亮 其余灯灭

当ucTimes=1,0x80>>ucTimes=1100 0000
此时LED_PORT1=0111 1111
0111 1111- 1100 0000 = 1011 1111
这里使用:减去一个数 等于 加上这个数的相反数
0111 1111 + 0100 0000 = 1011 1111 (相反数:取反再加一)
第二个灯亮 其余灯灭

其余就是类似的了
读者可以自行验证

  • 注:这里有个易错的地方,0x80>>ucTimes右移,左边是自动补1的

运行结果

流水灯

本文Proteus仿真图及源程序获取见:
在这里插入图片描述

说明

参考课本:单片机原理与嵌入式系统设计

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海轰Pro

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值