1.原理图
该原理图所示,由38译码器(74HC138N),驱动芯片(74HC245),两个四位共阴数码管与STC89C52RC单片机芯片组成。
1.1 74HC138N
三八译码器为一种将三位二进制数转化为8个独立输出信号的译码器。 如将A0 A1 A2=1 1 0则转为八位数在Y0到Y7上输出0000 0100即Y6置为高电平.A0 A1 A2=111,则转为八位数在Y0到Y7上输出0000 0001即Y7置为高电平。 如上图,
CS1,CS2,CS3为三个片选信号输入端,当CS1置为1,CS2CS3同时置为0时,该译码器译码。 而该电路通过NPN型三极管与一个10kΩ电阻连接到P36可通过P36引脚置1置0来控制译码器工作。 当P36置为0时,此时三极管处于截止状态(b=0时,c=0,e=0),不导通,CS1为高电平,正常译码。当P36置为1时,此时三极管处于饱和状态,此时相当于开关的导通状态,此时集电极电压为0,CS1为低电平,停止译码。
1.2 74HC245驱动芯片
由于51单片高电平的驱动能力很微弱,不足以点亮数码管,因此可以使用74HC245N作为驱动芯片。 下图为单片机某一引脚内部结构,
2.软件设计
如上图,数码管位选通过P13,P14,P15实现,段选通过P00-P07实现。
#include <STC89C5xRC.H> //包含STC89C52的头文件
#include <INTRINS.H>
#define SMG_EN P36
// 增加自定义类型,简化代码编写
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
// 数码管显示缓存
static u8 s_digital_buffer[8];
// 数字0-9的编码
static char s_digital_codes[10] = {
0x3F, // 0
0x06, // 1
0x5B, // 2
0x4F, // 3
0x66, // 4
0x6D, // 5
0x7D, // 6
0x07, // 7
0x7F, // 8
0x6F // 9
};
void DigitalTube_Refresh();
void DigitalTube_DisplayNum(u32 num);
void main()
{
// 打开数码管总开关
SMG_EN = 0;
// 让数码管显示12345678
DigitalTube_DisplayNum(12345678);
// 不断刷新数码管
while (1)
{
DigitalTube_Refresh();
}
}
/**
* @brief 将要显示的数字写进数码管的缓存
*
* @param num 要显示的数字
*/
void DigitalTube_DisplayNum(u32 num)
{
u8 i;
// 将显存清零
for (i = 0; i < 8; i++)
{
s_digital_buffer[i] = 0;
}
// 如果待展示的数字为0,直接展示
if (!num)
{
s_digital_buffer[7] = s_digital_codes[0];
return;
}
// 赋值显存
i = 7;
while (num > 0)
{
// 对显存赋值,如果num是12345,则s_digital_buffer[]里面依次存储0,0,0,0x06,0x5B,0x4F,0x66,0x6D
s_digital_buffer[i] = s_digital_codes[num % 10];
i--;
num /= 10;
}
}
void Delay1ms(u16 count) //@11.0592MHz
{
u8 i, j;
while (count > 0)
{
count--;
nop();
i = 2;
j = 199;
do
{
while (--j)
;
} while (--i);
}
}
/**
* @brief 让数码管的某一位显示特定的组合
*
* @param dig 片选,取值范围[0-7]
* @param dat 段选信号
*/
static void DigitalTube_DisplaySingle(u8 dig, u8 dat)
{
// 关掉当前数码管
P0 = 0;
// 完成片选
P1 &= 0xC7; // 置零
dig <<= 3; // 左移
P1 |= dig;
// 段选
P0 = dat;
}
void DigitalTube_Refresh()
{
u8 i;
// 依次刷新8位数码管
for (i = 0; i < 8; i++)
{
DigitalTube_DisplaySingle(i, s_digital_buffer[i]);
// 延时增加占空比
Delay1ms(1);
}
}