51单片机(四)静态数码管和动态数码管显示

news2024/9/22 21:20:33

❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。
☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋。
🌙专栏目标:实现从零基础入门51单片机和STM32单片机,力求在玩好单片机的同时,能够了解一些计算机的基本概念,了解电路及其元器件的基本理论等。

⭐️ 专栏主要内容: 主要学习51单片机的功能、各个模块、单片机的外设、驱动等,最终玩好单片机和单片机的外设,全程手敲代码,实现我们所要实现的功能。
🌴 专栏说明 :如果文章知识点有错误的地方,欢迎大家随时在文章下面评论,我会第一时间改正。让我们一起学习,一起进步。
💑专栏主页:http://t.csdn.cn/HCD8v

本学习过程参考:https://space.bilibili.com/383400717

单片机安装软件、各种资料以及源码的路径:
https://pan.baidu.com/s/1vDTN2o8ffvczzNQGfyjHng
提取码:gdzf

文章目录

  • 一、本节背景和目标
    • 1.1 数码管原理介绍(很重要!!!)
      • 1.1.1 数码管介绍
      • 1.1.2 一位数码管
      • 1.1.3 四位一体数码管
      • 1.1.4 多个数码管同时显示不同数字
      • 1.1.5 数码管原理图解析
      • 1.1.6 138译码器
      • 1.1.7 74HC245(双向数据缓冲器)
    • 1.2 本节目标
  • 二、静态数码管显示
  • 三、动态数码管显示

一、本节背景和目标

1.1 数码管原理介绍(很重要!!!)

1.1.1 数码管介绍

在这里插入图片描述

1.1.2 一位数码管

下图是个一位的数码管,
在这里插入图片描述

数码管是由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

1.1.3 四位一体数码管

下图是一个四位一体的数码管:
在这里插入图片描述
可以看到,以共阴极数码管为例,每个数码管共用阴极,但是四个数码管阳极所有的对应引脚都是连接同一个引脚;例如这四个数码管的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的目的。

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

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

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

1.1.5 数码管原理图解析

数码管在开发板上的位置

在这里插入图片描述
数码管的原理图如下所示:

在这里插入图片描述
其中138译码器和数码管都是其组成部分。

在这里插入图片描述
如果想要使某个数码管亮,将其置为引脚0;如上图,LED6(引脚8)置为0,将其选中,则LED6具备了点亮的条件;其他的LED置为1,表示不选中,不会亮。

例如想要是LED6显示数字1,则按照如下图操作:
在这里插入图片描述

1.1.6 138译码器

在这里插入图片描述

由上面的原理图可知,LED1-8(即公共负极)其实是接在138译码器的LED1-8(引脚7、9、10-15)上的,也是138译码器的输出;而138译码器的输入是接在MCU的P22-P24口的;所以可以得知,138译码器由P22-P24三个输入口,控制LED1-8这8个输出口LED的状态;具体是怎么做到的呢?

在这里插入图片描述

138译码器是三个线到八个线的译码器;其实就是负责将三个输入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;
以此类推。。。。

其真值表如下所示
在这里插入图片描述

1.1.7 74HC245(双向数据缓冲器)

在这里插入图片描述
由原理图可以得知,晶体管的正极是接在74HC245(双向数据缓冲器)上的。

作用:双向的数据缓冲

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

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

1.2 本节目标

目标1:在晶体管的任意位置显示任意数字,下图在第三个位置显示了数字6:

在这里插入图片描述

目标2:
在数码管的前三位显示三个数字123,即数码管的动态显示,可以在数码管的任意位置显示任意数字,且可以多个数字显示
在这里插入图片描述

二、静态数码管显示

经过上面的学习可以得知,如果想使数码管显示数字,
第一步是选择使哪个晶体管点亮:即要让目标点亮的等负极有效(参考第1.1.5和1.1.6节),而负极是接在138译码器上的,138译码器的8输出连接着静态数码管的负极,138译码器的3个输入连接着MCU的引脚(P22-P24口);所以我们要通过对P22-P24口的设置,来控制目标晶体管负极有效。

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

总结:

  • 第一步,选择哪个晶体管点亮,控制引脚为P22-P24;
  • 第二步,选择具体点亮的数字,控制引脚为P00-P07;

代码路径:51单片机入门教程资料\课件及程序源码\程序源码\KeilProject\4-1 静态数码管显示
具体代码:
先写一个使第三个数码管显示数字6的程序:
首先第一步,选择第三个数码管点亮,即LED1设置为低电平0;由下图可知,LED3对应着138译码器上的Y2,那么要使Y2输出0,其他Y输出1;由1.1.6节中的真值表可以得知,C、B、A对应的值应该设置为0.1,0;所以应该设置P22为0,P23为1,P24为0;

