段选:段选指的是选择数码管哪个“段”应该被点亮。一般情况下,每个“段”会连接到一个GPIO(通用输入/输出)管脚。我们通过更改GPIO电平来控制特定“段”是否点亮。例如,要显示数字“8”,我们就需要点亮所有的段。
位选:位选则是指选择哪一个数码管应该被点亮。这在我们有多个数码管需要显示不同数字或者字符的时候非常重要。比如在一个8位数码管显示器中,要显示“12345678”,我们首先选择第一位(位选)并且设置相应的“段”,以显示“1”,然后我们选择第二位并设置“段”以显示“2”,以此类推。
静态显示:在静态显示中,每一个段和每一位都直接连接到驱动电路(如微控制器)。当你需要显示一个数字或字母时,对应的段会被驱动电路点亮,同时,选中的位也会被驱动电路点亮,从而形成完整的显示。
静态显示的优点在于显示稳定,无需频繁刷新,但缺点是需要较多的驱动管脚,对于具有多位显示的数码管来说,可能需要很大的控制线路资源。
动态显示:动态显示则是一种更为经济的显示方式。在动态显示中,一次只点亮一位数码管,但是通过快速的切换显示内容,使人的眼睛看不出切换,给人一种所有数码管都同时在显示的假象,这就是视觉暂留效应。动态显示可以减少驱动管脚的数量,上大大减小了控制线路资源的需求。
但是,动态显示的缺点是需要持续刷新并维护显示内容,否则会产生闪烁。由于需要定时更新显示,对于程序而言可能更加复杂,并且会占用一部分处理器资源。在公共显示屏或者需要显示大量信息的场合,动态显示是最常用的。
开发板上用的数码管型号为F3461BH,也就是共阳极数码管。所以在段选锁存器输出端输出低电平时,数码管才能亮起来。
我画了一个表格来说明怎么设置段码的高低电平,如下图
在说完段码的设置之后,又有一个新问题就是:一共8个数码管,我们到底要把这个段码显示在哪个数码管上。
这个问题就涉及到了位选,位选就是选定我们要在哪个或哪几个数码管上显示我们的数据。我们要在哪个数码管上显示就设置哪个com为1就可以了。例如我想让第一个数码管显示,那么令P0=0x01。
记住两个点:
1.段码是低电平有效,也就是低电平使得数码管的某一段亮起来。
2.位选是高电平有效,也就是给哪个com口高电平,哪个数码管被选中。
编写流程:
清除P0口数据(P0=0xff)
---->设置138译码器,开启段选573锁存器(74HC138)
---->关闭所有锁存器
---->设置段选数据(P0=pos)
---->设置138译码器,开启位选573锁存器(74HC138)
---->设置段选数据(P0=data)
---->设置138译码器,开启段选573锁存器(74HC138)
---->关闭所有锁存器
代码如下:
void SegBit(u8 pos,u8 dat){
P0=0xff; // 清除P0先前的数据
HC573Select(7); // 开启段选锁存器
HC573Select(0); // 关闭段选锁存器
P0=0x01<<pos; // 选择要在哪个数码管上显示
HC573Select(6); // 开启位选锁存器
HC573Select(0); // 关闭位选锁存器
P0=dat; // 设置要显示什么
HC573Select(7); // 开启段选锁存器
HC573Select(0); // 关闭段选锁存器
}
代码使用技巧:也许大家不知道我为什么这么写,所以推荐大家先自己写一遍,写完后看也没有什么bug,如果没有bug那么恭喜,你很厉害。如果有bug大家参照我的代码修改一下自己的代码,会更有收获。
#include <stc15.h>
#include <intrins.h>
unsigned char code dat[]={0xc0, 0xf9, 0xa4, 0xb0, 0x99,
0x92, 0x82, 0xf8, 0x80, 0x90,
0x88, 0x83, 0xc6, 0xa1, 0x86,
0x8e, 0xff};
void selectHC573(unsigned char num)
{
switch(num)
{
case 4:
P2=(P2 & 0x1f) | 0x80;
break;
case 5:
P2=(P2 & 0x1f) | 0xa0;
break;
case 6:
P2=(P2 & 0x1f) | 0xc0;
break;
case 7:
P2=(P2 & 0x1f) | 0xe0;
break;
case 0:
P2=(P2 & 0x1f) | 0x00;
break;
}
}
void system_Init()
{
selectHC573(5);
P0=0x00;
}
void display_SMG_Bit(unsigned char dat, unsigned pos)
{
P0=0x00;
selectHC573(6);
P0=0x01<<pos-1;
selectHC573(0);
P0=0x00;
selectHC573(7);
P0=dat;
}
void display_All_SMG(unsigned char dat)
{
P0=0x00;
selectHC573(6);
P0=0xff;
selectHC573(0);
P0=0x00;
selectHC573(7);
P0=dat;
}
void Delay(unsigned int t)
{
while(t--);
while(t--);
}
void display_SMG()
{
int i,j;
for(i=0;i<9;i++)
{
for(j=0;j<10;j++)
{
display_SMG_Bit(dat[j], i);
Delay(60000);
Delay(60000);
}
}
for(j=0;j<16;j++)
{
display_All_SMG(dat[j]);
Delay(60000);
Delay(60000);
Delay(60000);
Delay(60000);
}
}
void main()
{
system_Init();
while(1)
{
display_SMG();
}
}