- 80C51单片机介绍
- 点亮第一个发光二极管,及流水灯案例
- 数码管显示及封装与消隐
文章目录
- 80C51单片机系列
- 数码管显示
- 数码管的控制逻辑
- 循环显示
- 封装数码管
- 消隐
- 下一章:中断
上一章中中我们学习了,如何操作二极管的发光熄灭。
这一节我们讲如何操作数码管,让数码管显示出数字。
数码管显示 数码管的控制逻辑数码管的控制由位选和段选控制。
位选:由哪一位显示,也就是哪个数码管显示。(例:下图中有四个数码管)
段选:也就是该数码管显示的内容,意思就是这个数码管的哪一段显示。一般每个数码管都有:a、b、c、b、e、f、g。八个段(如下图)
简单点来说就是:一个数码管是否显示,如果显示那么这个数码管要显示什么内容。
好啦现在我们已经大概知道数码管的控制逻辑。
下面来看来看原理图!
从上图(原理图)中我们可以看到,操控数码管分为两部分。
位选
在每个数码管的上面,都连接着一个串口。分别是:LEDS4、LEDS3、LEDS2、LEDS1。从上面说的数码管控制逻辑,我们可以猜测出,这四个串口应该是位选。
因为位选只需要控制是否显示,一个数码管一个串口就可以满足需求。
所以该四个串口为:位选
段选
再看数码管下面,有八个串口,图上非常清晰,a、b、c、b、e、f、g。
这八个串口连接到单片机上P0口的八个串口。
所以我们如果想要让第一个数码管显示1,那应该怎么做呢?
首先需要让这个数码管亮起来,这里数码管发光与熄灭,是低电平熄灭,高电平发光。
(注意:与二极管不同,二极管高电平熄灭,给低电平发光)
高电平就是赋值 1,低电平就是赋值 0。上一章中已经讲过。
我们找一下第一个数码管的位选,是LEDS4。
从图上左边可以看到,LEDS4连接单片机上的P1 ^ 3这个口。那么只需给P1 ^ 3 = 1 即可!
现在数码管已经亮起来了!
我们想要让数码管显示 1,还需要控制段选。
从上图中可以看到显示1,有两种选择。
一种是给 f,e 赋值高电平,其他低电平。
另一种给 b,c 赋值高电平,其他低电平。
这里选择第二种方式,因为这个更较标准一点
b,c 连接的串口可从上图(原理图)中尝试寻找一下,找不到了再看下面的代码
代码如下
#include//位选 sbit LEDS4 = P1^3; //段选 sbit b = P0^1; sbit c= P0^2; void main() { //初始化,全部为低电平 P1 = 0; P0 = 0; LEDS4 = 1; b = 1; c = 1; while(1); }
然后编译一下,下载到单片机里,开机然后就可以看到第一个数码管里显示为1啦!
循环显示
有了上面的例子后,下面我们就来练习一下。
就是循环显示出:0 1 2 3 4 5 6 7 8 9 A b c d e f 空
代码如下
#includetypedef unsigned int uint; typedef unsigned char uchar; void Delayms(unsigned char); // 0 1 2 3 4 5 6 7 8 9 A b c d e f 空 不显示 //{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; void main() { uchar DUAN[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; uchar i; while(1) { for(i=0; i<17; i++) { P1 = 0xff;//数码管全部打开 P0 = DUAN[i]; Delayms(500); } } } //延时函数 void Delayms(unsigned char c) { unsigned char a; for(;c>0;c--) for(a=200;a>0;a--); }
封装数码管
数码管的显示已经练习完了,为了方便后面使用,我们可以来封装一下!
.C文件
#include#include"num_led.h" #define Wei P1 #define Duan P0 // 位选 //{0x08,0x04,0x02,0x01}; unsigned char LED_WEI[4] = {0xf1,0xf2,0xf4,0xf8}; //段选 // 0 1 2 3 4 5 6 7 8 9 A B C D E F 空 //{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; unsigned char LED_NUM[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; static void Num_Delayms(unsigned char c); //处理数字并显示函数 void Num_show(unsigned int num) { unsigned char i,ge; unsigned int show_num; show_num = num; // 数字达到9999 显示为“- - - -” if(show_num >= 9999) { P0 = 0x40; P1 = 0x0f; return; } //将数字转换为16进制 for(i=0; i<4; i++) { ge = show_num % 10; show_num = show_num / 10; Wei = 0xf0;//置灭 消隐! 如果不先置灭,那么在位选重新赋值前,段选赋值后显示的是上一次位选的位置 Duan = LED_NUM[ge];//置段选 Wei = LED_WEI[i];//置亮 Num_Delayms(1); if(show_num == 0) { break; //直接跳出节省时间 } } } //数字延时函数 static void Num_Delayms(unsigned char c) { unsigned char a; for(;c>0;c--) for(a=200;a>0;a--); }
.h头文件
#include//传入要显示的数字 void Num_show(unsigned int);
这里就是封装好的数码管C文件、.h头文件。然后就可以直接调用非常方便!
想要显示什么数字,调用函数传进去即可!
消隐这里作者封装的代码里就已经消隐了!
如果不知道消的什么隐,可以把上面那一行消隐的代码注释掉。
位选和段选不管哪个先赋值,都会出现隐值
如果先置段选,那么在置段选之前,需要先把位选置灭。
不然在位选重新赋值前,段选赋值后显示的是上一次位选
如果实在,没听懂的可以把消隐的那一行去掉再看看。
就是简单的逻辑问题!仔细梳理一下逻辑就可以发现的。
下一章:中断
下一章:4.中断



