【51单片机实验笔记】LED篇(三) 数码管的基本控制 您所在的位置:网站首页 单片机共阳极 【51单片机实验笔记】LED篇(三) 数码管的基本控制

【51单片机实验笔记】LED篇(三) 数码管的基本控制

2024-07-15 11:18| 来源: 网络整理| 查看: 265

目录 前言硬件介绍原理图分析段选和位选 驱动芯片74HC138芯片74HC245芯片 软件实现点亮一只数码管倒计时效果动态显示字符 总结

前言

本节内容我们学习如何控制数码管,先尝试点亮一个数码管,并实现倒计时效果。

本节涉及到的封装源文件可在《模块功能封装汇总》中找到。

本节完整工程文件已上传GitHub,仓库地址,欢迎下载交流!

硬件介绍

数码管的英文为Nixie Tube,又称辉光管或LED数码管。其基本单元由LED组成,单个数码管的概念图如左图所示,一般可以分为七段数码管和八段数码管两种。八段比七段多一个小数点,应用更为广泛。

除此之外,单个数码管只能显示一个数字(字母),功能受限。所以常常将多个数码管封装起来,如右图所示,常用的为4位数码管。

图1 八段数码管 图2 多位数码管

数码管的发光颜色由管中充的低压气体决定,氖加上一些汞或氩,一般为橙色或绿色。

原理图分析

数码管的电路原理图如下: 在这里插入图片描述 按LED的连接方式可以分为共阴极数码管和共阳极数码管。

共阴极:将LED的阴极连在一起称为公共阴极(COM)共阳极:将LED的阳极连在一起称为公共阳极(COM)

共阴极需要单片机 IO 给高电平,对应的段(LED)才能点亮,而单片机的 IO 引脚电流输出能力不足,往往需要借助驱动芯片(如74HC245芯片)才可以点亮数码管。而共阳极只需要单片机 IO 给低电平,单片机的灌电流大于拉电流,故共阳极数码管应用更加广泛。

注:由于每段都是由LED组成,故实际电路中应该串联限流电阻,一般接一个8P排阻。

段选和位选

在数码管中有段选和位选两个概念,现阐释如下:

段选:针对单个数码管而言。选择要点亮数码管中 a、b、c、d、e、f、g、dp 哪些段。一般通过给 IO 引脚赋值实现。位选:针对多位数码管而言。选择点亮哪个数码管。即控制COM端的高低电平。

仔细观察数码管的段选顺序,按 a、b、c、d、e、f、g、h 逆时针排列,依次对应字节的低位至高位。因此,我们可以给出共阴极数码管的字形码编码表。(有些字母不易表示,缺省)

字形码dp g f e d c b a十六进制00011 11110x3f10000 01100x0620101 10110x5b30100 11110x4f40110 01100x6650110 11010x6d60111 11010x7d70000 01110x0780111 11110x7f90110 11110x6fA0111 01110x77b0111 11000x7cc0101 10000x58d0101 11100x5eE0111 10010x79F0111 00010x71G--H0111 01100x76I0011 00000x30J0000 11100x0eK--L0011 10000x38M--n0101 01000x54o0101 11000x5cp0111 00110x73q0110 01110x67r0101 00000x50s0110 11010x6dt--U0011 11100x3ev0001 11000x1cw--x--y0110 11100x6ez--

如果是共阳极,其编码表刚好是共阴极的按位取反(~)。

其实可以看出,数码管对显示字母并不友好,一般用于显示数字,在电梯楼层显示,计算器显示中应用广泛。

从上述一系列分析中我们得到,数码管相当于LED的堆叠,它对 IO 口资源的消耗是巨大的。如果要同时显示多个数字,除了采用芯片(如38译码器)来节约 IO 口,还可以采用不同的显示方式实现。数码管有两种驱动显示方式:静态显示和动态显示。

静态显示:即每个数码管的每一个段码都由一个单片机的I/O端口进行驱动。优点是编程简单,显示亮度高,缺点是占用I/O端口过多,这显然是致命的。动态显示:利用人眼暂留效应,分时轮流控制 COM端(位选),每个数码管的点亮时间为1ms~2ms,因为频率很快,仿佛所有数码管都是同时点亮的,这即是动态的含义。优点的节省大量IO口,功耗低,缺点是亮度不及静态显示方式,但可以通过降低限流电阻的阻值来提高亮度。 驱动芯片

我们需要清楚一点,单片机适合用于控制,它可以输入输出电平,但电流是很小的。或许单片机驱动单独一个LED是足够的,但当LED数量多起来时,它便无能为力了,更别提驱动大功率的灯泡或是电机了。

这些功率比较大的外设往往需要外接电源,通过驱动芯片来提供电流和能量,单片机提供信号指令。

74HC138芯片

2个4位共阴极数码管和74HC138芯片(38译码器)原理图如下:

2个4位共阴极数码管 38译码器