在这里插入图片描述

第二步,显示数字6,则要使第一个数码管中的a、f、e、d、g、C六个LED点亮,参考上图,可以得知应将P00、P05、P04、P03以及P06、P02设置为1,P01设置为0;
具体代码如下所示:

#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;
		
	}
}

该方法直接对P0的8个引脚逐个进行了赋值,当然除此之外,我们还可以对P0口整体进行赋值,以上面为例,P00、P05、P04、P03以及P06、P02设置为1,P01设置为0,则对应的P0口的值为:因为P0-P7中,P00为低位,P07为高位,按照从左到右为从高到低的写法,P0口的值为1111 1101,转化成16进制就是0xFD;所以方法2的代码如下:

#include <REGX52.H>

void main()	
{
	while(1)
	{
		P2_2=0;
		P2_3=1;
		P2_4=0;
				
		P0 = 0xFD;
		
	}
}

最终的效果为目标1:

在这里插入图片描述

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

#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(3,6);	//在数码管的第3位置显示数字6
	while(1)
	{
		
	}
}

三、动态数码管显示

代码路径:51单片机入门教程资料\课件及程序源码\程序源码\KeilProject\4-2 动态数码管显示

基于1.1.4节的理论和第二节的代码,我们可以得到动态数码管的方法和代码,即如果想让第一个数码管显示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.coloradmin.cn/o/465143.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

内存优化-比glibc更快的tcmalloc

TCMalloc 是 Google 开发的内存分配器&#xff0c;在不少项目中都有使用&#xff0c;例如在 Golang 中就使用了类似的算法进行内存分配。它具有现代化内存分配器的基本特征&#xff1a;对抗内存碎片、在多核处理器能够 scale。据称&#xff0c;它的内存分配速度是 glibc2.3 中实…

3d网上渲染平台是怎么渲图的_云渲染流程详解!

题主说的看到许多网友对‘’3d网上渲染平台是怎么渲图的‘’进行提问&#xff0c;瑞云渲染小编也提供自己的小小见解。针对3D网上渲染平台是指什么&#xff0c;实际应该是指云渲染农场。几十年来&#xff0c;随着计算机软硬件不断更迭&#xff0c;图形图像渲染的效果更加清晰、…

信号完整性分析基础知识之传输线和反射(二):阻性负载的反射,源端阻抗,弹跳图

传输线的端接需要考虑三种重要的特殊情况&#xff0c;每种情况中&#xff0c;传输线的特性阻抗均为50Ohm。信号将从源端在这条传输线上传播&#xff0c;并以特定的阻抗端接到达远端。 TIP:在时域中&#xff0c;信号对瞬时阻抗十分敏感&#xff0c;第二区域并不一定是一条传输线…

常见的链表的OJ题

在本次的博客当中&#xff0c;为了巩固关于链表技能的运用&#xff0c;我们先来看一些与链表有关的OJ题。 &#x1f335;反转链表 题目详情如下&#xff1a; 第一道题目从逻辑上看不难&#xff0c;我们只需要将链表进行拆分&#xff0c;将我们下一个节点进行一个类似于头插的操…

【Java 数据结构】Map和Set

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了 博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点!人生格言&#xff1a;当你的才华撑不起你的野心的时候,你就应该静下心来学习! 欢迎志同道合的朋友一起加油喔&#x1f9be;&am…

35岁程序员被裁赔偿27万,公司又涨薪让我回去,前提是退还补偿金,能回吗?

在大多数人眼里&#xff0c;35岁似乎都是一道槛&#xff0c;互联网界一直都有着“程序员是吃青春饭”的说法&#xff0c;。 如果在35岁的时候被裁能获得27万的赔偿&#xff0c;公司又涨薪请你回去上班&#xff0c;你会怎么选&#xff1f; 最近&#xff0c;就有一位朋友在网上…

Linux安装miniconda3

下载Miniconda&#xff08;Python3版本&#xff09; 下载地址&#xff1a;https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh 安装Miniconda&#xff08;需要连网&#xff09; &#xff08;1&#xff09;将Miniconda3-latest-Linux-x86_64.sh上传到/o…

研读Rust圣经解析——Rust learn-14(面向对象)

