51单片机点亮数码管(二)

概念

目录

概念

一 数码管静态显示数字3

二 动态显示20230723

三 数码管动态显示移动20230723

总结:


一个数码管是由a、b、c、d、e、f、g、dp八个二极管组成,八个LED一端接在一起,另一端引脚引出来。二极管如果阳极连在一起,就是共阳极数码管,阴极连在一起,就是共阴极数码管。

如下图,是一个共阴极数码管,要使数码管显示不同的数字,只需点亮对应LED即可。如:数码管显示“0”,则a、b、c、d、e、f六个LED亮,g、dp这俩个LED灭,即可显示“0”。

//共阴数码管数字0-9的段码表
unsigned char code segCodeTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

 共阴数码管数字0-9的段码表怎么来的呢?

显示数字“0”,abcdef亮,状态值00111111——>0x3f
显示数字“1”,bc亮,状态值00000110——>0x06
显示数字“2”,abdeg亮,状态值01011011——>0x5b
显示数字“3”,abcdg亮,状态值01001111——>0x4f
显示数字“4”,bcfg亮,状态值01100110——>0x66
显示数字“5”,acdfg亮,状态值01101101——>0x6d
显示数字“6”,acdefg亮,状态值01111101——>0x7d
显示数字“7”,abc亮,状态值00000111——>0x07
显示数字“8”,abcdefg亮,状态值01111111——>0x7f
显示数字“9”,abcdfg亮,状态值01101111——>0x6f
 

 74HC138译码器也叫3-8译码器,简单来说就是三通道输入,八通道输出,通过对三通道的操作实现对八通道的控制。看原理图。
在上面的原理图中,
左边的输入通道有六个,上面的ABC分别接P2.2口,P2.3口,P2.4口,下面的G1接VCC,G2A和G2B接GND.
右边的输出通道有八个,Y0–Y7 。
所以通过对左边ABC的输入来控制右边Y0–Y7的输出。

 

一 数码管静态显示数字3

#include <REGX52.H>
#define SEGCODE P0                   //从P0口送段选

//共阴数码管段码表
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

//延时子函数
void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}

/****************************************
函数名称    :nixieTube     
函数功能    :在第location个数码管上动态显示数字number 
函数参数    :location表示数字在第几个数码管上显示,范围是1-8 
               number表示当前要显示的数字,范围是0-9
函数返回值  : 无
****************************************/
void nixieTube(unsigned char location,number)
{
	switch(location)
	{
		case 8:	P2_4=0;P2_3=0;P2_2=0;break;//输入000,输出端的第一个引脚LED1选中,低电平有效,其它引脚置高电平(01111111),第一个数码管点亮
		case 7:	P2_4=0;P2_3=0;P2_2=1;break;//输入001,输出端的第二个引脚LED2选中,低电平有效,其它引脚置高电平(10111111),第二个数码管点亮
		case 6:	P2_4=0;P2_3=1;P2_2=0;break;//输入010,输出端的第三个引脚LED3选中,低电平有效,其它引脚置高电平(11011111),第三个数码管点亮
		case 5:	P2_4=0;P2_3=1;P2_2=1;break;//输入011,输出端的第四个引脚LED4选中,低电平有效,其它引脚置高电平(11101111),第四个数码管点亮
		case 4:	P2_4=1;P2_3=0;P2_2=0;break;//输入100,输出端的第五个引脚LED5选中,低电平有效,其它引脚置高电平(11110111),第五个数码管点亮
		case 3:	P2_4=1;P2_3=0;P2_2=1;break;//输入101,输出端的第六个引脚LED6选中,低电平有效,其它引脚置高电平(11111011),第六个数码管点亮
		case 2:	P2_4=1;P2_3=1;P2_2=0;break;//输入110,输出端的第七个引脚LED7选中,低电平有效,其它引脚置高电平(11111101),第七个数码管点亮
		case 1:	P2_4=1;P2_3=1;P2_2=1;break;//输入111,输出端的第八个引脚LED8选中,低电平有效,其它引脚置高电平(11111110),第八个数码管点亮
		
	}
	SEGCODE=segCodeTable[number];//根据段码表得到要显示数字的段码
    Delay(1);				     //延时1毫秒稳定显示
    SEGCODE=0x00;				 //段码清0,消影
}

void main()
{
	while(1)
	{
		nixieTube(1,3);		//在数码管的第1位置显示3

	}
}

二 动态显示20230723

typedef unsigned char u8;
#define SEGCODE P0                   //从P0口送段选

//共阴数码管段码表
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

//延时子函数
void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}

