51单片机———数码管显示

一、数码管介绍

1、数码管分类:

  静态数码管(单个,一位)  和 动态数码管(联排,2位、4位、8位)

   开发板上数码管位置如图所示:

可以看到数码管就是显示器件,用来显示数字

2、数码管定义

    是由多个发光二极管封装在一起形成“8”字形的器件

3、共阳极和共阴极数码管

   一个数码管内部的8个LED独立驱动的。如果8个LED的一端接在一起接到VCC上(负极分别接到单片机的不同引脚),这种接法就叫共阳极

反之如果8个LED一端接在一起接到GND(正极就分别接到单片机的不同引脚)就叫共阴极

两种接法都可以驱动数码管显示,但是一个是给予低电平才能亮,一个是给予高电平才能亮。总而言之,原理都一样,不管那一端默认接的是正极还是负极,只要通过程序控制另一端是低电平还是高电平(给0还是给1),使其电路完整就能点亮LED,进而获得自己想要的数字。

二、静态数码管:

1、根据原理图可知:

静态数码管一端默认为VCC(也就是高电平),所以要使静态数码管显示数字,只需要在其另一端(也就是J8引脚处给予低电平即可),同样可以看到,J8的8个引脚分别对应“8”字形的8个LED二极管(a、b、c、d、e、f、g、dp) ,所以也就是通过给予低电平来决定哪个LED灯亮进而显示出想要的数字

2、静态数码管编程示例

要想显示数字0则需要除了g和dp以外的二极管发光,所以需要给予g和dp高电平,给予其他低电平(低电平给0 高电平给1),如下:

通过杜邦线将J8与P0一一对应连接:

注意:因为P0_7至P0_0是高位到低位,所以应该是从P0_7开始读起,也就是1100 0000,转化为十六进制为0xC0

代码如下:

#include <REGX52.H>

void main()
{
	
	while(1)
	{
			P0 = 0xC0;  //1100 0000
		
	}
	
}

所以想要获得什么数字,只需要修改并查询所对应的十六进制是什么即可;

3、动态数字闪烁

如果想要得到动态的数字闪烁,只需要在循环中增加程序和延时功能即可,程序如下:

#include <REGX52.H>

void Delay(unsigned char xms)		
{
	unsigned char i, j;
	
	while(xms--)
	{
		i = 2;
	j = 239;
	do
	{
		while (--j);
	} while (--i);
		
	}

}

void main()
{
	
	while(1)
	{
		P0 = 0xC0; //显示0
		Delay(200);
		P0 = 0xF9; //显示1
		Delay(200);
		P0 = 0xA4; //显示2
		Delay(200);
		P0 = 0xB0 ; //显示3
		Delay(200);
		
	}
	
}

三、动态数码管

1、原理图:

根据对静态数码管的解释,再看动态数码管就会简单简单一些,可以清楚递看到二者的区别,虽然说静态数码管驱动简单直接,且好编程,但是它每一个LED灯都需要一个端口,所以这才有了动态数码管,可以看到动态数码管8个a位LED灯全部接在一个引脚上(此板J6给1则亮,J1给0则亮)

2、动态数码管端口

数码管有2端:COM端和段码端

COM(共极)接单片机一个IO口,多个联排数码管的COM共同接一个IO端

静态和动态数码管本质区别是:静态数码管中只要给了段码数码管就一定工作(显示只取决于段码端),动态数码管中段码端给了段码值后还需要COM端配合才能点亮数码管。

简单来说:J1操控的是8个“8”字形,相当于总开关;而J6操控的是每一个“8”字形里面的LED灯亮灭情况,需要二者配合才能成功点亮某一个位置8并且显示数字。

3、动态数码管编程示例

想要在第二个位置显示数字0:

连线如下:两组杜邦线,一组连接J1和P0端 ,一组连接J6和P1端

程序如下

#include <REGX52.H>


void main()
{
	
	while(1)
	{
		P0 = 0xBF; //1011 1111
		P1 = 0x3F; //0011 1111
		
	}
	
}

供参考:0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F   分别是0-9的表示(针对P1端)

 0x7F; 0xBF; 0xDF; 0xEF; 0xF7; 0xFB; 0xFD; 0xFE 分别是1-8的表示,决定第几个8字形亮(针对P0端)

4、动态数码管静态显示

新的问题来了,如果我想要指定某个位置的8显示某个数字,我就得重新再对重新进行修改,未免过于麻烦,所以想到使用数组和switch-case,将上面的参考数据全部装起来。

程序如下:

#include <REGX52.H>

int Number[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

void Nixie(unsigned char Location,number)
{
	switch (Location)
		{   case 1 : P0 = 0x7F;break;
			case 2 : P0 = 0xBF;break;
			case 3 : P0 = 0xDF;break;
			case 4 : P0 = 0xEF;break;
			case 5 : P0 = 0xF7;break;
			case 6 : P0 = 0xFB;break;
			case 7 : P0 = 0xFD;break;
	        case 8 : P0 = 0xFE;break;
		}

	P1=Number[number];
}

void main()
{

    Nixie(2,0); //只需要改变这里的两个数即可获得第几个位置显示什么数字,这表示第2个位置显示0)
	
	while(1)
	{
		
	}
}

5、动态数码管动态显示

在以上基础,又如何实现流动的数字呢?只需要在循环当中增贴即可:

#include <REGX52.H>

int Number[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

void Delay(unsigned char xms)		
{
	unsigned char i, j;
	
	while(xms--)
	{
		i = 2;
	j = 239;
	do
	{
		while (--j);
	} while (--i);
		
	}

}

void Nixie(unsigned char Location,number)
{
	switch (Location)
		{ case 1 : P0 = 0x7F;break;
			case 2 : P0 = 0xBF;break;
			case 3 : P0 = 0xDF;break;
			case 4 : P0 = 0xEF;break;
			case 5 : P0 = 0xF7;break;
			case 6 : P0 = 0xFB;break;
			case 7 : P0 = 0xFD;break;
	    case 8 : P0 = 0xFE;break;
		}

	P1=Number[number];
}

void main()
{
	
	while(1)
	{
		Nixie(1,1); 
		Delay(200);
		Nixie(2,2);
		Delay(200);
		Nixie(3,3);
		Delay(200);
		Nixie(4,4);
		Delay(200);
		Nixie(5,5);
		Delay(200);
		Nixie(6,6);
		Delay(200);
		Nixie(7,7);
		Delay(200);
		Nixie(8,8);
		Delay(200);
		
	}
}

效果如下:

WeChat_20240218172716

  • 52
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值