单片机C51 之(5)GPIO流水灯

流水灯是若干个灯泡依次点亮,视觉上感觉到灯光在流动就叫做流水灯。
单片机C51 之(5)GPIO流水灯_第1张图片
选用单片机的P0端口8只引脚作为输出脚,1只引脚控制1只LED灯。设置P0_0脚为低电平,使得第1只LED灯点亮,并延时一点时间,然后设置P0_0脚为高电平,熄灭第1只LED,以此同理控制其余7只引脚。比如:
P0_0脚为低电平,使得第1只LED灯点亮
P0_1脚为低电平,使得第2只LED灯点亮
P0_2脚为低电平,使得第3只LED灯点亮
P0_3脚为低电平,使得第4只LED灯点亮
P0_4脚为低电平,使得第5只LED灯点亮
P0_5脚为低电平,使得第6只LED灯点亮
P0_6脚为低电平,使得第7只LED灯点亮
P0_7脚为低电平,使得第8只LED灯点亮

程序控制
实现8个LED流水灯程序用中文表示为:P0.0低、延时、P0.0高、P0.1低、延时、P0.1高、P0.2低、延时、P0.2高、P0.3低、延时、P0.3高、P0.4低、延时、P0.4高、P0.5低、延时、P0.5高、P0.6低、延时、P0.6高、P0.7低、延时、P0.7高、返回循环开始。

  • 一、总线方法实现流水灯。
    比较笨但又最易理解的方法,采用顺序程序结构,用位指令控制P0口的每一个位输出高低电平,加上延时函数,即可控制每个LED灯的亮灭:
#include  //包含特殊功能寄存器定义的头文件


sbit LED0 = P0^0;  //位地址声明,注意: sbit 必须小写、 P 大写!
sbit LED1 = P0^1;  //位地址声明,注意: sbit 必须小写、 P 大写!
sbit LED2 = P0^2;  //位地址声明,注意: sbit 必须小写、 P 大写!
sbit LED3 = P0^3;  //位地址声明,注意: sbit 必须小写、 P 大写!
sbit LED4 = P0^4;  //位地址声明,注意: sbit 必须小写、 P 大写!
sbit LED5 = P0^5;  //位地址声明,注意: sbit 必须小写、 P 大写!
sbit LED6 = P0^6;  //位地址声明,注意: sbit 必须小写、 P 大写!
sbit LED7 = P0^7;  //位地址声明,注意: sbit 必须小写、 P 大写!


void DelayTime10ms(unsigned int DelayValue);

void main()//任何一个 C 程序都必须有且仅有一个 main 函数
{
	for(;;){//死循环
	
		LED0 = 0; //第一个灯亮
		DelayTime10ms(100);
		
		LED0 = 1;
		LED1 = 0;
		DelayTime10ms(100);
		
		LED1 = 1;
		LED2 = 0;
		DelayTime10ms(100);
				
		LED2 = 1;
		LED3 = 0;
		DelayTime10ms(100);
				
		LED3 = 1;
		LED4 = 0;
		DelayTime10ms(100);
				
		LED4 = 1;
		LED5 = 0;
		DelayTime10ms(100);
				
		LED5 = 1;
		LED6 = 0;
		DelayTime10ms(100);
				
		LED6 = 1;
		LED7 = 0;
		DelayTime10ms(100);
		
		LED7 = 1;
	}	
}

void DelayTime10ms(unsigned int DelayValue){
	unsigned int a,b;
	for(a=0;a<DelayValue;a++)
		for(b=0;b<1828;b++);	
}
  • 二、改变赋值
    对整个P0口进行赋值操作实现流水灯效果:
    11111110 P0_0脚为低电平,使得第1只LED灯点亮
    11111101 P0_1脚为低电平,使得第2只LED灯点亮
    11111011 P0_2脚为低电平,使得第3只LED灯点亮
    11110111 P0_3脚为低电平,使得第4只LED灯点亮
    11101111 P0_4脚为低电平,使得第5只LED灯点亮
    11011111 P0_5脚为低电平,使得第6只LED灯点亮
    10111111 P0_6脚为低电平,使得第7只LED灯点亮
    01111111 P0_7脚为低电平,使得第8只LED灯点亮
#include  //包含特殊功能寄存器定义的头文件

void DelayTime10ms(unsigned int DelayValue);

