数码管介绍
LED数码管:数码管是一种简单、廉价的显示器,是由多个发光二极管封装在一起组成“8”字型的器件。
一位数码管引脚定义
数码管的接法,有共阳和共阴之分。
- 共阴时,拉高电压即可点亮。
- 共阳时,拉低电平点亮。
开发板四位一体的数码管引脚定义
数码管段码表(共阴极电路)
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 |
0011 1111 | 0000 0110 | 0101 1011 | 0100 1111 | 0110 0110 | 0110 1101 | 0111 1101 | 0000 0111 | 0111 1111 | 0110 1111 | 0111 0111 | 0111 1100 | 0011 1001 | 0101 1110 | 0111 1001 | 0111 0001 | 0000 0000 |
0x00
是用来实现消影效果的,将数码管清零。
- 7段发光二极管加上1个小数点dp共计8段,字形代码与这8段的关系如下:
- 字形代码与十六进制数的对应关系见下表。从表中可以看出,共阴极与共阳极的字形代码互为补数。
数码管驱动方式
- 单片机直接扫描:硬件设备简单,但会耗费大量的单片机CPU时间
- 专用驱动芯片:内部自带显存、扫描电路,单片机只需告诉它显示什么即可
硬件原理图
138译码器
- 138译码器控制数码管使能(使用3个单片机输入控制8个数码管显示),每个数字的一个笔画由双向数据缓存器245(单片机输出能力有限,需要该芯片提高输入能力)控制亮灭。
- 因此,首先控制P2_2~P2_4来选中数码管,然后选中数码管的笔画,最终呈现数据。
- ABC中C为高位,138译码器可以将可将地址端(A、B、C)的二进制编码在Y0至Y7对应的输出端以低电平译出。
- Y表示三位二进制对应的十进制数,当Y=0时表示Y0有效,既Y0为0,其余位为1,其他位的输出也是如此。
动态数码管模块
- 数码管分为位选和段选,138译码器控制数码管的位选,通过138译码器选择LED1~8哪个显示数字,74HC245控制数码管段选,显示数字的每个部分实质上是LCD灯,通过点亮不同部分的而实现数字的显示。
- 例如:要使第一个数码管显示数字1,在段选的时候就要点亮f段和e段,对应的八位二进制数为1111 0011转化为十六进制为E3。
- 每个数码管可以显示的数字均为0~9,可以通过数组存储每个数字显示的所对应的十六进制断码,进而访问数组的各个元素,实现数码管数字的显示。
C语言知识补充
C51单片机数组
数组:把相同类型的一系列数据统一编制到某一个组别中,可以通过数组名+索引号简单快捷的操作大量数据
int x[3]; //定义一组变量(3个)
int x[]={1,2,3}; //定义一组变量并初始化
x[0] //引用数组的第0个变量
x[1] //引用数组的第1个变量
x[2] //引用数组的第2个变量
引用x[3]时,数组越界,读出的数值不确定,应避免这种操作
51单片机子函数
子函数:将完成某一种功能的程序代码单独抽取出来形成一个模块,在其它函数中可随时调用此模块,以达到代码的复用和优化程序结构的目的
void Function(unsigned char x, y)
{
……
}
返回值 函数名(形参)
{
函数体
}
数码管实操
3-1 静态数码管的显示
1、在指定路径下创建工程并添加新文件
2、编写代码
#include <REGX52.H>
unsigned char NixieTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71, 0x00};
void Nixie(unsigned char Location,Number)
{
switch(Location)
{
case 1: P2_4=1;P2_3=1;P2_2=1;
break;
case 2: P2_4=1;P2_3=1;P2_2=0;
break;
case 3: P2_4=1;P2_3=0;P2_2=1;
break;
case 4: P2_4=1;P2_3=0;P2_2=0;
break;
case 5: P2_4=0;P2_3=1;P2_2=1;
break;
case 6: P2_4=0;P2_3=1;P2_2=0;
break;
case 7: P2_4=0;P2_3=0;P2_2=1;
break;
case 8: P2_4=0;P2_3=0;P2_2=0;
break;
}
P0=NixieTable[Number];
}
void main()
{
Nixie(7,3);
while(1)
{
}
}
- 定义了一个
NixieTable
数组,存储了数字0
到9
和一些特殊字符对应的数码管段码值。这些值将用于在数码管上显示相应的数字或字符。Nixie
子函数接受两个参数:Location
和Number
。该函数通过Location
参数控制数码管的位置,通过Number
参数确定要显示的数字。
具体操作:通过设置51单片机的GPIO
口来控制数码管的位置,然后将NixieTable
数组中对应Number
位置的值写入P0
口,从而在数码管上显示对应的数字。- 在主函数
main
中,调用Nixie
函数将数字3
显示在位置7
的数码管上。while(1)
无限循环来让程序持续执行。
3-2 动态数码管的显示
1、在指定路径下创建工程并添加新文件
2、编写代码
#include <REGX52.H>
unsigned char NixieTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71, 0x00};
//延时函数
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
//xms--;
}
}
void Nixie(unsigned char Location,Number)
{
switch(Location)
{
case 1: P2_4=1;P2_3=1;P2_2=1;
break;
case 2: P2_4=1;P2_3=1;P2_2=0;
break;
case 3: P2_4=1;P2_3=0;P2_2=1;
break;
case 4: P2_4=1;P2_3=0;P2_2=0;
break;
case 5: P2_4=0;P2_3=1;P2_2=1;
break;
case 6: P2_4=0;P2_3=1;P2_2=0;
break;
case 7: P2_4=0;P2_3=0;P2_2=1;
break;
case 8: P2_4=0;P2_3=0;P2_2=0;
break;
}
//消影
//位选 段选 清零(防止数据串位) 位选 段选
P0=NixieTable[Number];
Delay(1);
P0=0x00;
}
void main()
{
while(1)
{
Nixie(1,1);
Delay(300);
Nixie(2,2);
Delay(300);
Nixie(3,3);
Delay(300);
Nixie(4,4);
Delay(300);
Nixie(5,5);
Delay(300);
Nixie(6,6);
Delay(300);
Nixie(7,7);
Delay(300);
Nixie(8,8);
Delay(300);
}
}
- 定义了一个
NixieTable
数组,存储了数字0
到9
和一些特殊字符对应的数码管段码值。这些值将用于在数码管上显示相应的数字或字符。
注意最后一个0x00
是用于消影的,将数码管清零。Delay
延时函数:控制显示数字时的延时。在该函数中,使用了一个简单的嵌套循环来进行延时,实现了以毫秒为单位的延时。Nixie
函数接受两个参数:Location
和Number
。该函数通过Location
参数控制数码管的位置,通过Number
参数确定要显示的数字。
具体操作:通过设置51单片机的GPIO
口来控制数码管的位置,然后将NixieTable
数组中对应Number
位置的值写入P0
口,从而在数码管上显示对应的数字。
在显示完数字后,调用Delay(1)
函数进行短暂延时,然后将P0
口清零,以实现消影效果。- 在主函数
main
中,使用一个无限循环,依次调用Nixie
函数显示数字1
到8
在不同的位置,并在每次显示后通过Delay
函数进行短暂延时。通过不断循环调用Nixie
函数,实现了循环显示数字1到8的效果。