江科大51单片机——第4节、数码管显示

2024年八月六号,编写

这一节老师教了两个实验:4-1 静态数码管显示

                                           4-2 动态数码管显示

        如图4-1所示,数码管其实就一个显示器。LED就是发光二极管;LED数码管也就是由多个发光二极管封装在一起的显示器。

图4-1

1、单个数码管引脚定义

        数码管的接法,有共阳和共阴之分。我们使用的51单片机的数码管接法为共阴接法,如图4-2所示,图片的8个LED(发光二极管)都接在了引脚3和8上面。其中上面是发光二极管的负极接在了引脚3和8上面,这种数码管接法就属于共阴接法;下面是发光二极管的正极接在了引脚3和8上面,这种数码管接法就属于共阳接法。

        共阴接法,如果给引脚3和8高电平,则LED则永远不亮;共阳接法,如果给引脚3和8低电平,则LED则永远不亮;

图4-2

        如图4-3左图所示,数码管为共阴接法时(表示数码管里面的发光二极管的接法),位选(决定那数码管亮)处给低电平(位寄存器给0),段选(一个数码管有8个LED,有8段)处给高电平(位寄存器给1),这一段的LED才会亮。数码管为共阳极接法,如图4-3右图,原理一样。

图4-3

        段选,如图4-4所示,一个数码管有8个LED灯,分别是:A、B、C、D、E、F、G、DP,这8个(也叫8段)LED,段选是为了控制这些段LED亮或者灭,让这些段形成想要的数字。

图4-4

2、开发板四位一体的数码管引脚定义

        前面说的是一个数码管,这里讲的是4个数码管连在一起。那么就会有4个共阴或者共阳引脚点。4个数码管的每一段都是对应的接在同一个引脚,比如4个数码管的A段LED接在一起、B段LED接在一起等,如图4-4所示。这样就会导致,不同的数码管会显示相同的数字,所以得用延时函数,通过在while循环中快速的换数字(也就是说,数字停留的时间小于人眼观察的时间,这样我们就会观察不到数字波动)。

        如图4-4所示,以共阴接法为例,通过给引脚12、9、8、6高电平或者低电平(位寄存器1/0),就可以选择哪个数码管亮,比如如果想让引脚8对应的数码管亮,其他的数码管暗,我们可以让引脚8的位寄存器值为0,其他的共阴引脚为1。

图4-4

3、原理图

        先尝试自己分析下原理图4-5和4-6,然后再去看下面的解答。

图4-5

图4-6

        在单片机数码管项目过程中,一般都是如图4-7所示,通过控制8个数码管,来实现哪些数码管亮并且显示哪个数字。我们用的51单片机,数码管采用共阴接法,所以要想让数码管亮,则位寄存器为0,低电平。

图4-7

        如图4-8所示,位选。位选:也就是选择哪一个数码管亮。从图中,我们可以看到用三个接口(P2_1、P2_2、P2_3)来控制8个LED灯(并没有按照一一对应的那种控制),这样可以节约接口,二进制(111)刚好可以控制8个灯。一定要注意高位对高位,数据的高位对应二极管的高位,比如:P2_4(C)对应位寄存器的值位1、P2_3(B)对应位寄存器的值位0、P2_4(A)对应位寄存器的值位0,则二进制为100,相当于数字4,则点亮LED5。

        注意,二进制000,点亮的是LED1。

        图中的G1、G2A、G2B,这块板子的开发人员已经为我们接好对应的高电平和低电平了,单片机通电就会自动工作,承担使能的作用。

图4-8

        如图4-9所示,段选。段选:也就是让数码管显示具体的数字。从图中我们可以看到通过P0接口对LCD进行一一对应的控制。单片机中:一定要注意高位对高位,也就是数据的高位对应二极管的高位。正如图中所示,想让数码管显示数字6,也就是让B段LED和DP段LED不亮,其他段都亮。我们可以让B段LED和DP段LED处的位寄存器值位0,因为最下面是P0_7,所以数据的最高位是P0_7所对应位寄存器的值,二进制应该是0111 1101,对应十六进制应该是0x7D。

图4-9

        如图4-10所示,使用注意:数码管接法为共阴接法的数码管断码表,比如:想让数字0显示在数码管上面,直接使用十六进制0x3F(令P0=0x3F)。也就是说,上面为想显示的数字或者字母,下面则是P0等于十六进制的程序就行了,属于程序就会显示。

