一个流水灯就有八种方式,你觉得那种更好呢?(单片机花式点灯)

流水灯相信大家都不陌生吧,百度get到(流水灯是若干个灯泡依次点亮,视觉上感觉到灯光在流动就叫做流水灯。),就流水灯也太简单了吧,但是我想分享的是多种方式操作流水灯,例如P0,P1,P2,P3口都可以用来接LED灯。

下面我会分别使用这个四个口来操作流水的,使用不同的方式实现,其中不乏有最简单的直接付给低电平,也有使用指针来操作LED灯的控制码。相对来说还是很简单的,不多说了,来看代码。
在这里插入图片描述

1、移位函数操作流水灯
#include<reg52.h>
#include<intrins.h> //左移函数头文件 
/***********************/ 
 typedef unsigned int u16; //对数据类型声明定义,就是将 u16定义为无符号整型 ; 
 typedef unsigned char u8;
 /***********************/ 
 #define led P1 
 /****************************************************************
***************
* 函 数 名 : delay
* 函数功能 : 延时函数,i=1 时,大约延时 10us

*****************************************************************
**************/
void delay(u16 i)
{
	while(i--);
}
/***********************/ 
void main() 
{ 
  u8 i;
  led=~0x01;//0x01取反即为 0xFE
  delay(50000); //大约延时 450ms
  while(1)
	{
		for(i=0;i<7;i++)
		{
			P1=_crol_(led,1);//将 led 左移一位
			delay(50000); 
		}		
		for(i=0;i<7;i++)
		{
			P1=_cror_(led,1);//将 led 右移一位
			delay(50000); 
		}
	}
}
2、P3口操作流水灯

这里先解释一下什么是控制码,简单来说我们需要点亮LED灯就需要给这个灯输低电平。然而代码中我们一般用16进制数来表示二进制数,当芯片去读这个16进制数会自动转换从二进制。

例如
unsigned char code Tab[] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
0xfe 转化成二进制就是 1111 1110 低位为0这样第一个灯就会亮

在这里插入图片描述
下面这种方式就是属于比较笨的方法,一个一个的给低电平

#include<reg52.h>
#include<intrins.h> //左移函数头文件 
/***********************/ 
 typedef unsigned int u16; //对数据类型声明定义,就是将 u16定义为无符号整型 ; 
 typedef unsigned char u8;
 /***********************/ 
 #define led P1
 #define led P3
 /****************************************************************
***************

* 函 数 名 : delay
* 函数功能 : 延时函数

*****************************************************************
**************/
void delay(u16 i)
{
	while(i--);
}
void main(void){
while(1){

    P3 = 0xfe ;  //16 进制转换为二进制 1111 1110 第一个灯点亮,下面同理
   delay(2000); 
    P3 = 0xfd ;  //1111 1101
   delay(2000); 
    P3 = 0xfb ;  //1111 1011
   delay(2000); 
    P3 = 0xf7;   
   delay(2000); 
    P3 = 0xef;   
   delay(2000); 
    P3 = 0xdf;  
   delay(2000); 
    P3 = 0xbf;   
   delay(2000); 
    P3 = 0x7f;   
   delay(2000); 

  }

}


3、右移操作流水灯
#include<reg52.h>
//#include<intrins.h> //左移函数头文件 
/***********************/ 
 typedef unsigned int u16; //对数据类型声明定义,就是将 u16定义为无符号整型 ; 
 /***********************/ 
 #define led P1 
 /****************************************************************
***************
* 函 数 名 : delay
* 函数功能 : 延时函数
*****************************************************************
**************/
void delay(u16 i)
{
	while(i--);
}
/***********************/ 
void main() 
{ 
  unsigned char i;
  while(1){
  P1 = 0xff;
  delay(200000);
  for(i = 0;i<8;i++){
     P1 = P1>>1;//将0xff右移动以为高位就变成0 低电平LED 灯亮
     //1111 1111 右移动一位后就变成0111 1111
     delay(20000);
      
      }

   }
}
4、do -while 流水灯写法

这个写法其实是多余的,就是用的循环方式不同而已,见谅。

