数码管基础知识
今天我们先来了解一种新的元器件--数码管。数电教材中一般将他和译码一起讲解。它是一种显示器件,现在我们来看看它是一个什么样的东西。
以上是最常见的一些数码管,当然它的外观样式非常多,那它的工作原理是怎么样的呢?
我们现在来看一下它内部结构应该就能知道它的显示原理了。
其内部就是由一些LED电路构成,固定在其底面,然后表面通过注塑一些透明材料让显示部分在内部LED发光时能够显示出来,从而达到显示信息的效果。这种显示器是最简单,也是最经济的一种显示工具。在我们日常生活中的电器中是非常常见的,相信大多数人都遇到过,只是在这之前你可能不会想到它叫数码管显示屏。正是因为它的这些特点所以市面上各种各样的数码管显示屏都有,大家都可以定制一些特定显示内容的屏用在自己的产品上,你若有意把自己的名字制作成屏都可以,哈哈哈……这也是我在电子元器件基础知识中没有介绍它的原因。再来看看它内部电路结构,刚学完点亮LED 的朋友是否能想到点亮它的办法呢?
上图中的共阴,共阳又是什么意思?从图中很容易看出来,共阴型数码管的所有LED的阴极是接在一起的,而共阳型数码管刚好相反,这还是很好区分的吧。那这么做的目的是什么呢?把某一端接在一起,这样制作时就内部可以省一些线路,又可以少引出几个端口吧。如果使用的是共阳型数码管,在使用时将公共端接到地,这时要点亮哪一段就将所在端的LED设置为高电平就好了。
看完以上说明你也会觉得数码管也是很简单的吧,但是也先别那么得以,任何简单的应用原理背后都还隐藏很多复杂的事情,这只是显示原理最基础的一内容。当然,对于还不会使用单片机控制数码管的朋友也不用担心,接着看后面的内容你就可以入门了。如果你已经会使用数码管了不妨再来看看下面这个图中的数码管,你会使用它吗(没基础的朋友先跳过这个问题),注意它只有8个引脚!这应该是扩音器或蓝牙音箱产品上用的显示屏。
P0端口和排阻
根据以上原理分析,我设计如下的一个电路,接下来我们在这个电路上进行讲解数码管显示控制的编程内容。
细心的朋友可能发现了数码管连接的单片机P0端口每个引脚都接在了一个元件上,这是什么意思呢?这个元器件叫做排阻,简单说它就是有一排电阻,也就是说它内部包含了一组参数相同的电阻,说白了它还是电阻。我们为什么要使用这种电阻呢,看我们在接LED的电路中使用了8个一样的电阻,为了话电路图时方便或减少电路板的空间我们是不是也可以像数码管一样把公用的一端接一起呢,是吧?所以就出现了排阻这种器件。当然如果不考虑这两问题的话我们也可以用单独的电阻代替,
不过它内部结构不一定就刚刚好一个独立引脚对应一个单独的电阻,它可能有具体的一些内部电路,但是我们使用时把它等效成每个对应一个电阻就好了。
现在的排阻大多都是贴片的了,像下面这样:
那我们电路中P0端口为何要接一组排阻到电源呢?这就涉及到P0端口特殊的结构了,在我们介绍单片机基础是文章中我们提到了,现在再做一些具体的介绍。
P0端口是开漏设计的,我们查看芯片数据手册来看一下。
官方手册是这么说的,是不是看了还是很迷糊?
说到开漏一词是不是有似曾相识的感觉,模电课程考及格的朋友应该都会有印象。看上面的图也可以看出来,就是端口是直接接在一个nmos管漏极的,nmos管漏极没有有电源电路连接,我们前面介绍三极管与mos管驱动LED的视频中nmos管的漏极是要与电源连接才能驱动LED吧,这里也是是个道理。开漏输出端口是没有能力输出高电平驱动负载的,当控制其输出低电平时其引脚将接地,控制其输出高电平时引脚既不输出高电平,也不输出低电平,为高阻态状态。所以现在知道我们为什么需要接一排阻到电源了吧?这个电阻我们也称之为上拉电阻,就是将引脚接到电源端的电阻,与之对应的是下拉电阻,就是将引脚接到地端的电阻。
任何显示具体数据
现在问题来了,如我们上面设计的电路所示,我们要怎么做才能让数码管上显示出我们需要显示的内容(比如数字0,1……9)呢?这时就需要根据其内部电路分布推算出显示信息对应的控制位的数据了,以我们使用的图为例,比如要显示“0”这个符号就需要点亮a,b,c,d,e,f这六段,在我们的单片机中与这六段相连的引脚都要输出高电平才能点亮。使用这时我们就将P0端口输出数据数值为0x3f,同样的方法我们可以推断出显示其他数据时P0端口对应输出的数据。把它计算出来做成一个真值表,以后使用时就很方便了,当然这其中需要你根据具体的电路接线图来确定数据的。实际做项目时肯定会遇到不是同一组端口中连接数码管各段的情况,所以现在掌握好基础知识后遇到其他情况就需要灵魂处理了。
数组与数据显示
现在我们来看看显示一个数的程序要怎么实现。
#include
#include
sbit com1 = P2^0; //定义数码管com1引脚
sbit com2 = P2^1; //定义数码管com2引脚
typedef unsigned char u8;
typedef unsigned int u16;
u8 code num_codelist[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void delay(u8 ms);
void main()
{
u8 i;
for(i=0;i<10;i++)
{
P0 = num_codelist[i];
delay(100);
}
}
void delay(u8 ms) //定义函数
{
u8 i,j;
for(i=0;i
}
com1,com2是声明连接数码管两个公共端的,只使用一位数码管时可以不用定义,将其公共端直接接地就行,后面的程序中我们会使用到这两端口。
程序中出现了我们之前没有介绍的内容--u8 code num_codelist[10],这种数据结构叫数组,在C语言中它用来有序存储一组相同类型的数据,"[n]"中的n就是它的序号,也称它为下标。它的基础定义方式为:
数据类型 数组名 [数组元素总数N];
例如:unsigned char code[10];
它的意思是定义了一个有十位数据的数组。
它的下标计数规则是从0开始计数的,即以上数组中第一位数据为code[0]。
如果我们定义时没对其进行赋值,编译器一般会将其中所有内容初始化为0(但不一定所有编译器都是默认这么处理的,所有定义时最好还是初始化一下比较安全)。我们也可以在定义时对其中内容进行赋值,且赋值时不一定全都要赋值,可以只赋前面一位或几位部分,未赋值的内容还是会被初始化为0。
有时我们定义时也可以省略其数组元素总数N,比如:
unsigned char code[] = {1,2,3,4};
这时编译器将自动识别出数组元素总数N为4。
数组元素总数N是定义后就不能变的,即在后面的程序中不能对数组添加内容,但改变其中的数据是可以的。
刚才讲的数组,我们称为一维数组,当然数组也可以是二维或多维的,就和我们排队一样,可以排成一排,也可以排成多行,比如定义二维数组:
unsigned char code[2][5];
这里的意思就是D定义了一个有2行5列的二维数组。
使用时行列下标都要包含,比如code[0][2]就是第一行第三列的数据。
其他多维数组以此类推。
关于数组我们先介绍这些基础内容,更多知识内容后面遇到时再详细讲解。
那为什么在C51单片机编程时使用的是code table[]格式呢,这里我们添加了一个关键词code,是编译器决定的,和前面的sfr 和sbit情况类似 ,这些是要记住的内容,如果换其他编译器也要视情况而定,每种编译器使用的规则各有不同。
后面的main函数内容就是让数码管从0~9依次切换显示数字了。
任何实现动态数字显示
上面只是显示一位数据,在实际情况中要显示二位甚至多位该怎么处理呢?接下来我们看看显示两位时要怎么编程。
#include
#include
sbit com1 = P2^0; //定义数码管com1引脚
sbit com2 = P2^1; //定义数码管com2引脚
typedef unsigned char u8;
typedef unsigned int u16;
u8 code num_codelist[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void delay(u8 ms);
void main()
{
//显示第一位数字0
com1 = 0;//将第一位的com端设置为低电平
com2 = 1;
P0 = num_codelist[0];
delay(1);
P0 = 0x00;
com1 = 1;
com2 = 0;//将第二位的com端设置为低电平
P0 = num_codelist[1];
delay(1);
P0 = 0x00;
}
void delay(u8 ms) //定义函数
{
u8 i,j;
for(i=0;i
}
这段代码中main函数外的程序段跟前面的一样,现在主要看main函数内部的程序。
首先我们要了解的是两位或以上的数码管同时显示不一样的内容应用的原理是人眼视觉暂留的特点。其实显示器都是根据这一原理来设计的。
那什么是视觉暂留呢?视觉暂留(英文:Persistence of vision)也称为正片后像,是光对视网膜所产生的视觉,在光停止作用后,仍然保留一段时间的现象,其具体应用是电影的拍摄和放映。原因是由视神经的反应速度造成的,其时值约是1/16秒,对于不同频率的光有不同的暂留时间。比如:我们日常使用的日光灯每秒大约熄灭100余次,但我们基本感觉不到日光灯的闪动,这就是因为视觉暂留的作用。我们平时说的某动画片,电影是30帧每秒的,电脑显示屏是75fps的,手机显示屏是120fps的,都是指屏幕刷新率,屏幕就是不停闪烁的,只是什么看不到它的闪烁而已。如果哪天外星人来了,或许它们就能看出吧。
视觉暂留现象首先是咱们中国人发现的,走马灯便是据历史记载中最早的视觉暂留运用。宋时已有走马灯,当时称“马骑灯”。随后法国人保罗·罗盖在1828年发明了留影盘,它是一个被绳子在两面穿过的圆盘。盘的一个面画了一只鸟,另一面画了一个空笼子。当圆盘旋转时,鸟在笼子里出现了。这证明了当眼睛看到一系列图像时,它一次保留一个图像。再后来就有了电影,最后又了显示屏。
现在回来我们正题,我们让数码管同时显示两位不一样的数字该怎么操作呢?是不是先显示第一位,然后马上又显示第二位,后面再这么一直循环往复就形成了视觉暂留效果,数码管上的数据看起来就成了静态不变的数据了。现在看注释是不是就能看明白了?
当然这种做法知识最基础办法,当我们在复杂应用中这么使用时不合理的,至于为什么呢,我们后面介绍其他内容时再详细讲解。另外这个应用电路图仅仅也是适用于仿真用,实际使用时还是需要进一步优化的,因为数码管中每个LED灯点亮需要耗费的电流都是比较大的了,如果同时亮很多灯,对于驱动能力若的单片机可能会遇到的问题是:你把逻辑正确的程序下载进去,结果没有任何显示,或显示不正常。这种情况可能真的不是你的程序问题,而是单片机带不动它,就像你是一个100斤的瘦子去背一个300斤的胖子一样,要么你瞬间被压第地上,如果你很坚强那就还能走走停停动两步吧。
在进化设计电路时要参考单片机数据手册中的电流参数来确定你的电路是否合理。遇到可能使电路工作不正常的情况我们需要借助一些外部芯片来驱动它,比如使用锁存器或专用驱动芯片,锁存器一是可以帮助单片机键显示数据暂时锁存利于减少单片机内部CPU资源消耗,二是可以它可以加大驱动电流,使得显示电路不影响单片机内部工作的稳定。
做过项目的朋友应该对电路中电流的波动对产品性能的影响非常有印象吧。因为我在我创业之前我的本职工作一直都是做医疗器械。因电流电路中变化产品出现的大小问题基本都是能看的出来(虽然我主要职责是软件开发的,电路整改由硬件工程师负责)。因为医疗电子行业是国家限制最严格的一个行业,人命关天,即使是万分之一概率事故发生你都承担不了。不过这个行业薪资还是很不错的,不比互联网差多少(具体差不差也还看个人能力哈),有兴趣的朋友这是一个很好的选择。但做这行你要沉得住气,做好一个产品2~3年,甚至更久都不能上市的准备,也就是你至少要熬出一款产品来。过程会比较枯燥,但程序员不都是自乐其中吗,干啥不是干呢,有钱就行,对吧?
评论
查看更多