P1.0口接8个LED,编程实现8个灯依次亮灭并循环,间隔0.1秒。

项目一彩灯控制器 任务1-3流水灯控制器_单片机


常规方法:

/*************************
项目名称:项目一彩灯控制器
任务名称:任务1-3流水灯控制器
任务描述:P1.0口接8个LED,编程实现8个灯依次亮灭并循环,间隔0.1秒
*************************/
#include<reg51.h>
void delay(int i)
{
	int j,k;
	for(k=0;k<i;k++)
		for(j=0;j<100;j++);
}
/*******************************/
void main()
{
	while(1)
	{
		P1=0xfe;//1111 1110,D1亮
		delay(1000);//延时1秒
		
		P1=0xfd;//1111 1101,D2亮
		delay(1000);//延时1秒
		
		P1=0xfb;//1111 1011,D3亮
		delay(1000);//延时1秒
		
		P1=0xf7;//1111 0111,D4亮
		delay(1000);//延时1秒
		
		P1=0xef;//1110 1111,D5亮
		delay(1000);//延时1秒
		
		P1=0xdf;//1101 1111,D6亮
		delay(1000);//延时1秒
		
		P1=0xbf;//1011 1111,D7亮
		delay(1000);//延时1秒
		
		P1=0x7f;//0111 1111,D8亮
		delay(1000);//延时1秒
	}
}

项目一彩灯控制器 任务1-3流水灯控制器_循环右移_02

循环结构当中控制字每次不相同解决方法:

1.找到一个通用算法,每循环一次,计算一次,得到新控制字。

2.将找到控制字列表,每次循环调用不同数组。

上述代码为第一个解决方法,以下代码为第二个解决办法。

#include<reg51.h>
int led[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//流水灯控制字列表
void delay(int i)
{
	int j,k;
	for(k=0;k<i;k++)
		for(j=0;j<100;j++);
}
/*******************************/
void main()
{
	int i;
	while(1)
	{
		for(i=0;i<8;i++)
		{
		P1=led[i];//0111 1111,D1亮
		delay(100);//延时0.1秒
	}
	}
}


以下方法引入一个循环运算符,使之循环右移:

_cror_(a,1)    ------->循环右移

_crol_(a,1)    ------->循环左移

此为闭环右移,首尾相接。

项目一彩灯控制器 任务1-3流水灯控制器_单片机_03

#include<reg51.h>
#include<intrins.h>
void delay(int i)
{
	int j,k;
	for(k=0;k<i;k++)
		for(j=0;j<100;j++);
}
/*******************************/
void main()
{
	int i,j;
	while(1)
	{
		for(i=0,j=0x7f;i<8;i++)
		{
		P1=j;//控制字
		delay(1000);//延时0.1秒
		j=_cror_(j,1);//将控制字循环右移一位
	}
	}
}

项目一彩灯控制器 任务1-3流水灯控制器_proteus_04

循环左移:_crol_(a,1) 

项目一彩灯控制器 任务1-3流水灯控制器_i++_05

#include<reg51.h>
#include<intrins.h>
void delay(int i)
{
	int j,k;
	for(k=0;k<i;k++)
		for(j=0;j<100;j++);
}
/*******************************/
void main()
{
	int i,j;
	while(1)
	{
		for(i=0,j=0x7f;i<8;i++)
		{
		P1=j;//控制字
		delay(1000);//延时0.1秒
		j=_crol_(j,1);//将控制字循环左移一位,将最后一个R换成L
	}
	}
}

项目一彩灯控制器 任务1-3流水灯控制器_i++_06

或者修改for条件,实现循环左移

#include<reg51.h>
int led[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//流水灯控制字列表
void delay(int i)
{
	int j,k;
	for(k=0;k<i;k++)
		for(j=0;j<100;j++);
}
/*******************************/
void main()
{
	int i;
	while(1)
	{
		for(i=7;i>-1;i--)//从右往左亮,从编号大到小
		{
		P1=led[i];//0111 1111,D1亮
		delay(100);//延时0.1秒
	}
	}
}

项目一彩灯控制器 任务1-3流水灯控制器_proteus_07

以下代码实现从两头到中间逐渐亮的过程:

#include<reg51.h>
//int led[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//流水灯控制字列表
int led[]={0xff,0x7e,0x3c,0x18,0x00};//全灭,头尾各一个亮,各两个,各三个,全亮。
void delay(int i)
{
	int j,k;
	for(k=0;k<i;k++)
		for(j=0;j<100;j++);
}
/*******************************/
void main()
{
	int i;
	while(1)
	{
		for(i=0;i<5;i++)
		{
		P1=led[i];//0111 1111,D1亮
		delay(100);//延时0.1秒
	}
	}
}

项目一彩灯控制器 任务1-3流水灯控制器_i++_08

以下代码实现led灯累加点亮并循环

>>开环右移运算符,右移后补0

#include<reg51.h>
#include<intrins.h>
void delay(int i)
{
	int j,k;
	for(k=0;k<i;k++)
		for(j=0;j<100;j++);
}
/*******************************/
void main()
{
	int i,j;
	while(1)
	{
		for(i=0,j=0xff;i<9;i++)
		{
		P1=j;//控制字
		delay(100);//延时0.1秒
		j=j>>1;//将控制字开环右移,右移后补0,累加点亮并循环
	}
	}
}

项目一彩灯控制器 任务1-3流水灯控制器_i++_09

 综上所述,有规则变换时用算法更简便,无规则时列表更好。