P1.0口接8个LED,编程实现8个灯依次亮灭并循环,间隔0.1秒。
常规方法:
/*************************
项目名称:项目一彩灯控制器
任务名称:任务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.找到一个通用算法,每循环一次,计算一次,得到新控制字。
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) ------->循环左移
此为闭环右移,首尾相接。
#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);//将控制字循环右移一位
}
}
}
循环左移:_crol_(a,1)
#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
}
}
}
或者修改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秒
}
}
}
以下代码实现从两头到中间逐渐亮的过程:
#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秒
}
}
}
以下代码实现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,累加点亮并循环
}
}
}
综上所述,有规则变换时用算法更简便,无规则时列表更好。