80C51单片机:3.数码管显示、封装与消隐
时间:2023-05-20 21:37:00
80C51单片机系列
- 80C51单片机介绍
- 照亮第一个发光二极管和流水灯案例
- 数字管显示、包装和隐藏
文章目录
- 80C51单片机系列
- 数码管显示
-
-
- 数字管的控制逻辑
- 循环显示
-
- 封装数码管
-
- 消隐
- 下一章:中断
在上一章中,我们学会了如何操作二极管的发光熄灭。
这一节我们讲如何操作数码管,让数码管显示出数字。
数码管显示
数字管的控制逻辑
数字管的控制由位选和段选控制。
选择:哪个显示,哪个数字管显示。(例:下图中有四个数字管)
段选:即数码管显示的内容,即数码管显示的哪一段。一般每个数码管都有:a、b、c、b、e、f、g。八段(如下图所示)
简单地说:是否显示否显示,如果显示,数字管应显示什么。
现在我们大概知道数字管的控制逻辑了。
看原理图吧!
从上图(原理图)可以看出,控制数码管分为两部分。
位选
在每个数字管上连接一个串口。分别是:LEDS4、LEDS3、LEDS2、LEDS1。从上面说的数码管控制逻辑,我们可以猜到这四个串口应该是位选。
因为位选只要控制是否显示,数字管和串口就能满足需求。
所以这四个串口是:位选
段选
看下面的数码管,有八个串口,图片很清晰,a、b、c、b、e、f、g。
这八个串口连接到单片机P八串0口。
所以我们如果想要让第一个数码管显示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 空
代码如下
#include typedef 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.中断、定时器