STC89C52单片机学习——第11节:[4-1]静态数码管显示
写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做!
本文写于:==2025.03.12==
51单片机学习——第11节:[4-1]静态数码管显示
- 前言
- 开发板说明
- 引用
- 解答和科普
- 一、数码管的简介
- 二、代码编写
- 问题
- 总结
前言
本次笔记是用来记录我的学习过程,同时把我需要的困难和思考记下来,有助于我的学习,同时也作为一种习惯,可以督促我学习,是一个激励自己的过程,让我们开始51单片机的学习之路。
欢迎大家给我提意见,能给我的嵌入式之旅提供方向和路线,现在作为小白,我就先学习51单片机了,就跟着B站上的江协科技开始学习了.
在这里会记录下江协科技51单片机开发板的配套视频教程所作的实验和学习笔记内容,因为我之前有一个开发板,我大概率会用我的板子模仿着来做.让我们一起加油!
另外为了增强我的学习效果:每次笔记把我不知道或者问题在后面提出来,再下一篇开头作为解答!
开发板说明
本人采用的是慧净的开发板,因为这个板子是我N年前就买的板子,索性就拿来用了。不再另外购买视频中的普中开发板了。
原理图如下
视频中的都用这个开发板来实现,如果有资源就利用起来。
仔细看了看:开发板的晶振为:11.0592Mhz;12Mhz晶振是用来给CH340G芯片外置晶振;
下图是实物图
引用
51单片机入门教程-2020版 程序全程纯手打 从零开始入门
还参考了下图中的书籍:
手把手教你学51单片机(C语言版)
解答和科普
1、无
一、数码管的简介
1.1数码管的简介
共阴极和共阳极
不断扫描,动态数码管显示。
这是比较常见的数码管的原理图,我们板子上一共有68个数码管。前边有了 LED 小灯的学习,数码管学习就会轻松的多了。从图 5 3 可以看出来,数码管共有 a 、 b 、 c 、 d 、 e 、 f 、 g 、dp 这么 8 个段,而实际上,这 8 个段每一段都是一个 LED 小灯,所以一个数码管就是由 8个 LED 小灯组成的。我们看一下数码管内部结构的示意图。
数码管分为共阳和共阴两种,共阴数码管就是8 只 LED 小灯的阴极是连接在一起的,阴极是公共端,由阳极来控制单个小灯的亮灭。同理,共阳数码管就是阳极接在一起,的数码管上边有 2 个 com ,这就是我们数码管的公共端。为什么有2 个呢,一方面是 2 个可以起到对称的效果,刚好是 10 个引脚,另外一个方面,公共端通过的电流较大,我们初中就学过,并联电路电流之和等于总电流,用2 个 com 可以把公共电流平均到 2 个引脚上去,降低单条线路承受的电流。
6个数码管的 com 都是接到了正极上,当然了,和 LED 小灯电路一样,也是由 74HC138控制三极管的导通来控制整个数码管的使能。先来看最右边的 DS1 这个数码管,原理图上可以看出,控制 DS1 的三极管是 Q17 ,控制 Q17 的引脚是 LEDS0 ,对应到 74HC138 上边就是U3 的 Y0 输出,如图。
我们现在的目的是让LEDS0 这个引脚输出低电平,相信大家现在可以根据前边 学过的知 识独立 把 ADDR0 、 ADDR1 、 ADDR2 、 ADDR3 、 ENLED 这 4 个 所需 输入 的值 写出来。
在江科大讲解的原理图中:
整个数码管电路的逻辑是:
第一步,选择哪一位数码管:74LS138是译码器,它的输出连接着数码管的公共端,要想使数码管亮,可以选择通过输入端控制38译码器的输出,选择哪一个数码管。
LED1-8 接到74LS138译码器输出端;138译码器可以实现一个为0其余为相反位1;还能满足3个IO口控制8个输出端;整个控制过程就是:1、38译码器的3个输入,经过译码器输出位Yn为选中LEDn,也就是选中了数码管的位选,哪一个数码管会显示;
第二步:
就是显示段码的,让选中的数码管显示对应的位数,2、然后是从缓冲器左侧的数据给到段码,然后在位置确定后的数码管上显示对应的数据。
74HC24是缓冲器,从DIR是方向,左边可以传到右边。然后进行对P0口操作,进而控制数码管的显示。电阻是又来限流,因为输入高电平LED才会点亮。
1.2自己开发板数码管原理
由原理图可以看出,这个是共阴极,因为公共端连接在了38译码器的输出,大概率就是共阴极了,因为38译码器由3个IO口控制8个端口,且能让端口输出低电平,其他的为高电平。
可以看到P2.1控制数码管的位置,选择哪一个数码管,P2.0控制数码管显示什么内容。且这两个接在两个锁存器,左端都是P0口,因此就是P0口控制那个位置和现实多少。应该要加入延迟,就比如先控制位置,锁存器U6进行对位选的锁存,然后再去处理U⑤,控制数据选择什么。这样就完成了一个周期的,注意延迟会出现bug。
二、代码编写
2.1江科大的代码
#include <REGX52.H>
void main ()
{
P2_4=1;
P2_3=0;
P2_2=1;
P0=0x7D;
while(1)
{
}
子函数优化,封装起来。
#include <REGX52.H>
unsigned char NixieTable[]= {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00};
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(7,2); //模块调用,内部不用管
while(1)
{
}
}
2.2本开发板编写
1、显示数字
#include <REGX52.H>
#include <INTRINS.H>
sbit wei= P2^1;
sbit duan=P2^0;
sbit dianzheng=P2^2;
void Delayxms(unsigned int xms) //@11.0592MHz
{
while(xms--)
{
unsigned char i, j;
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
void main()
{
dianzheng=0; //关闭点阵的显示
wei=1; //选择位的锁存器开关
P0=0xFE; //1111 1110 就是选择第一位数码管公共端为低电平
wei=0; //关闭位选择的锁存器开关,保持住位数据,接下来要用P0口写段码
duan=1; //选择段码的锁存器开关
P0=0x06; //0000 0110 为数字1的段码
duan=0; //关闭选择段码的锁存器开关
while(1)
{
}
}
2、优化和封装
#include <REGX52.H>
#include <INTRINS.H>
sbit wei= P2^1;
sbit duan=P2^0;
sbit dianzheng=P2^2;
unsigned char NixieDuanTable[]= {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00};
unsigned char NixieWeiTable[]={0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};
void Nixie(unsigned char WeiNum, DuanNum)
{
wei=1;
P0=NixieWeiTable[WeiNum];
wei=0;
duan=1;
P0=NixieDuanTable[DuanNum];
duan=0;
}
void Delayxms(unsigned int xms) //@11.0592MHz
{
while(xms--)
{
unsigned char i, j;
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
void main()
{
dianzheng=0;
Nixie(6,6);
while(1)
{
}
}
本代码没有用到Delay函数,放在这没有删除,这里把段码和位码用数组存放起来,再利用函数的调用,把具体的数值调用出来,进而完成本次实验。
unsigned char NixieDuanTable[]= {0x3F,0x06,0x5B,0x4F,0x66,0x
6D,0x7D,0x07,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00};
这个NixieDuanTable 数组存放的是段码表。
unsigned char NixieWeiTable[]={0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};
这个NixieWeiTable 数组存放的是位码表。
创建了函数:
void Nixie(unsigned char WeiNum, DuanNum)
{
wei=1;
P0=NixieWeiTable[WeiNum];
wei=0;
duan=1;
P0=NixieDuanTable[DuanNum];
duan=0;
}
同上面的显示一样,打开位开关,写入数据P0,然后关闭位开关。
打开段码开关,P0口写入段码,然后关闭段码开关。
最后再函数调用:
Nixie(6,6);
这里的意思是:把实参赋值给形参,就是第一个6,复制给WeiNum,此时位选P0=0xDF(1101 1111);分别位8764 4321的选择,此时第六位为0,则选择了第6个数码管。
第二个实参6,赋值给DuanNum;此时P0=0x7D(0111 1101)对应的a、c、d、e、f、g、点亮就是数字6点亮。
完成整个实验,dianzhen等于0是关闭点阵的开关。
实验现象:
问题
1、如何实现数码管动态显示,我加入了Delay函数,只是延迟一下而已。
总结
本节课主要学了数码管的静态显示:
1、首先学习了数码管的原理,就如8个LED,通过控制相应的灯亮,来显示出不同的数字字母,然后知道分为共阴极和共阳极,以及对应的段码。
2、学习了数码管的硬件电路,江协科技的是用38译码器来选择哪一位数码管,然后是驱动缓冲电路,输入段码。本开发板是用来两个锁存器,分为选择位置和段码,然后都从P0口输入控制,位选后,进行段选应该都可以。
3、然后还学习了C语言的数组,以及定义函数,函数的形参和实参,通过调用函数,进行参数传递,最终选择了数组中的数据,在函数值只需要写需要在第几位,显示什么数就完成了。