嵌入式开发学习(STC51-5-数码管)

内容

静态数码管:最左端显示0
动态数码管:从左到右,显示0-9

数码管简介

数码管是一种半导体发光器件,其基本单元是发光二极管;

类别:

  • 数码管按段数可分为七段数码管和八段数码管,八段数码管比七段数码管多一个发光二极管单元,也就是多一个小数点(DP),这个小数点可以更精确的表示数码管想要
    显示的内容;
  • 按能显示多少个(8)可分为1位、2位、3位、4位、5位、6位、7位等数码管;
  • 按发光二极管单元连接方式可分为共阳极数码管和共阴极数码管;

共阳数码管和共阴数码管:

  • 共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管,共阳数码管在应用时应将公共极COM接到+5V,当某一字段发光二极管的阴极为低电平时,相应字段就点亮,当某一字段的阴极为高电平时,相应字段就不亮;
  • 共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数码管,共阴数码管在应用时应将公共极COM接到地线GND上,当某一字段发光二极管的阳极为高电平时,相应字段就点亮,当某一字段的阳极为低电平时,相应字段就不亮;

显示原理

我们开发板上使用的数码管是2个四位一体的共阴极数码管(即8个LED的阳极全部并联一起引出,阴极分别引出如A、B、……、DP);

如果要让共阴数码管显示数字0,即对应的段ABCDEF要点亮即给它高电平,其他的段熄灭即给它低电平,其他的数字显示方式一样;

共阴和共阳数码管的0-F段码数据表

  • 共阴数码管码表
0x3f 0x06 0x5b 0x4f 0x66 0x6d 0x7d 0x07 0x7f 0x6f 0x77 0x7c 0x39 0x5e 0x79 0x71 0x00
0 1 2 3 4 5 6 7 8 9 A B C D E F 无显示
  • 共阳数码管码表
0xC0 0xF9 0xA4 0xB0 0x99 0x92 0x82 0xF8 0x80 0x90 0x88 0x83 0xC6 0xA1 0x86 0x8E 0xFF
0 1 2 3 4 5 6 7 8 9 A B C D E F 无显示

从上述共阳和共阴码表中不难发现,它们的数据正好是相互取反的值;

共阴数码管数字0段码,0x3f,其二进制是0011 1111,该段码数据由来,是将dp段做为最高位,a段作为最低位,共8位,正好和51单片机的一组端口数一样,因此可以直接使用某一组端口控制数码管的段选数据口,比如P0口

静态数码管显示原理

每个数码管的段选接一个8位数据线来保持显示的字形码,当送入一次字形码后,显示字形可一直保持,直到送入新字形码为止;

优点是占用CPU时间少,显示便于监测和控制;

缺点是硬件电路比较复杂,成本较高,比如使用4个静态数码管,那么就得32个IO来控制,这对51单片机来说是无法承受的;

动态数码管显示原理

将所有数码管的段选线并联在一起,由位选线控制是哪一位数码管有效;

选亮数码管采用轮流显示的方式,利用发光管的余辉和人眼视觉暂留作用,使人的感觉好像各位数码管同时都在显示;

动态显示的亮度比静态显示要差一些,所以在选择限流电阻时应略小于静态显示电路的电阻;

原理图

线路图
嵌入式开发学习(STC51-5-数码管)_第1张图片
嵌入式开发学习(STC51-5-数码管)_第2张图片

由原理图可以看出,P00-07管脚控制数码管显示的图形,P22-24控制哪个数码管被点亮;

因为单片机IO口外部都增加了外部上拉电阻,因此P22、P23、P24引脚默认就是高电平,根据74HC138译码器输出特点,此时Y7脚输出有效(即LED8点亮),为低电平;

而数码管的段选a-dp连接在74HC245驱动芯片输出口,由P0端口控制,所以只要控制P0口输出高电平,SMG1最左边那个数码管默认就可以显示;

静态数码管

思路

让P0口设置为0的的段码数据,即可在最左端显示数字0

编码

main.c

/*
 * @Description: 静态数码管-最左端显示0
 */
#include "reg52.h"

typedef unsigned int u16; // 对系统默认数据类型进行重定义
typedef unsigned char u8;

#define SMG_A_DP_PORT P0 // 使用宏定义数码管段码口

// 共阴极数码管显示0~F的段码数据
u8 gsmg_code[17] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71};

void main()
{
	SMG_A_DP_PORT = gsmg_code[0]; // 将数组第1个数据赋值给数码管段选口
	while (1)
	{
	}
}

编译和结果

按F7编译,无错误,生成.hex文件,使用pz-isp将hex文件下载到单片机

结果:数码管最左端显示0
嵌入式开发学习(STC51-5-数码管)_第3张图片

动态数码管

思路

人的肉眼正常情况下只能分辨变化超过24ms间隔的运动;

所以我们可以循环点亮各个数码管,并且这个循环间隔不超过24ms,这样看起来就是每个数码管都被点亮了;

编码

main.c

/*
 * @Description: 动态数码管-从左到右,显示0-9
 */
#include "reg52.h"

typedef unsigned int u16; // 对系统默认数据类型进行重定义
typedef unsigned char u8;

#define SMG_A_DP_PORT P0 // 使用宏定义数码管段码口

// 定义数码管位选信号控制脚
sbit LSA = P2 ^ 2;
sbit LSB = P2 ^ 3;
sbit LSC = P2 ^ 4;

// 共阴极数码管显示0~F的段码数据
u8 gsmg_code[17] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71};

/**
 * @description: 延时函数(循环一次大约10us)
 * @param {u16} ten_us
 * @return {*}
 */
void delay_10us(u16 ten_us)
{
	while (ten_us--)
		;
}

/**
 * @description: 循环点亮各个数码管
 * @return {*}
 */
void smg_display(void)
{
	u8 i = 0;

	for (i = 0; i < 8; i++)
	{
		switch (i) // 位选
		{
		case 0:
			LSC = 1;
			LSB = 1;
			LSA = 1;
			break;
		case 1:
			LSC = 1;
			LSB = 1;
			LSA = 0;
			break;
		case 2:
			LSC = 1;
			LSB = 0;
			LSA = 1;
			break;
		case 3:
			LSC = 1;
			LSB = 0;
			LSA = 0;
			break;
		case 4:
			LSC = 0;
			LSB = 1;
			LSA = 1;
			break;
		case 5:
			LSC = 0;
			LSB = 1;
			LSA = 0;
			break;
		case 6:
			LSC = 0;
			LSB = 0;
			LSA = 1;
			break;
		case 7:
			LSC = 0;
			LSB = 0;
			LSA = 0;
			break;
		}
		SMG_A_DP_PORT = gsmg_code[i]; // 传送段选数据
		delay_10us(100);			  // 延时一段时间,等待显示稳定
		SMG_A_DP_PORT = 0x00;		  // 消影
	}
}

void main()
{
	while (1)
	{
		smg_display();
	}
}

编译和结果

按F7编译,无错误,生成.hex文件,使用pz-isp将hex文件下载到单片机

结果:
嵌入式开发学习(STC51-5-数码管)_第4张图片

你可能感兴趣的:(嵌入式开发学习,学习,51单片机)