ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

上传的实验三LED计数显示

2021-03-30 18:02:41  阅读:472  来源: 互联网

标签:char P0 LED unsigned 拨上 计数 sbit 上传


需知道:

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

实验要求:

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

实验工具:

仿真软件:proteus8.0

软件:keil4

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

实验步骤

实验电路

仿真电路图

元件简要介绍:

元件名称图片备注
7SEG-MPX8-CC—BLUEMPX表示多位一体,8表示8位
RESPACK—88个可以连接的引脚,1号引脚连接电源,2-9号引脚连接单片机的P0接口,可做上拉电阻用
SW-SPDT
AT89C51AT89C51图片

软件源代码:

版本1

此代码参考了 参考链接

#include<reg51.h> 
#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 <REGX51.H>
#include <intrins.h>
 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 <REGX51.H>
#include <intrins.h>
 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();}	
 	
    }
 }

最后

欢迎各位评论,指教!

标签:char,P0,LED,unsigned,拨上,计数,sbit,上传
来源: https://blog.csdn.net/weixin_45706406/article/details/115331736

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有