void main()
{
	for(;;){	
		P0 = 0xfe;  //在头文件中定义P0 = 0x80,这里可以直接使用P0
		DelayTime10ms(100);
		
		P0 = 0xfd;
		DelayTime10ms(100);
		
		P0 = 0xfb;
		DelayTime10ms(100);
		
		P0 = 0xf7;
		DelayTime10ms(100);
		
		P0 = 0xef;
		DelayTime10ms(100);
		
		P0 = 0xdf;
		DelayTime10ms(100);
		
		P0 = 0xbf;
		DelayTime10ms(100);
		
		P0 = 0x7f;
		DelayTime10ms(100); 
	}
}

void DelayTime10ms(unsigned int DelayValue){
	unsigned int a,b;
	for(a = 0;a<DelayValue;a++)
		for(b = 0;b<1828;b++);	
}
  • 三、采用数组形式
#include  //包含特殊功能寄存器定义的头文件

void DelayTime10ms(unsigned int DelayValue);

unsigned char LED[] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};

void main()
{
	for(;;){	
		
		P0 = LED[0];
		DelayTime10ms(100);
		
		P0 = LED[1];
		DelayTime10ms(100);
		
		P0 = LED[2];
		DelayTime10ms(100);
		
		P0 = LED[3];
		DelayTime10ms(100);
		
		P0 = LED[4];
		DelayTime10ms(100);
		
		P0 = LED[5];
		DelayTime10ms(100);
		
		P0 = LED[6];
		DelayTime10ms(100);
		
		P0 = LED[7];
		DelayTime10ms(100);
	}
}

void DelayTime10ms(unsigned int DelayValue){
	unsigned int a,b;
	for(a = 0;a < DelayValue;a++)
		for(b = 0;b < 1828;b++);	
}
  • 四、将(三)优化一下
#include  //包含特殊功能寄存器定义的头文件

void DelayTime10ms(unsigned int DelayValue);

unsigned char LED[] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};

void main()
{
	int i;
	for(;;){	
		for(i = 0;i<8;i++){
			P0 = LED[i];
			DelayTime10ms(100);
		}
	}
}

void DelayTime10ms(unsigned int DelayValue){
	unsigned int a,b;
	for(a = 0;a < DelayValue;a++)
		for(b = 0;b < 1828;b++);	
}
  • 五、逻辑移位
    可以使用逻辑移位语句,每次赋值后,将数值左移一位。
#include  //包含特殊功能寄存器定义的头文件

void DelayTime10ms(unsigned int DelayValue);

void main()
{
	int i,temp;
	for(;;){	
	
		temp = 0xfe;
		for(i = 0;i < 8;i++){   //左移,LED0到LED7
			P0 = temp;
			DelayTime10ms(100); 
			
			temp = temp<<1;   
			temp = temp + 1;		//移位之后补0,所以加上1	 		
		}
		
		temp = 0x7f;
		for(i = 0;i < 8;i++){   //右移,LED7到LED0
			P0 = temp;
			DelayTime10ms(100); 
			
			temp = temp>>1;
			temp = temp + 128;	//移位之后补0,所以加上128	
		}
	}
}

void DelayTime10ms(unsigned int DelayValue){
	unsigned int a,b;
	for(a = 0;a < DelayValue;a++)
		for(b = 0;b < 1828;b++);	
}
  • 六、库函数 跟移位类似
#include 
#include 

void DelayTime10ms(unsigned int DelayValue);

void main()
{
	int i,temp;
	for(;;){	
	
		for(i=0;i<7;i++){ 
			temp=_crol_(0xfe,i);
			XXX=temp;
			DelayTime10ms(100); 		
		}		
		
		for(i=0;i<7;i++){ 
			temp=_cror_(0x7f,i);
			XXX=temp;
			DelayTime10ms(100); 		
		}
	}
}

void DelayTime10ms(unsigned int DelayValue){
	unsigned int a,b;
	for(a = 0;a < DelayValue;a++)
		for(b = 0;b < 1828;b++);	
}
  • 七、通过公式运算实现流水灯
#include 
#include 

void DelayTime10ms(unsigned int DelayValue);

void main() 
{
	unsigned int a,b; 
	for(;;){
		b=1; 
		P0=0xfe; 
		DelayTime10ms(100); 	
			
		for(a = 0;a < 7;a++{
			P0 -= b; // P0=P0-b 
			DelayTime10ms(100); 		
			b = b*2; //都化为同一类型进制运算 
		} 
	} 
}

void DelayTime10ms(unsigned int DelayValue){
	unsigned int a,b;
	for(a = 0;a < DelayValue;a++)
		for(b = 0;b < 1828;b++);	
}

你可能感兴趣的:(C51单片机)