#include<reg52.h>
#include<intrins.h> //左移函数头文件 
/***********************/ 
 typedef unsigned int u16; //对数据类型声明定义,就是将 u16定义为无符号整型 ; 
 /***********************/ 
 #define led P3
 /****************************************************************
***************

* 函 数 名 : delay
* 函数功能 : 延时函数,i=1 时,大约延时 10us

*****************************************************************
**************/
void delay(u16 i)
{
	while(i--);
}
void main(void){
do
{
    P3 = 0xfe ;  //16 进制转换为二进制 1111 1110 第一个灯点亮,下面同理
   delay(2000); 
    P3 = 0xfd ;  //1111 1101
   delay(2000); 
    P3 = 0xfb ;  //1111 1011
   delay(2000); 
    P3 = 0xf7;   
   delay(2000); 
    P3 = 0xef;   
   delay(2000); 
    P3 = 0xdf;  
   delay(2000); 
    P3 = 0xbf;   
   delay(2000); 
    P3 = 0x7f;   
   delay(2000); 

  }while(1);

}
5、字符数组控制P0口流水灯

这种使用将控制码放在数组中的方式就会让代码显得很优雅,嘻嘻。

#include<reg52.h>
/***********************/ 
 typedef unsigned int u16; //对数据类型声明定义,就是将 u16定义为无符号整型 ; 
 #define led P0 
 /****************************************************************
***************
* 函 数 名 : delay
* 函数功能 : 延时函数
*****************************************************************
**************/
void delay(u16 i)
{
	while(i--);
}

void main(void){
  unsigned char i;
  unsigned char code Tab[] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
  while(1){
  	for(i = 0;i<8;i++){
  		P0 = Tab[i];
  		delay(2000);
	  }
  }
}
6、指针数组控制P0 口流水灯

使用指针的优势恐怕现在是不能凸显出来,如果对比的同学应该知道正确使用指针后代码执行数度贼快,哈哈哈。

#include<reg52.h>
/***********************/ 
 typedef unsigned int u16; //对数据类型声明定义,就是将 u16定义为无符号整型 ; 
 #define led P0 
 /****************************************************************
***************
* 函 数 名 : delay
* 函数功能 : 延时函数
*****************************************************************
**************/
void delay(u16 i)
{
	while(i--);
}
void main(void){
  unsigned char i;
  unsigned char code Tab[] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
  unsigned char *P[] = {&Tab[0],&Tab[1],&Tab[2],&Tab[3],&Tab[4],&Tab[5],&Tab[6],&Tab[6],&Tab[7]};
  while(1){
  	for(i = 0;i<8;i++){
  		P0 = *P[i];
  		delay(2000);
	  }
  }
}
7、数组的指针控制P0口流水灯

这个要仔细看就会发现和上面第6种方法的区别,指针在数组种的使用方法有很多种。

#include<reg52.h>
/***********************/ 
 typedef unsigned int u16; //对数据类型声明定义,就是将 u16定义为无符号整型 ; 
 #define led P0 

 /****************************************************************
***************
* 函 数 名 : delay
* 函数功能 : 延时函数
*****************************************************************
**************/
void delay(u16 i)
{
	while(i--);
}

void main(void){
  unsigned char i;
  unsigned char code Tab[] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//流水灯控制码 
  unsigned char *P
  P = Tab;
  while(1){
  	for(i = 0;i<8;i++){
  		P0 = *(p+i);//*(p+i)相当于a[i],通过指针引用数组元素 
  		delay(2000);
	  }
  }
}


8、指针作为参数控制流水灯

这里就是用函数来操作控制码,毕竟模块化编程还是需要了解的。

#include<reg52.h>
/***********************/ 
 typedef unsigned int u16; //对数据类型声明定义,就是将 u16定义为无符号整型 ; 
 #define led P0 
 /****************************************************************
***************
* 函 数 名 : delay
* 函数功能 : 延时函数
*****************************************************************
**************/
void delay(u16 i)
{
	while(i--);
}
void led_flow(unsigned char *p){
    unsigned char i;	
	 while(1){
  	for(i = 0;i<8;i++){
  		P0 = *(p+i);//*(p+i)相当于a[i],通过指针引用数组元素 
  		delay(2000);
	  }
    }
} 
void main(void){
  unsigned char code Tab[] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//流水灯控制码 
  unsigned char *P;
  P = Tab;
  led_flow(p);//调用函数传入指针
}

以上就是我总结的关于流水灯的操作方式,可能代码中会有小错误,但是相信都开始学单片机的同学还是有一定的编程能力,一定能找出我写的bug哈哈哈。

posted @ 2020-11-07 16:24  茶凡_Matrix  阅读(20)  评论(0编辑  收藏  举报  来源