图4-10

5、函数与数组

图4-11

图4-12

如下图:子函数,无参数,无返回值

图4-13

如下图:子函数,有参数x,无返回值。如果主函数中给x=8,则子函数中输出8,在主函数中也会输出8。

图4-14

如下图:子函数,有参数x,有返回值。a=子函数的整个函数值(整个函数体),也就是返回值6,所以a=6。

图4-15

4-1 静态数码管显示

如图4-9所示,数码管位置从左到右依次是:LED8、LED7、LED6...LED1。

所以,想要让第一个数码管显示数字,实际上是让LED8亮,所以代码中P2_4=1,P2_3=1,P2_2=1。

#include <REGX52.H>
unsigned char NiXieTube[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void NiXie(unsigned char Location,Number)
{
	switch(Location)
	{
		case 1:P2_4=1;P2_3=1;P2_2=1;break;
		case 2:P2_4=1;P2_3=1;P2_2=0;break;
		case 3:P2_4=1;P2_3=0;P2_2=1;break;
		case 4:P2_4=1;P2_3=0;P2_2=0;break;
		case 5:P2_4=0;P2_3=1;P2_2=1;break;
		case 6:P2_4=0;P2_3=1;P2_2=0;break;
		case 7:P2_4=0;P2_3=0;P2_2=1;break;
		case 8:P2_4=0;P2_3=0;P2_2=0;break;
	}	
	P0=NiXieTube[Number];
}
void main()
{
	NiXie(6,6);
	while(1)
	{
		
	}
}

4-2 动态数码管显示

需要循环扫描,while()循环中编写;

需要加入延时函数;

#include <REGX52.H>

unsigned char NiXieTube[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void NiXie(unsigned char Location,Number)
{
	switch(Location)
	{
		case 1:P2_4=1;P2_3=1;P2_2=1;break;
		case 2:P2_4=1;P2_3=1;P2_2=0;break;
		case 3:P2_4=1;P2_3=0;P2_2=1;break;
		case 4:P2_4=1;P2_3=0;P2_2=0;break;
		case 5:P2_4=0;P2_3=1;P2_2=1;break;
		case 6:P2_4=0;P2_3=1;P2_2=0;break;
		case 7:P2_4=0;P2_3=0;P2_2=1;break;
		case 8:P2_4=0;P2_3=0;P2_2=0;break;
	}	
	P0=NiXieTube[Number];
}
void main()
{
	
	while(1)
	{
		NiXie(1,1);	
		NiXie(2,2);	
		NiXie(3,3);	
	}
}

        上面代码数码管的数字跑到其他的数码管上面,数字重叠,也就是说会有篡位;所以数码管需要消除影子(消影

图4-16

解决方法如下所示:

图4-17

图4-18

#include <REGX52.H>
void Delay(unsigned char xms)		//@12.000MHz
{
	unsigned char i, j;
	while(xms--)
	{
		i = 12;
		j = 169;
		do
		{
			while (--j);
		} while (--i);
	}
}
unsigned char NiXieTube[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void NiXie(unsigned char Location,Number)
{
	switch(Location)
	{
		case 1:P2_4=1;P2_3=1;P2_2=1;break;
		case 2:P2_4=1;P2_3=1;P2_2=0;break;
		case 3:P2_4=1;P2_3=0;P2_2=1;break;
		case 4:P2_4=1;P2_3=0;P2_2=0;break;
		case 5:P2_4=0;P2_3=1;P2_2=1;break;
		case 6:P2_4=0;P2_3=1;P2_2=0;break;
		case 7:P2_4=0;P2_3=0;P2_2=1;break;
		case 8:P2_4=0;P2_3=0;P2_2=0;break;
	}	
	P0=NiXieTube[Number];
	Delay(1);//延迟1毫秒,让数字显示更稳定,不然数字亮度会暗
	P0=0x00;//清零
}
void main()
{
	
	while(1)
	{
		NiXie(1,1);	
		NiXie(2,2);	
		NiXie(3,3);
		
	}
}

        本文用的就是单片机直接扫描:会耗费大量的单片机CPU时间,会遇到闪烁、不显示的问题

        专用驱动芯片(比如:TM1640)

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值