将各数码管相同的段选连在一起,由 P0 统一控制,这样每个数码管显示的字符都是一样的。如何使不同数码管显示不同的字符?只需要给出位选信号指定不同的数码管点亮即可。

虽然位选端共有8个引脚,但实际上我们只需要每次点亮一个数码管,即只有8种情况,那么完全可以用3个引脚来控制这8种输出,这就是38译码器的实现机理。

观察38译码器原理图。其中, G 1 G1 G1、 G 2 ‾ \overline{G2} G2、 G 3 ‾ \overline{G3} G3 为使能端,其中G1高电平有效,G2、G3低电平有效(即上横线的含义)。38译码器的真值表为

A0A1A2Y0Y1Y2Y3Y4Y5Y6Y70000111111100110111111010110111110111110111110011110111101111110111101111110111111111110

因为是共阴极数码管,所以Y端口为低电平时该数码管被点亮。

74HC245芯片

在这里插入图片描述 主要用于提升单片机 IO 口的驱动电流。一般 IO 口的输出电流为20mA,这个电流大小仅仅点亮一颗LED是没有问题的,但对于驱动数码管、点阵等多负载模块就力不从心了。

74HC245芯片可以将输出电流提升至70-80mA左右,具有8路输入和8路输出,可输出低电平、高电平、高阻态三态。其中DIR引脚用于控制输入输出方向,高电平(A => B)、低电平(B => A)。 O E ‾ \overline{OE} OE为使能引脚,低电平输出有效。

软件实现 点亮一只数码管 #include "REGX52.H" #define SMG_PORT P0 //重定义数据类型 typedef unsigned char u8; typedef unsigned int u16; //共阴极数码管字形码编码 u8 code smgduan[] = {0x3f,0x06,0x5b,0x4f,0x66, //0 1 2 3 4 0x6d,0x7d,0x07,0x7f,0x6f, //5 6 7 8 9 0x77,0x7c,0x58,0x5e,0x79, //A b c d E 0x71,0x76,0x30,0x0e,0x38, //F H I J L 0x54,0x5c,0x73,0x67,0x50, //n o p q r 0x6d,0x3e,0x1c,0x6e}; //s U v y void main() { //P0口控制数码管显示字符 SMG_PORT = smgduan[14]; //E while(1); }

定义共阴极数码管字形码编码,注意这里的定义中使用了code关键字,这是C51中拓展的存储器类型。在标准C中,变量的定义格式为

[存储类别] 数据类型 变量名 = 初值;

存储类别含义特点auto自动变量默认类型。(生存期)属于动态局部变量,调用时临时分配内存,函数调用结束即释放。(初值分配)在调用时赋初值,未赋初值则初值不确定。(作用域)仅在函数体内可调用。static静态变量(生存期) 属于静态局部(全局)变量,调用结束后保留当前值。(初值分配)只在编译时赋初值,默认赋0或'\0'。 (作用域)静态局部变量仅在函数体内可调用,静态全局变量在本文件中可调用。extern外部变量外部声明,数据类型可省略。扩展变量作用域,实现跨文件调用。register寄存器变量将变量存储在CPU的寄存器中,减小内存开销。

但在C51中,变量的完整定义格式为

[存储类别] 数据类型 [存储器类型] 变量名 = 初值;

存储器类型特点code变量放在ROM(程序存储器,64KB),不可更改data变量放在可直接寻址片内RAM(数据存储器,低128B),访问速度快xdata变量放在间接寻址片外RAM(数据存储器,全64KB)bdata变量放在可位寻址片内RAM(数据存储器,20H~2FH,16B)idata变量放在间接寻址片内RAM(数据存储器,全256B)pdata变量放在间接寻址片外RAM(数据存储器,低128B)

单片机的ROM一般比RAM大很多(STC89C52单片机ROM为8KB,RAM为256个字节),所以一些硬编码数据(比如字形库数据)可以放在ROM区,以节省片内RAM资源。

倒计时效果

代码如下:

#include #define SMG_PORT P0 typedef unsigned char u8; typedef unsigned int u16; void delay(u16 t){ while(t--); } void main(){ //定义共阴数码管字形码编码 u8 smg_array[] = {0x3f,0x06,0x5b,0x4f,0x66, //0 1 2 3 4 0x6d,0x7d,0x07,0x7f,0x6f}; //5 6 7 8 9 while(1){ int i; for(i=0;i0x30,0x38,0x3f,0x3e,0x79,0x6e,0x3f,0x3e}; sbit A0 = SMG_SELECT_PORT^2; sbit A1 = SMG_SELECT_PORT^3; sbit A2 = SMG_SELECT_PORT^4; void delay(u16 t){ while(t--); } //位选码,利用十进制取余 void Dec2Bin(u8 i){ A0 = i % 2; i /= 2; A1 = i % 2; i /= 2; A2 = i % 2; } void main(){ u8 i; while(1){ for(i=0;i


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有