51单片机流水灯学习笔记

目录

流水灯

一,最一目了然实现流水灯

二,位运算符“<<”实现流水灯

三,位或操作实现流水灯

来回荡的流水灯

封装成模块的流水灯


单片机使用的是普中51,型号选择是AT89c52

流水灯

一,最一目了然实现流水灯

#include <REGX52.H>
#include <intrins.h>

void Delay(unsigned int xms);
unsigned char i;

void main ()
{
	while(1)
	{
        P2=0xfe;
		Delay(500);
		P2=0xfd;
		Delay(500);
		P2=0xfb;
		Delay(500);
		P2=0xf7;
		Delay(500);
		P2=0xef;
		Delay(500);
		P2=0xdf;
		Delay(500);
		P2=0xbf;
		Delay(500);
		P2=0x7f;
		Delay(500);
	}

}

调用了delay模块,后续不再赘述

一盏盏灯点亮,也可以将代码简化成数组的形式,就是把给P2的高低电平信号放于一个数组之中,再写个循环即可。

二,位运算符“<<”实现流水灯

#include <REGX52.H>
#include <intrins.h>
void Delay(unsigned int xms);

unsigned char i;
unsigned char tmp;

void main ()
{
	while(1)
	{
		for(i=0;i<8;i++)
		{
			P2=(tmp<<i)+1;
			Delay(500);
		}
	}

}

0xfe<<i: 这是一个左位移操作。初始值0xfe表示1111 1110,所以在第一次循环中,最低位是0(LED亮),其他位是1(LED灭)。当i递增,这个0会向左移动,实现从左到右的流水效果。

三,位或操作实现流水灯

#include <REGX52.H>
#include <intrins.h>
void Delay(unsigned int xms);

unsigned char i;

void main ()
{
	while(1)
	{
		for(i=0;i<8;i++)
		{
			P2=(0xfe<<i)|(0xfe>>(8-i));//或运算减少内存使用,增快运算速度
			Delay(500);
		}
	}

}

在每次循环中,我们将0xfe左移i位。当i递增,0(也就是0xfe的最低位)将向左移动。然后,我们将0xfe右移8-i位。当i递增,右移的位数实际上在递减。这是为了确保左移和右移操作合并后可以得到单一的0位移动从右到左的效果。将上述两个操作合并,我们使用按位或操作(|)。其目的是取两个操作的组合效果,这样在每次循环中都只有一个0

实际上位操作是在“加0上去,把前头的1挤出去”。

来回荡的流水灯

#include <REGX52.H>
#include <intrins.h>
void Delay(unsigned int xms);

unsigned char i;

void main ()
{
	while(1)
	{
		for(i=0;i<8;i++)
		{
			P2=(0xfe<<i)|(0xfe>>(8-i));//或运算减少内存使用,增快运算速度
			Delay(500);
		}
		for(i=0;i<6;i++)
		{
			P2=(0xbf>>i)|(0xbf<<(8-i));//或运算减少内存使用,增快运算速度
			Delay(500);
		}
	}

}

两个for循环实现荡漾的流水灯,注意从右到左的i循环会有两次重复

不够简洁,下面代码只使用一个for循环

#include <REGX52.H>
#include <intrins.h>
void Delay(unsigned int xms);

unsigned char i;

void main ()
{
	while(1)
	{
		for(i=0;i<14;i++)
		{
			if(i<8)
			{
				P2=(0xfe<<i)|(0xfe>>(8-i));//从最左端开始算起的位移操作
				Delay(500);
			}
			else
			{
				P2=(0xbf>>(i-8))|(0xbf<<(16-i));//从最右端开始算起的位移操作
				Delay(500);
			}
		}
	}

}

封装成模块的流水灯

#include <REGX52.H>
#include <intrins.h>
void Delay(unsigned int xms);
#define N 6 // N代表流水灯的个数
void led_running(bit dir)//dir为1代表先向右,0代表先向左
{
	static unsigned char i=0;
	unsigned char tmp;
	
		if(dir) // dir=1
		{
			P2=(0xfe<<i)|(0xfe>>(8-i));
		}
		else
		{
			tmp=(0xfe<<(N-1))|(0xfe>>(8-(N-i)));
			P2=(tmp>>i)|(tmp<<(8-i));
		}
			Delay(250);
			i++;
			if(i==N) i=0;
}
void main ()
{
	unsigned char i=0;
	while(1)
	{
			led_running(1);
	}

}

用define定义流水灯的个数,同时节省了内存空间。当bit型的dir等于0时流水灯向左流,等于1的时候流水灯向右流,等于0的时候流水灯向左流。采用静态变量i,不定义在全局之中,节省内存。使用函数使得代码变得简洁雅观。

define不仅能够节省内存空间,还能单独做成一个.h文件,用作加密

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值