实验三LED计数静动态显示(附代码和电路图)

需知道:

LED的特性是什么?共阳极与共阴极的区别?什么是段码?段码是怎么计算的(自己可以推断共阴极或共阳极的段码)?段码与位选的区别?7段LED显示的字符分别有哪些?自己能够写得出吗?能够区分静态显示与动态显示吗?

实验要求:

​ 编程控制单片机驱动一个八位一体LED数码管和一个开关,实现:开关拨上实现八个LED数码管同时循环显示“0,1,2……E,F”等十六个字符。开关拨下时,实时切换八个LED数码管显示状态为同时显示八个不同的数字,例如“12345678”。当开关再次拨上时,将继续切换前的字符往下同时循环显示“0,1,2……E,F”等十六个字符。

实验工具:

仿真软件:proteus8.0

软件:keil4

提示:高版本的可以打开低版本的,但是低版本打不开高版本的。

实验步骤

实验电路

实验三LED计数静动态显示(附代码和电路图)_第1张图片

元件简要介绍:

元件名称 图片 备注
7SEG-MPX8-CC—BLUE 实验三LED计数静动态显示(附代码和电路图)_第2张图片 MPX表示多位一体,8表示8位
RESPACK—8 实验三LED计数静动态显示(附代码和电路图)_第3张图片 8个可以连接的引脚,1号引脚连接电源,2-9号引脚连接单片机的P0接口,可做上拉电阻用
SW-SPDT 实验三LED计数静动态显示(附代码和电路图)_第4张图片
AT89C51 实验三LED计数静动态显示(附代码和电路图)_第5张图片

软件源代码:

版本1

此代码参考了 参考链接

#include 
#define uchar unsigned char 
sbit DI1=P0^0; //定义8位数码管位选信号 
sbit DI2=P0^1; 
sbit DI3=P0^2; 
sbit DI4=P0^3; 
sbit DI5=P0^4; 
sbit DI6=P0^5; 
sbit DI7=P0^6; 
sbit DI8=P0^7; 
//定义输入端的信号端口
sbit sw=P1^7; 

void delay(uchar x) //定义延时函数 
{ 
	uchar j; 
	while(x--)
	{ 
		for(j=0;j<125;j++); 
	} 
} /*定义数码管显示字符跟数字的对应数组关系*/ 

unsigned char code dis[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F ,0x77,0x7c,0x39,0x5e,0x79,0x71};

 void main() 
 { 
	char i,k=0;
 	 while(1)
	{
 	if(sw==1)
		   {
	  			for(i=0;i<=15;i++)
	     		{	 	
		 			P0=0x00;
	   	 			P3=dis[k%16];
					if(sw!=1)
					break;
	   	 			delay(500);
					k++;
	 			}
	 		}
	
					
		
		  else
				{	  
				  P3=0x00; //P0口初始化 
						DI1=0; //第一位数码管位选 
						 	P3=dis[1]; //第一位数码管显示0 
						 	delay(5); 
						 	DI1=1; //关闭第一位数码管位选 
						 
						 	DI2=0; //第二位数码管位选 
						 	P3=dis[2]; //第二位数码管显示1 
						 	delay(5); 
						 	DI2=1; //关闭第二位数码管位选 
						 	
							DI3=0; //第三位数码管位选 
						 	P3=dis[3]; //第三位数码管显示2 
						 	delay(5); 
						 	DI3=1; //关闭第三位数码管位选 
						 
						 	DI4=0; //第四位数码管位选 
						 	P3=dis[4]; //第四位数码管显示3 
						 	delay(5); 
						 	DI4=1; //关闭第四位数码管位选 
						   
						    DI5=0;
						   P3=dis[5];
						   	delay(5);
							 DI5=1;

					    	DI6=0;  //6位
						   P3=dis[6];
						   	delay(5);
							 DI6=1;
							//7位
							 DI7=0;
						   P3=dis[7];
						   	delay(5);
							 DI7=1;
							
							 DI8=0;	  //8位
						   P3=dis[8];
						   	delay(5);
							 DI8=1;
						}	 
				
		}	
	
}

