51单片机小鸟归巢问题四种方法解决

最近突然碰到小鸟归巢问题,网上也基本上没有很好的解决办法,现在自己也花费几个小时得到了三种实现方法。

  1. 单循环
#include <REGX52.H>

void Delay(unsigned int t)		//@11.0592MHz,5ms延迟器
{
	unsigned char i, j;
	while(t--){
		i = 54;
		j = 199;
		do
		{
		while (--j);
		} while (--i);
	}
}

void main(){
	unsigned char x=128; //用于控制j的值
	unsigned char i,j=1; // i为循环次数,j控制进行流水的位数
	unsigned char n=8; //表示8位流水灯
	P2 = 0xFE; //8位LED的初始状态
	while(1)
	{
		for(i=0;i<n;i++){
			Delay(20); //先延迟100ms用于显示初始状态
			j=j*2; //第j个LED亮
			if(j<=x){ //j要小于等于x的值,实现后面高位恒亮
				P2=(P2-j)+j/2; 
			}
			if(j==x){
				P2=P2-1;
				x=x/2;
				if(P2==0x00){ //全部亮时从头开始
					x=128;
					Delay(20);
					P2=0xFE;
				}
				j=1;
			}
			/*
			上面两个if进行解释一下,例如第一次j=2,j的二进制为0000 0010,
			j/2等于1,二进制为0000 0001,初始P2=0xFE=1111 1110那么
			P2=(P2-0000 0010)+0000 0001=1111 1101,从而实现流水灯
			以此类推,当满足j==x的条件时,这时候while将要执行第一次for循环
			这时x=128,j=128,P2=1011 1111,j/2等于64,
			执行j==x后,P2=(P2-1000 0000)+0100 0000=0111 1111
			while第二次执行for循环后,下面条件j==x时,根据上一步有P2=0111 1111
			P2=P2-1=0111 1111-1=0111 1110,保留了最高位显示
			这时x=x/2=64,j只能到64,因此当第一个if到j==x时,P2=0011 1111
			执行第二个if时,P2=P2-1=0011 1110,保留了最高位和次高位,以此类推,
			从而实现小鸟归巢
			*/
		}
	}
}
  1. 双循环
#include <REGX52.H>

void Delay(unsigned int t)		//@11.0592MHz,5ms延迟器
{
	unsigned char i, j;
	while(t--){
		i = 54;
		j = 199;
		do
		{
		while (--j);
		} while (--i);
	}
}

void main(){ //这个方法是上一个方法的改进
	unsigned char x=128;
	unsigned char i,j=1,k=0;
	P2 = 0xFE;
	while(1)
	{
		for(k=7;k>0;k--){ //控制进行流水灯的位数,从而实现保留高位恒亮
			for(i=0;i<k;i++){ //实现流水灯
				Delay(20);
				j=j*2;
				if(j<=x){
					P2=(P2-j)+j/2;
				}
				if(i==k-1){
					P2=P2-1;
					j=1;
				}
				if(P2==0x00){ //当P2全亮时从头开始
					Delay(20);
					P2=0xFE;
				}
			}
		}
	}
}
  1. 双向移位法
#include <REGX52.H>
#include <INTRINS.H>
void Delay(unsigned int t)		//@11.0592MHz,5ms延迟器
{
	unsigned char i, j;
	while(t--){
		i = 54;
		j = 199;
		do
		{
		while (--j);
		} while (--i);
	}
}

void main()
{
	unsigned char i,j=0,P=0xFF;
	P2 = 0xFE;
	while(1)
	{
		for(j=8;j>0;j--){
			for(i=0;i<j-1;i++){
				Delay(10);
				P2=(P2<<1)+1;
				P2=P2&P;
			}
			Delay(10);
			P=(P>>1)-1;
			P2=P2&P;
			P=P+1;
		}
		P2 = 0xFE;
		P=0xFF;
	}
}
  1. 位数拼凑法

        接下来这个方法简单粗暴,直截了当,通过位移函数和移位符号相结合就可实现

#include <REGX52.H>
#include <INTRINS.H>
void Delay(unsigned int t)		//@11.0592MHz,5ms延迟器
{
	unsigned char i, j;
	while(t--){
		i = 54;
		j = 199;
		do
		{
		while (--j);
		} while (--i);
	}
}

void main(){ //这个方法简单粗暴
	unsigned char i,k=0;
	while(1)
	{
		for(k=8;k>0;k--){ //控制流水灯位数,并且保留高位恒亮
			for(i=0;i<k;i++){ //实现流水灯效果的循环
				P2 = _crol_(0xFE,i);//实现流水灯效果
				P2 = (0xFF>>(8-k))&(P2);//通过(0xFF>>(8-k))保留高位恒亮	
				Delay(20);
			}
		}
	}
}

觉得不错的话点个赞吧~~~~

猜你喜欢

转载自blog.csdn.net/m0_59799878/article/details/127963326
今日推荐