51单片机编程应用(C语言):数码管

目录

1.数码管原理

一位数码管引脚定义:

四位一体数码管:

多个数码管同时显示不同数字 

51单片机的数码管的原理图

51单片机实现静态显示和动态显示

静态显示:

 动态显示:


1.数码管原理

一位数码管引脚定义:

数码管是由8个LED组成的,其中共阴极数码管是8个LED共用一个阴极;共阳极数码管是8个LED共用一个阳极;每个数码管灯由图中左下角的8段LED构成,分别是ABCDEFG以及DP;正好和1个字节的8位相对应;从图中也可以看出,8段LED中,每段LED对应的引脚图,即每段LED和引脚之间的连接关系,基本是按照就近原则来连接的,比如A段,A段的正极连接3和8引脚(在共阳极数码管的情况下),A段的负极连接7号引脚;以此类推,其他引脚关系都可从图中看出来。

值得注意的是,我们开发板上的连接方式是共阴极连接。
如果想要使这个数码管显示数字“6”,该怎么操作呢?需要让A、F、E、D、C、G都亮起来即可。那么如何使A、F、E、D、C、G都点亮,其他的熄灭呢?参照上面的图可知,对于共阴极连接方式,首先3和8引脚都是要接地的(即负极、低电平、0);然后A、F、E、D、C、G都接正极(高电平,1),B和DP接负极,这样就能得到一个数字“6”,即A、B、C、D、E、F、G、DP设置为1011 1110;

下面为proteus仿真视频

proteus单个数码管仿真

实现9到0依次循环,代码如下 :

#include <REGX52.H>
void Delay(unsigned int xms)
{unsigned char i, j;while(xms--){i = 2;j = 239;do{while (--j);} while (--i);}
}
void main()	
{while(1){P2=0x6F;Delay(500);P2=0x7F;Delay(500);P2=0x07;Delay(500);P2=0x7D;Delay(500);P2=0x6D;Delay(500);P2=0x66;Delay(500);P2=0x4F;Delay(500);P2=0x5B;Delay(500);P2=0x06;Delay(500);P2=0x3F;Delay(500);}
}

因为我是P2-7接的是G,P2-6接的是F..........反过来的,所以根据上面的引脚图要反着来计算二进制的值。

四位一体数码管:

可以看到,以共阴极数码管为例,每个数码管共用阴极,但是四个数码管阳极所有的对应引脚都是连接同一个引脚;例如这四个数码管的A段LED都是连接在一起的,和11引脚相连;这四个数码管的B段LED都是连接在一起的,和7引脚相连。这样做的好处是节省单片机的引脚,如图中有4*8=32个LED段,但是只用12个引脚就可以了。
对于这种数码管,如果想让第三位数码管显示一个数字1,怎么操作?

因为是共阴极,所以12、9、8、6正常来讲都是负极才能点量对应的数码管。要想达到只第三个数码管显示1的目的:其中引脚12、9、6这三个阴极都置为1(高电平),这样第一、二、四个数码管就都不会亮;将引脚8设置为0(低电平),这样第三个数码管就有了电路连通的条件;然后再将B断和C段对应的引脚置为高电平,即7和4引脚置为1(高电平),此时就能第三个数码管中的B和C段对应的LED灯就亮了,其他段的灯不亮,即达到了只第三个数码管显示1的目的。

proteus仿真如下:

代码是P2=0x60;我这里P2.7接的是A,根据这两个例子,P2的值赋值是不是要看数码管的A,B,C,D.....与P2的8个引脚怎么接才行,这里P2.7接A,依次下去,亮一,就赋值P2=0x60。

比如P2.0接A,亮1就赋值0x06,所以一定要看自己的单片机原理图是如何接的,还要看是共阴极还是共阳极,

下面我就给出两种情况显示各个数字的值(小数点dp都不点亮)(共阴极数码管)

第一种:P2.0接A,依次接下去,(例如视频所示)

第二种:P2.7接A,依次接下去:(例如上面图所示) 

0  :  0xFE     1:     0x60         2:      0xDA       3:       0xF2        4: 0x66       5:         0xB6  

6   :   0xBE     7  :     0xD0       8:      0xFE       9:        

多个数码管同时显示不同数字 

 