/****************************************
函数名称    :nixieTube     
函数功能    :在第location个数码管上动态显示数字number 
函数参数    :location表示数字在第几个数码管上显示,范围是1-8 
               number表示当前要显示的数字,范围是0-9
函数返回值  : 无
****************************************/
void nixieTube(unsigned char location,number)
{
	switch(location)
	{
		case 8:	P2_4=0;P2_3=0;P2_2=0;break;//输入000,输出端的第一个引脚LED1选中,低电平有效,其它引脚置高电平(01111111),第一个数码管点亮
		case 7:	P2_4=0;P2_3=0;P2_2=1;break;//输入001,输出端的第二个引脚LED2选中,低电平有效,其它引脚置高电平(10111111),第二个数码管点亮
		case 6:	P2_4=0;P2_3=1;P2_2=0;break;//输入010,输出端的第三个引脚LED3选中,低电平有效,其它引脚置高电平(11011111),第三个数码管点亮
		case 5:	P2_4=0;P2_3=1;P2_2=1;break;//输入011,输出端的第四个引脚LED4选中,低电平有效,其它引脚置高电平(11101111),第四个数码管点亮
		case 4:	P2_4=1;P2_3=0;P2_2=0;break;//输入100,输出端的第五个引脚LED5选中,低电平有效,其它引脚置高电平(11110111),第五个数码管点亮
		case 3:	P2_4=1;P2_3=0;P2_2=1;break;//输入101,输出端的第六个引脚LED6选中,低电平有效,其它引脚置高电平(11111011),第六个数码管点亮
		case 2:	P2_4=1;P2_3=1;P2_2=0;break;//输入110,输出端的第七个引脚LED7选中,低电平有效,其它引脚置高电平(11111101),第七个数码管点亮
		case 1:	P2_4=1;P2_3=1;P2_2=1;break;//输入111,输出端的第八个引脚LED8选中,低电平有效,其它引脚置高电平(11111110),第八个数码管点亮
		
	}
	SEGCODE=segCodeTable[number];//根据段码表得到要显示数字的段码
    Delay(1);				     //延时1毫秒稳定显示
    SEGCODE=0x00;				 //段码清0,消影
}

//在8位数码管上要显示的数字表
u8 displayNumberSet[]={2,0,2,3,0,7,2,3};
void main()				    
{
	u8 i;
	while(1)
	{
		for(i=1;i<=8;i++) //在8个数码管上动态显示数字表中的8个数字
		{
			nixieTube(i,displayNumberSet[i-1]);//在第i个数码管上显示数字表中的第i个数字
		}
	}
}

三 数码管动态显示移动20230723

只需要在案列二的基础上将主函数和数组进行修改即可

//15屏移动显示的字符表(共7+8+7=22个),空格表示不显示
u8  nixietubeMoveData[]={' ',' ',' ',' ',' ',' ',' ',' ',2,0,2,3,0,6,0,6,' ',' ',' ',' ',' ',' ',' ',' '};

void main()						     
{
	u8 num;                                         //数码管显示数字的屏数,共15屏,取值为0-14
	u8 j;                                           //数码管每屏循环显示的次数,共50次,取值为0-49
	u8 i;                                           //显示数字的数码管个数,共8个,取值为1-8
	while(1)
	{
		for(num=0;num<15;num++)                       //显示15屏字符,num表示移动显示的屏数
			for(j=0;j<50;j++)                           //循环显示一屏字符50次,达到延时显示作用
				for(i=1;i<=8;i++)                         //在8个数码管上轮流显示数字
				{
					nixieTube(i,nixietubeMoveData[num+i-1]);//在第i个数码管上显示第num屏的第i个字符
				}
	}
}

总结:

数码管记住两个词,就是位选和段选
位选:其实就是控制哪一个数码管显示
段选:其实就是控制数码管显示的内容

  • 2
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,以下是51单片机点亮数码管0~99的程序: ```c #include <reg52.h> // 包含51单片机的头文件 sbit LSA = P2^2; // 数码管A引脚 sbit LSB = P2^3; // 数码管B引脚 sbit LSC = P2^4; // 数码管C引脚 sbit LED = P2^0; // 数码管段选引脚 unsigned char code DisplayTable[] = { // 0~9、A~F的编码 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71 }; void main() { unsigned char num = 0; // 数码管显示的数字 unsigned char cnt = 0; // 计数器 while (1) { // 循环执行 LED = 0; // 共阳极数码管,低电平点亮 P0 = DisplayTable[num / 10]; // 显示十位数码 LSA = 0; LSB = 0; LSC = 0; // 第一个数码管 delay(1); // 延时一段时间 LED = 1; // 灭数码管 LED = 0; // 共阳极数码管,低电平点亮 P0 = DisplayTable[num % 10]; // 显示个位数码 LSA = 1; LSB = 0; LSC = 0; // 第数码管 delay(1); // 延时一段时间 LED = 1; // 灭数码管 cnt++; // 计数器加1 if (cnt == 100) { // 显示完0~99后,重新从0开始 cnt = 0; num = 0; } else { num++; // 数码管显示的数字加1 } } } void delay(unsigned int i) { // 延时函数 unsigned int j, k; for (j = i; j > 0; j--) { for (k = 114; k > 0; k--); } } ``` 在这个程序中,我们使用P0口连接数码管的段选引脚,使用P2口连接数码管的位选引脚。程序中的`DisplayTable`数组包含了0~9、A~F的编码,`num`变量表示数码管显示的数字,`cnt`变量用于计数,`delay`函数用于延时。程序中先显示十位数码,再显示个位数码,最后将计数器加1,如果计数器达到100,则重新从0开始。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@ChenPi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值