研读Rust圣经解析——Rust learn-14&#xff08;面向对象&#xff09; Rust面向对象对象包含数据和行为封装继承多态 实现面向对象书写最外层逻辑userServiceUser Rust面向对象 在一些定义下&#xff0c;Rust 是面向对象的&#xff1b;在其他定义下&#xff0c;Rust 不是 对象…

算法刷题|300.最长递增子序列、674.最长连续递增序列、718.最长重复子数组

最大递增子序列 题目&#xff1a;给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&#xff0c;[3,6,2,7] 是数组 [0,3,1,6…

c++文件操作Ofstream、Ifstream,如何获取文件长度

一、文件光标定位streampos 在读写文件时&#xff0c;有时希望直接跳到文件中的某处开始读写&#xff0c;这就需要先将文件的读写指针指向该处&#xff0c;然后再进行读写。 ifstream 类和 fstream 类有 seekg 成员函数&#xff0c;可以设置文件读指针的位置&#xff1b;ofstr…

OpenGL光照:颜色

知识点归纳 现实世界中有无数种颜色&#xff0c;每一个物体都有它们自己的颜色。我们要做的工作是使用(有限的)数字来模拟真实世界中(无限)的颜色&#xff0c;因此并不是所有的现实世界中的颜色都可以用数字来表示。然而我们依然可以用数字来代表许多种颜色&#xff0c;并且你甚…

autosar

一 autosar简介 AUTOSAR&#xff0c;汽车开放系统架构&#xff08;AUTomotive Open System Architecture&#xff09;是一家致力于制定汽车电子软件标准的联盟。AUTOSAR是由全球汽车制造商、部件供应商及其他电子、半导体和软件系统公司联合建立&#xff0c;各成员保持开发合作…

QT DAY2

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);this->setFixedSize(600,600); //设置固定尺寸this->setWindowTitle("汪玉洁大聪明")…

Hadoop学习笔记(一)Hadoop的组成

1. HDFS NameNode用于记录整个数据的存储情况&#xff0c;具体的数据存储在各个Hadoop节点中&#xff0c;每个Hadoop的节点可以称为DataNode。假设Hadoop1到Hadoop100的机器每个都有1T的容量。那么一共就可以存储100T的数据。 NameNode(nn)&#xff1a;存储文件的元数据&…

位运算【巧妙思路、两种常见题型】

这里介绍两种代码中位运算非常常用的操作 n的二进制表示中第k位数——右移操作 &1 例如说&#xff0c;我们需要计算11的第2位数。 11 (1011)2 我们常规思路就是将其转化为二进制数后&#xff0c;直接观察对应位置的值 这里需要注意的是第k位数指的是从右开始的第k位&a…

Linux shell编程 条件语句

条件测试 test命令 测试表达式是否成立&#xff0c;若成立返回0&#xff0c;否则返回其他数值 格式1: test 条件表达式 格式2: [ 条件表达式 ]文件测试 [ 操作符 文件或者目录 ][ -e 1.txt ]#查看1.txt是否存在&#xff0c;存在返回0 echo $? #查看是上一步命令执行结果 0成…

DJ4-3 连续分配存储管理方式

目录 4.3.1 单一连续分配 4.3.2 固定分区分配 1. 分区说明表 2. 内存分配过程 4.3.3 动态分区分配 一、分区分配中数据结构 二、分区分配算法 三、分区分配操作 4.3.4 可重定位分区分配 1. 紧凑 2. 动态重定位 3. 动态重定位分区分配算法 连续分配是指为用户程…

【数据结构】堆(一)

&#x1f61b;作者&#xff1a;日出等日落 &#x1f4d8; 专栏&#xff1a;数据结构 如果我每天都找出所犯错误和坏习惯&#xff0c;那么我身上最糟糕的缺点就会慢慢减少。这种自省后的睡眠将是多么惬意啊。 目录 &#x1f384;堆的概念及结构&#xff1a; &#x1f384;堆的实…

万丈高楼平地起 AI帮你做自己

AI的自我介绍 AI是人工智能&#xff08;Artificial Intelligence&#xff09;的英文缩写&#xff0c;是一种通过计算机技术模拟和延伸人类智能的技术和应用。AI可以被看作是一种智能化的计算机程序或系统&#xff0c;它能够自动地执行一些需要人类智能才能完成的任务&#xf…

JavaEE初阶学习:初识网络

1.网络发展史 1.独立模式 独立模式:计算机之间相互独立&#xff1b; 2.网络互连 随着时代的发展&#xff0c;越来越需要计算机之间互相通信&#xff0c;共享软件和数据&#xff0c;即以多个计算机协同工作来完成业务&#xff0c;就有了网络互连。 网络互连&#xff1a;将多…