关于上面讲到的,这四个数码管四个数码管阳极所有的对应引脚都是连接同一个引脚,这样导致的结果是,如果我们想让第二个数码管和第三个数码管同时点亮,且第二个和是第三个数码管显示不同的数字,是无法做到的,因为即使为了让第二个数码管亮而将9号引脚置为0,那么此时9和8引脚都为0,7和4引脚都为1,结果是第二个二极管和第三个二极管都显示数字1,无法达到显示不同数字的目的;所以因为四个二极管对应段LED都共用同一个引脚,导致的结果是只能显示同样的数字。

那么如何使不同的数码管显示不同的数字呢?这就是我们的目标2要实现的了,即动态数码管显示;利用的原理是人眼的视觉暂留和数码管显示的余晖原理;比如我们想达到让前三个数码管分别显示“1”“2”“3”的目的,经过上面的理论我们可以知道让三个数码管同时显示三个不同的数字是不可能的,但是我们可以让第一个数码管显示数字1,然后迅速的让第二个数码管显示数字2,然后迅速的让第三个数码管显示数字3,这要他们的间隔足够短,在我们视觉上看起来就像是同时在显示1、2、3一样。

#include <REGX52.H>//数码管段码表
unsigned char NixieTable[]={0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xD0,0xFE,0xF6};//延时子函数
void Delay(unsigned int 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_0=1;P0_1=1;P0_2=1;P0_3=1;break;//4个数码管都不选case 2:P0_0=1;P0_1=1;P0_2=1;P0_3=0;break;//选择第四个数码管case 3:P0_0=1;P0_1=1;P0_2=0;P0_3=1;break;//选择第三个数码管case 4:P0_0=1;P0_1=1;P0_2=0;P0_3=0;break;//选择第3和第4个数码管case 5:P0_0=1;P0_1=0;P0_2=1;P0_3=1;break;//选择第二个数码管case 6:P0_0=1;P0_1=0;P0_2=1;P0_3=0;break;//选择第2和第4个数码管case 7:P0_0=1;P0_1=0;P0_2=0;P0_3=1;break;//选择第2和第3个数码管case 8:P0_0=1;P0_1=0;P0_2=0;P0_3=0;break;//选择第2和第3和第4个数码管case 9:P0_0=0;P0_1=1;P0_2=1;P0_3=1;break;//选择第一个数码管case 10:P0_0=0;P0_1=1;P0_2=1;P0_3=0;break;//选择第1和第4个数码管case 11:P0_0=0;P0_1=1;P0_2=0;P0_3=1;break;//选择第1和第3个数码管case 12:P0_0=0;P0_1=1;P0_2=0;P0_3=0;break;//选择第1和第3和第4个数码管case 13:P0_0=0;P0_1=0;P0_2=1;P0_3=1;break;//选择 1 2 号数码管case 14:P0_0=0;P0_1=0;P0_2=1;P0_3=0;break;//选择1 2 4  号数码管case 15:P0_0=0;P0_1=0;P0_2=0;P0_3=1;break;//选择1 2 3 号数码管case 16:P0_0=0;P0_1=0;P0_2=0;P0_3=0;break;//四个数码管全选}P2=NixieTable[Number];	//段码输出Delay(1);				//显示一段时间P2=0x00;				//段码清0,消影
}void main()
{while(1){Nixie(9,1);		//在数码管的第1位置显示1
//		Delay(20);Nixie(5,2);		//在数码管的第2位置显示2
//		Delay(20);Nixie(3,3);		//在数码管的第3位置显示3
//		Delay(20);Nixie(2,0);	}
}

注意: 虽然我switch case 把所有的情况都列出来了,也就是位选的所有情况,但是,动态扫描时,一个数码管是显示一位数字,所以尽量要选择单个数码管,代码中的case9 5 3 2。如果你选中的是多个数码管,那么他只会显示相同的数字,而且,你选中多个数码管时,main语句时要注意不要重复选中相同的数码管,比如不能同时选择case7 8,否则会出错,下图所示是选择4个数码管一起亮,显示5:

 代码是:Nixie(16,5);

上面是用了C语言的数组,和switch case语句,调用函数,我们讲一下数组就OK了,switch case 还是很好理解的

 有了这些基础,我们看看51单片机的数码管的相关原理图

51单片机的数码管的原理图

 

显然,8个数码管的位选(选择哪一个数码管亮)由单片机3个引脚控制,这样的好处大大缩小了引脚的数量,不用每一个LED对应一个引脚。下面我们讲一讲38译码器电路。

38译码器是三个线到八个线的译码器;其实就是负责将三个输入A、B、C(P22-P24)转成八个输出Y0-Y7(也对应LED1-8);A、B、C三个输入值分别表示为三个二进制的数(C为高位,B为中位,A为低位,即数字组成为CBA),这三个输入值,转换成十进制,就对应他们的输出。

例如输入A为0,B为0,C为0,则输入为000,其对应的十进制值是0,即Y0有效,其他无效(低电平为有效,高电平位无效),所以Y0是0,Y1-Y7为1;

再例如,如果输入A为1,B为0,C为0,则输入为001(CBA,前面说了,C为高位,B为中位,A为低位),其对应的十进制为1,即Y1有效,其他无效(低电平为有效,高电平位无效),所以Y1是0,Y0和Y2-Y7为1;刚好对应我们的8个数码管,
以此类推。。。。

其真值表如下所示

有了这些知识,比如我们要选中第三个数码管亮,LED(1~8)的值是 

对应38译码器是不是 101  P2_4=1,P2_3=0,P2_2=1,即可

下面我们再来看数74HC245(双向据缓冲器)

根据原理图我们是不是知道,数码管的段选都与这个芯片连接,即晶体管的正极是接在74HC245(双向数据缓冲器)上的。为什么不直接接在CPU上呢?还要多此一举呢?

因为单片机的高电平驱动能力太弱,这个缓存器提高驱动能力。这样单片机的I/O口就变成了控制信号,不需要很高的电流驱动,把数据给了这个芯片之后,这个芯片有VCC给他供电,就很好的驱动数码管,亮度得到了保证。

DIR的高低电平决定了数据的流向;在74HC245中,如果将DIR,也就是LE(1引脚)设置为高电平,则表示数据流向为从左边到右边。由下图可知,A0对应B0,A1对应B1,以此类推;而B0-B7对应LCD0-7;

总结一下说就是,输入给P00-P07什么数据,该数据就原封不动的送给LCD0-LCD7。 

电容的作用:给VCC滤波,稳定电源,确保电路稳定性。提高电路工作性能。

电阻:限流

  74HC245作用:双向的数据缓冲 

51单片机实现静态显示和动态显示

静态显示:

第二个数码管显示5

第一步是选择使哪个晶体管点亮:即要让目标点亮的等负极有效,而负极是接在138译码器上的,138译码器的8输出连接着静态数码管的负极,138译码器的3个输入连接着MCU的引脚(P22-P24口);所以我们要通过对P22-P24口的设置,来控制目标晶体管负极有效。

第二步是设置该目标点亮的晶体管具体显示什么数字;即通过对正极引脚的设置,控制具体LED的8段LED哪几段点亮,用以生成目标数字。晶体管的正极是由74HC245的P00-P07等8个引脚来输入的;

总结:

  • 第一步,选择哪个晶体管点亮,控制引脚为P22-P24;
  • 第二步,选择具体点亮的数字,控制引脚为P00-P07;
#include <REGX52.H>void main()	
{while(1){P2_2=0;P2_3=1;P2_4=0;P0_0=1;P0_1=0;P0_2=1;P0_3=1;P0_4=1;P0_5=1;P0_6=1;P0_7=0;}
}

最后,我们可以对代码进行完善,写一个函数,两个入参分别为:第一个参数为第几个等亮,第二个参数为显示什么数字,这样就能通过调用该函数时,传入参数的不同,控制不同的灯显示不同的数字,代码如下: 

#include <REGX52.H>//数码管段码表
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//数码管显示子函数
//Location表示第几个数码管点亮;Number表示该数码管显示什么数字
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=NixieTable[Number];	//段码输出
}void main()
{Nixie(2,5);	//在数码管的第3位置显示数字6while(1){}
}

 动态显示:

