数码管显示
前言
- 本文主要介绍两种数码管显示原理及实验,主要内容包括:
- 1、一位数码管显示0~F,16进制对应字符;
- 2、四位数码管显示数字1234;
- 3、四位数码管实时显示LM35采集的温度值。
1 一位数码管显示
1.1 工作原理
- (1)数码管是一种半导体发光器件,其基本单元是发光二极管。按发光二极管单元连接方式可分为共阳极数码管和共阴极数码管。
- (2)共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管,共阳数码管在应用时应将公共极 COM 接到+5V,当某一字段发光二极管的阴极为低电平时,相应字段就点亮,当某一字段的阴极为高电平时,相应字段就不亮。
- (3)共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数码管,共阴数码管在应用时应将公共极 COM 接到地线 GND 上,当某一字段发光二极管的阳极为高电平时,相应字段就点亮,当某一字段的阳极为低电平时,相应字段就不亮。
- (4)共阳数码管的引脚示意图:
- (5)显示原理:
- ① 如果想点亮a段的 LED,需要a引脚提供低电平,com 口提供高电平;
- ② 在 COM引脚串联一个电阻用于分压限流。
1.2 共阳极数码管5161BS
- (1)本文选用共阳极数码管5161BS,产品外形如下图所示:
- (2)数码管引脚:
其中,com口接线选择3引脚或8引脚,并串联一个1KΩ电阻至5V电源;其余IO,结合1.1和1.2节,数码管引脚对应的LED段接入MCU。 - (3)共阳数码管显示 0~F时候的码值:
显示内容 | a | b | c | d | e | f | g | dp |
---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 |
2 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 1 |
3 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 |
4 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 |
5 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 1 |
6 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |
7 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 |
8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
9 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |
A | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
b | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |
C | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 1 |
d | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 |
E | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 |
F | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 1 |
1.3 一位数码管显示0~F
-
(1)本实验采用Arduino UNO R3开发板及自主搭建电路的方式,实现预设功能。
-
(2) 一位数码管显示的电路图,如下图所示:
-
(3)实现功能:1位共阳极数码管显示,间隔1S,循环显示0,1,2,3,4,5,6,7,8,9,A,b,C,d,E,F
代码实现:
//数码管显示
//共阳极数码管型号:5161BS
//1位共阳极数码管显示,间隔1S,循环显示0,1,2,3,4,5,6,7,8,9,A,b,C,d,E,F
#include <Arduino.h>
#define SEG_a 2 //IO命名
#define SEG_b 3
#define SEG_c 4
#define SEG_d 5
#define SEG_e 6
#define SEG_f 7
#define SEG_g 8
#define SEG_h 9
//数码管0-F数字码值
unsigned char table[16][8] =
{
{1, 1, 0, 0, 0, 0, 0, 0}, //0
{1, 1, 1, 1, 1, 0, 0, 1}, //1
{1, 0, 1, 0, 0, 1, 0, 0}, //2
{1, 0, 1, 1, 0, 0, 0, 0}, //3
{1, 0, 0, 1, 1, 0, 0, 1}, //4
{1, 0, 0, 1, 0, 0, 1, 0}, //5
{1, 0, 0, 0, 0, 0, 1, 0}, //6
{1, 1, 1, 1, 1, 0, 0, 0}, //7
{1, 0, 0, 0, 0, 0, 0, 0}, //8
{1, 0, 0, 1, 0, 0, 0, 0}, //9
{1, 0, 0, 0, 1, 0, 0, 0}, //A
{1, 0, 0, 0, 0, 0, 1, 1}, //b
{1, 1, 0, 0, 0, 1, 1, 0}, //C
{1, 0, 1, 0, 0, 0, 0, 1}, //d
{1, 0, 0, 0, 0, 1, 1, 0}, //E
{1, 0, 0, 0, 1, 1, 1, 0} //F
};
void setup()
{
pinMode(SEG_a, OUTPUT); //设置引脚为输出
pinMode(SEG_b, OUTPUT);
pinMode(SEG_c, OUTPUT);
pinMode(SEG_d, OUTPUT);
pinMode(SEG_e, OUTPUT);
pinMode(SEG_f, OUTPUT);
pinMode(SEG_g, OUTPUT);
pinMode(SEG_h, OUTPUT);
}
void loop()
{
unsigned char i;
//循环显示0,1,2,3,4,5,6,7,8,9,A,b,C,d,E,F
for ( i = 0 ; i < 16 ; i++)
{
digitalWrite(SEG_a, table[i][7]); //设置a引脚的电平
digitalWrite(SEG_b, table[i][6]); //设置b引脚的电平
digitalWrite(SEG_c, table[i][5]); //设置c引脚的电平
digitalWrite(SEG_d, table[i][4]); //设置d引脚的电平
digitalWrite(SEG_e, table[i][3]); //设置e引脚的电平
digitalWrite(SEG_f, table[i][2]); //设置f引脚的电平
digitalWrite(SEG_g, table[i][1]); //设置g引脚的电平
digitalWrite(SEG_h, table[i][0]); //设置h引脚的电平
delay(1000); //延迟1s
}
}
- (4)实现现象(显示数字6):
2 四位数码管显示
2.1 工作原理
-
(1)四位数码管简介
-
① 每一位数码管由八个发光二极管组成,其供电模式分为共阳极和共阴极两种,一般有12个引脚。
-
② 共阳极:即四位供电脚LED1+、LED2+、LED3+、LED4+需要给高电平(HIGH);八个显示A、B、C、D、E、F、G、dp需要给低电平(LOW)。
-
③ 共阴极:即四位供电引脚LED1-、LED2-、LED3-、LED4-需要给低电平(LOW);八个显示引脚A、B、C、D、E、F、G、dp需要给高电平(HIGH)。
-
④ 位选和段选:位选指通过给LED1+、LED2+、LED3+、LED4+其中一个供电电平,即哪一位亮,全给就是全都亮。段选指要显示的数字多少,这里我们用数组实现段选。
-
(2)数码管动态扫描
-
① 动态显示的特点是将所有位数码管的段选线并联在一起,由位选线控制是哪一位数码管有效。这样一来,就没有必要每一位数码管配一个锁存器,从而大大地简化了硬件电路。
-
② 选亮数码管采用动态扫描显示。所谓动态扫描显示即轮流向各位数码管送出字形码和相应的位选,利用发光管的余辉和人眼视觉暂留作用,使人的感觉好像各位数码管同时都在显示。通俗点说,动态扫描就是一位一位显示数码管的速度加快,速度达到几个 ms 以内。
-
③ 动态扫描时候去除余晖(显示模糊):在动态扫描时候切换位选时候先把段选的输出清零,然后再切换位选,这样可以有效去除余晖。
2.2 共阳极数码管3641BS
- (1)本文选用共阳极数码管3641BS,产品外形如下图所示:
- (2)数码管尺寸及引脚:
引脚6、8、9、12是段选信号,其余引脚是位选信号。
2.3 四位数码管显示数字1234
-
(1)本实验采用Arduino UNO R3开发板及自主搭建电路的方式,实现预设功能。
-
(2) 四位数码管显示数字1234的电路图,如下图所示:
-
(3)实现功能:四位数码管显示,第1位显示1,第2位显示2,第3位显示3,第4位显示4。
代码实现:
//数码管实验
//四位数码管显示,第1位显示1,第2位显示2,第3位显示3,第4位显示4
#include <Arduino.h>
#define SEG_A 2
#define SEG_B 3
#define SEG_C 4
#define SEG_D 5
#define SEG_E 6
#define SEG_F 7
#define SEG_G 8
#define SEG_H 9
#define COM1 10
#define COM2 11
#define COM3 12
#define COM4 13
unsigned char table[10][8] =
{
{1, 1, 0, 0, 0, 0, 0, 0}, //0
{1, 1, 1, 1, 1, 0, 0, 1}, //1
{1, 0, 1, 0, 0, 1, 0, 0}, //2
{1, 0, 1, 1, 0, 0, 0, 0}, //3
{1, 0, 0, 1, 1, 0, 0, 1}, //4
{1, 0, 0, 1, 0, 0, 1, 0}, //5
{1, 0, 0, 0, 0, 0, 1, 0}, //6
{1, 1, 1, 1, 1, 0, 0, 0}, //7
{1, 0, 0, 0, 0, 0, 0, 0}, //8
{1, 0, 0, 1, 0, 0, 0, 0}, //9
};
void setup()
{
pinMode(SEG_A, OUTPUT); //设置为输出引脚
pinMode(SEG_B, OUTPUT);
pinMode(SEG_C, OUTPUT);
pinMode(SEG_D, OUTPUT);
pinMode(SEG_E, OUTPUT);
pinMode(SEG_F, OUTPUT);
pinMode(SEG_G, OUTPUT);
pinMode(SEG_H, OUTPUT);
pinMode(COM1, OUTPUT);
pinMode(COM2, OUTPUT);
pinMode(COM3, OUTPUT);
pinMode(COM4, OUTPUT);
}
void loop()
{
Display(1, 1); //第1位显示1
delay(3);
Display(2, 2); //第2位显示2
delay(3);
Display(3, 3); //第3位显示3
delay(3);
Display(4, 4); //第4位显示4
delay(3);
}
void Display(unsigned char com, unsigned char num) //显示函数,com可选数值范围1-4,num可选数值范围0-9
{
digitalWrite(SEG_A, HIGH); //去除余晖
digitalWrite(SEG_B, HIGH);
digitalWrite(SEG_C, HIGH);
digitalWrite(SEG_D, HIGH);
digitalWrite(SEG_E, HIGH);
digitalWrite(SEG_F, HIGH);
digitalWrite(SEG_G, HIGH);
digitalWrite(SEG_H, HIGH);
switch (com) //选通位选
{
case 1:
digitalWrite(COM1, HIGH); //选择位1
digitalWrite(COM2, LOW);
digitalWrite(COM3, LOW);
digitalWrite(COM4, LOW);
break;
case 2:
digitalWrite(COM1, LOW);
digitalWrite(COM2, HIGH); //选择位2
digitalWrite(COM3, LOW);
digitalWrite(COM4, LOW);
break;
case 3:
digitalWrite(COM1, LOW);
digitalWrite(COM2, LOW);
digitalWrite(COM3, HIGH); //选择位3
digitalWrite(COM4, LOW);
break;
case 4:
digitalWrite(COM1, LOW);
digitalWrite(COM2, LOW);
digitalWrite(COM3, LOW);
digitalWrite(COM4, HIGH); //选择位4
break;
default: break;
}
digitalWrite(SEG_A, table[num][7]); //a查询码值表
digitalWrite(SEG_B, table[num][6]);
digitalWrite(SEG_C, table[num][5]);
digitalWrite(SEG_D, table[num][4]);
digitalWrite(SEG_E, table[num][3]);
digitalWrite(SEG_F, table[num][2]);
digitalWrite(SEG_G, table[num][1]);
digitalWrite(SEG_H, table[num][0]);
}
- (4)实现现象(显示数字1234):
2.4 四位数码管实时显示LM35采集的温度值
-
(1)本实验采用Arduino UNO R3开发板及自主搭建电路的方式,实现预设功能。
-
(2) 四位数码管实时显示LM35采集的温度值的电路图,如下图所示:
- (3)实现功能:LM35测出环境温度,四位数码管显示温度值(不显示温度单位)。
代码实现:
//数码管实验
//LM35测出环境温度,四位数码管显示温度值(不显示温度单位)
#include <Arduino.h>
#define LM35 A0
float temp, val;
int val1, val2, val3, val4, loopCount = 0;
#define SEG_A 2
#define SEG_B 3
#define SEG_C 4
#define SEG_D 5
#define SEG_E 6
#define SEG_F 7
#define SEG_G 8
#define SEG_H 9
#define COM1 10
#define COM2 11
#define COM3 12
#define COM4 13
unsigned char table[10][7] =
{
{1, 0, 0, 0, 0, 0, 0}, //0
{1, 1, 1, 1, 0, 0, 1}, //1
{0, 1, 0, 0, 1, 0, 0}, //2
{0, 1, 1, 0, 0, 0, 0}, //3
{0, 0, 1, 1, 0, 0, 1}, //4
{0, 0, 1, 0, 0, 1, 0}, //5
{0, 0, 0, 0, 0, 1, 0}, //6
{1, 1, 1, 1, 0, 0, 0}, //7
{0, 0, 0, 0, 0, 0, 0}, //8
{0, 0, 1, 0, 0, 0, 0}, //9
};
void setup()
{
pinMode(SEG_A, OUTPUT); //设置为输出引脚
pinMode(SEG_B, OUTPUT);
pinMode(SEG_C, OUTPUT);
pinMode(SEG_D, OUTPUT);
pinMode(SEG_E, OUTPUT);
pinMode(SEG_F, OUTPUT);
pinMode(SEG_G, OUTPUT);
pinMode(SEG_H, OUTPUT);
pinMode(COM1, OUTPUT);
pinMode(COM2, OUTPUT);
pinMode(COM3, OUTPUT);
pinMode(COM4, OUTPUT);
Serial.begin(9600); //初始化串口波特率为9600
}
void loop()
{
if (loopCount % 300 == 0)
{
val = analogRead(LM35);
temp = val * 0.48876 * 100; //温度值扩大100倍,方便取数
Serial.println(temp);
val1 = int(temp) / 1000 % 10; //显示第1位数码管,千位
val2 = int(temp) / 100 % 10; //显示第2位数码管,百位
val3 = int(temp) / 10 % 10; //显示第3位数码管,十位
val4 = int(temp) % 10; //显示第4位数码管,个位
}
Display(1, val1);
digitalWrite(SEG_H, HIGH);
delay(1);
Display(2, val2);
digitalWrite(SEG_H, LOW);
delay(1);
Display(3, val3);
digitalWrite(SEG_H, HIGH);
delay(1);
Display(4, val4);
digitalWrite(SEG_H, HIGH);
delay(1);
loopCount++;
}
void Display(unsigned char com, unsigned char num) //显示函数,com可选数值范围1-4,num可选数值范围0-9
{
digitalWrite(SEG_A, HIGH); //去除余晖
digitalWrite(SEG_B, HIGH);
digitalWrite(SEG_C, HIGH);
digitalWrite(SEG_D, HIGH);
digitalWrite(SEG_E, HIGH);
digitalWrite(SEG_F, HIGH);
digitalWrite(SEG_G, HIGH);
digitalWrite(SEG_H, HIGH);
switch (com) //选通位选
{
case 1:
digitalWrite(COM1, HIGH); //选择位1
digitalWrite(COM2, LOW);
digitalWrite(COM3, LOW);
digitalWrite(COM4, LOW);
break;
case 2:
digitalWrite(COM1, LOW);
digitalWrite(COM2, HIGH); //选择位2
digitalWrite(COM3, LOW);
digitalWrite(COM4, LOW);
break;
case 3:
digitalWrite(COM1, LOW);
digitalWrite(COM2, LOW);
digitalWrite(COM3, HIGH); //选择位3
digitalWrite(COM4, LOW);
break;
case 4:
digitalWrite(COM1, LOW);
digitalWrite(COM2, LOW);
digitalWrite(COM3, LOW);
digitalWrite(COM4, HIGH); //选择位4
break;
default: break;
}
digitalWrite(SEG_A, table[num][6]); //a查询码值表
digitalWrite(SEG_B, table[num][5]);
digitalWrite(SEG_C, table[num][4]);
digitalWrite(SEG_D, table[num][3]);
digitalWrite(SEG_E, table[num][2]);
digitalWrite(SEG_F, table[num][1]);
digitalWrite(SEG_G, table[num][0]);
}
- (4)实现现象(显示当前温度值):
参考资料1: Arduino:利用四位共阴极数码管读取lm35的温度值
参考资料2: 基于arduino UNO开发板的四位数码管循环计数器