看到版本2的代码,会觉得这个代码行数过多。而且在else里的代码有很多循环的,可以利用通式将其替换。

版本2:

#include 
#include 
 sbit  sw=P1^7; 
 //段码	,code存储在RAM中,访问速度快
unsigned char code dis[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F ,0x77,0x7c,0x39,0x5e,0x79,0x71};

//延时函数
 void delay(unsigned int time)
 {	unsigned int i;
     for(;time>0;time--)
	 for(i=125;i>0;i--);		   
 }

//主函数
 void main()
{	unsigned char bit_scan[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//每次亮一个灯   
		unsigned char  i,j,k=0;
	while(1)
	{
 		if(sw==1) //开关拨上    
		{ 
		   	for(j=0;j<16;j++)
	 		{ 	
	 			P0=0x00;//位码。LED全部亮
	 			P3=dis[k%8];
	    		if(sw!=1)//开关拨下,退出循环
	    		break;
				delay(500);	//无它不显示其他的数字
				k++; //标记
		   	}	
		}
		
		else
		{	
		 for(i=0;i<8;i++)
			{
  		 		P0=bit_scan[i]; 
   				P3=dis[i+1];
  				delay(5);	
			}
 		}
	 }
 }

遇到的问题

问题1

WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
不影响运行,只是说你定义的函数没有调用而已

解决办法:不用管

问题2

多次修改代码,然后就提示

--- Error: failed to execute 'D:\program files\单片机开发工具\Keil4\C51\BIN\C51.EXE'

然后按照提示的路径,查看文件,发现自己没有BIN文件(之前没有注意看,同学有这个文件,所以就默认自己有吧)

解决办法参考1.1:https://blog.csdn.net/qq_24835087/article/details/87929636

解决办法参考1.2:http://www.myexceptions.net/ai/1918822.html

解决办法参考1.3:https://www.cnblogs.com/shareidea/p/5273158.html

1.1未解决,复制了同学的BIN文件到安装路径,结果还是不行。

1.2未解决,在RealView Folder里选择keil安装目录下的C:\Keil\ARM\ARMCC\bin,点OK后就可以正常使用了里根本浏览不了路径

1.3,解决了。路径\Keil4\

问题3

如果将版本2的代码,稍微改一下,即开关拨上拨下各自弄个函数。那么实验要求里的当开关再次拨上时,将继续切换前的字符往下同时循环显示“0,1,2……E,F”等十就实现不了。为什么会出现这样的效果,我没有弄清楚

#include 
#include 
 sbit  sw=P1^7; 
 //段码	,code存储在RAM中,访问速度快
unsigned char code dis[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F ,0x77,0x7c,0x39,0x5e,0x79,0x71};

//延时函数
 void delay(unsigned int time)
 {	unsigned int i;
     for(;time>0;time--)
	 for(i=125;i>0;i--);		   
 }
 //开关拨上函数
 void hight()
 {  unsigned char j,k=0;
 			//P0=0x00;//在这个位置LED不亮
 	   	for(j=0;j<16;j++)
	 	{ 	P0=0x00;//位码。LED全部亮
	 		P3=dis[k%16];
	    	if(sw!=1)//开关拨下,退出循环
	    	break;
			delay(500);	//无它不显示其他的数字
				k++; //标记
		   }
 }

 //开关拨下函数
void low()
{  unsigned char bit_scan[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//每次亮一个灯	
	unsigned char  i;
  for(i=0;i<8;i++)
{
   P0=bit_scan[i]; 
   P3=dis[i+1];
  delay(5); 
  if(sw!=0)
  break;
   }
} 
//主函数
 void main()
{	 
	while(1)
	{
 		if(sw==1) //开关拨上    
		{ 	hight();}
		
		else
		{low();}	
 	
    }
 }

最后

欢迎各位评论,指教!

你可能感兴趣的:(单片机学习,单片机)