实现动态数码管的方法和代码,即如果想让第一个数码管显示1,第二个数码管显示2,第三个数码管显示3,且让他们同时显示;方法就是先让第一个显示1,然后立马让第二个显示2,再立马让第三个显示3;只要他们之间的间隔足够短,在我们视觉效果上看来就是在同时显示。

代码如下

#include <REGX52.H>//数码管段码表
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);}
}//数码管显示子函数
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=NixieTable[Number];	//段码输出Delay(1);				//显示一段时间P0=0x00;				//段码清0,消影
}void main()
{while(1){Nixie(1,1);		//在数码管的第1位置显示1
//		Delay(20);Nixie(2,2);		//在数码管的第2位置显示2
//		Delay(20);Nixie(3,3);		//在数码管的第3位置显示3
//		Delay(20);}
}

其中的P0=0x00;表示每次循环结束时都将所有的数码管进行清零,即全部熄灭,免得留下灯的残影。

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/249833.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Git版本管理工具(实战进阶):零基础到起飞实战项目完整篇 →Git学习一篇就够 从基本指令、到本地仓库、远程仓库、实战项目开发演练介绍超详细!

heima 李师傅最新版 Git的讲解 文章目录 Git在实战项目开发使用功能学习01.Git 初识02.Git 仓库03.Git 的三个区域04.Git 文件状态05.Git 暂存区作用06.练习-登录页面07.Git-切换版本08.删除文件09.忽略文件10.分支的概念11.练习-登录 bug 修复12.分支-合并与删除13.分支-合并与…

测试ASP.NET Core项目调用EasyCaching的基本用法(Redis)

EasyCaching中的包EasyCaching.Redis和EasyCaching.CSRedis都支持集成Redis实现缓存&#xff0c;前者基于StackExchange.Redis&#xff0c;而后者基于CSRedisCore&#xff0c;本文学习使用EasyCaching.Redis包连接redis服务实现缓存的基本用法。   新建WebApi项目&#xff0c…

github请求超时解决方法

github请求超时解决办法 我使用windows执行如下git命令,提示超时 git clone xxxxx命令行提示如下&#xff1a; Failed to connect to github.com port 443: Timed out问题排查 可我Chrome可以正常访问github甚至ChatGPT&#xff0c;但是为什么在命令行里面却无法访问&#…

云上自动部署丨使用 Terraform 在 AWS 上搭建 DolphinDB

HashiCorp Terraform 是一款基础架构即代码工具&#xff0c;旨在实现 "Write, Plan, and Create Infrastructure as Code"。它通过配置文件来描述云资源的拓扑结构&#xff0c;包括虚拟机、存储账户和网络接口。Terraform 几乎支持市面上所有的云服务&#xff0c;能够…

光学3D表面轮廓仪服务超精密抛光技术发展

随着技术的不断进步&#xff0c;精密制造领域对材料表面的处理要求越来越高&#xff0c;超精密抛光技术作为当下表面处理的尖端技术&#xff0c;对各种高精密产品的生产起到了至关重要的作用&#xff0c;已广泛应用于集成电路制造、医疗器械、航空航天、3C电子、汽车、精密模具…

面试经典 150 题 -- 滑动窗口 (总结)

面试经典150题链接 面试经典 150 题 - 学习计划 - 力扣&#xff08;LeetCode&#xff09;全球极客挚爱的技术成长平台 209 . 长度最小的子数组 思路 : 滑动窗口的思想&#xff0c;取ij0,向后遍历j,记录前缀和[l,r]为s,如果s>target,那么左端点向右移动&#xff0c;直到s…

2022 年全国职业院校技能大赛高职组云计算赛项试卷

【赛程名称】云计算赛项第二场-容器云 说明&#xff1a; 完成本任务需要两台安装了 CentOS7.9 操作系统的云主机&#xff1a; master 和 node。Chinaskill_Cloud_PaaS.iso 镜像包中有本次容器云部署所需的所有文件&#xff0c;运维所需的文件见附件。 某公司技术部产品开发上线…

HTML+CSS+JS的3D进度条

<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>HTMLCSSJS的3D进度条</title><style>…

JavaWeb前端——HTML/CSS

HTML/CSS概述 HTML&#xff1a;学习标签&#xff0c;CSS&#xff1a;学习样式 HTML 1. 不区分大小写。 2. 属性可以使用单引号/双引号 3. 在记事本/编辑器中编写html语言&#xff0c;通过浏览器解析渲染语言 4. 语法结构松散&#xff08;编写时要尽量严谨&#xff09; VSc…

Tensorflow2.0笔记 - tensor的padding和tile

本笔记记录tensor的填充和tile操作&#xff0c;对应tf.pad和tf.tile import tensorflow as tf import numpy as nptf.__version__#pad做填充 # tf.pad( tensor,paddings, modeCONSTANT,nameNone) #1维tensor填充 tensor tf.random.uniform([5], maxval10, dtypetf.int32) pri…

【Uni-App】运行微信小程序时报错routeDone with a webviewId 2 that is not the current page

使用HBuilderX开发微信小程序&#xff0c;运行项目的时有可能会出现routeDone with a webviewId 1 that is not the current page的报错&#xff0c;但不影响运行。如果强迫症介意的话&#xff0c;可以考下面的方法进行修复。 产生原因 由于微信开发者工具的调试基础库处于灰度…

【靶场实战】Pikachu靶场XSS跨站脚本关卡详解

Nx01 系统介绍 Pikachu是一个带有漏洞的Web应用系统&#xff0c;在这里包含了常见的web安全漏洞。 如果你是一个Web渗透测试学习人员且正发愁没有合适的靶场进行练习&#xff0c;那么Pikachu可能正合你意。 Nx02 XSS跨站脚本概述 Cross-Site Scripting 简称为“CSS”&#xff…

SG2520CAA汽车用晶体振荡器

爱普生SG2520CAA是简单的封装晶体振荡器&#xff08;SPXO&#xff09;&#xff0c;具有CMOS输出&#xff0c;这款SPXO是汽车和高可靠性应用的理想选择&#xff0c;符合AEC-Q200标准&#xff0c;功耗低&#xff0c;工作电压范围为1.8 V ~ 3.3 V类型&#xff0c;宽工作温度-40℃~…

PyTorch复现网络模型VGG

VGG 原论文地址&#xff1a;https://arxiv.org/abs/1409.1556VGG是Visual Geometry Group&#xff08;视觉几何组&#xff09;的缩写&#xff0c;它是一个在计算机视觉领域中非常有影响力的研究团队&#xff0c;主要隶属于牛津大学的工程系和科学系。VGG以其对卷积神经网络&am…

CSS常用属性

CSS常用属性 1. 像素的概念 概念&#xff1a;我们的电脑屏幕是&#xff0c;是由一个一个“小点”组成的&#xff0c;每个“小点”&#xff0c;就是一个像素&#xff08;px&#xff09;。规律&#xff1a;像素点越小&#xff0c;呈现的内容就越清晰、越细腻。 注意点&#xff…

开源:基于Vue3.3 + TS + Vant4 + Vite5 + Pinia + ViewPort适配..搭建的H5移动端开发模板

vue3.3-Mobile-template 基于Vue3.3 TS Vant4 Vite5 Pinia ViewPort适配 Sass Axios封装 vconsole调试工具&#xff0c;搭建的H5移动端开发模板&#xff0c;开箱即用的。 环境要求&#xff1a; Node:16.20.1 pnpm:8.14.0 必须装上安装pnpm&#xff0c;没装的看这篇…

maven代码规范检查(checkstyle、findbugs)

maven代码规范检查 前言一、使用checkstyle插件1. maven-checkstyle-plugin 介绍2. 接入方式3. 如何排除某个类、包下面的文件不进行检查使用suppressionsLocation 4. 如何关闭 二、使用findbugs插件1.findbugs-maven-plugin介绍2. 接入方式3. 如何排除某个类、包下面的文件不进…

sql指南之null值用法

注明&#xff1a;参考文章&#xff1a; SQL避坑指南之NULL值知多少&#xff1f;_select null as-CSDN博客文章浏览阅读2.9k次&#xff0c;点赞7次&#xff0c;收藏21次。0 引言 SQL NULL&#xff08;UNKNOW&#xff09;是用来代表缺失值的术语&#xff0c;在表中的NULL值是显示…

rasa3.X 自定义action的注册问题

rasa3.X 自定义action的注册问题 文章目录 rasa3.X 自定义action的注册问题前言一、问题重述 前言 幸好在这之前抽时间稍微看了一点django源码&#xff0c;让我对于python的导入机制有了一个概念。虽然还不是很确切的知道python import机制&#xff0c;不过在看到类似_import_…

【算法】拦截导弹(线性DP)

题目 某国为了防御敌国的导弹袭击&#xff0c;发展出一种导弹拦截系统。 但是这种导弹拦截系统有一个缺陷&#xff1a;虽然它的第一发炮弹能够到达任意的高度&#xff0c;但是以后每一发炮弹都不能高于前一发的高度。 某天&#xff0c;雷达捕捉到敌国的导弹来袭。 由于该系…