#如何控制数码管

第二次任务

1.如何控制单个数码管

通过引脚P2_4,P2_3,P2_2,进行位选,即选择哪一个数码管进行显示(一次只能控制一个数码管进行显示)若我们想控制第三个数码管进行显示
则先将3减一后转化为三位二进制数010,再取反为101,然后P2_4取1,P2_3取0,P2_2取1.

然后进行段选,即选择一个数码管的哪一个灯进行选择。如果我们想第三个数码管显示3,那么查看电路图,需要a,b,c,d,g对应引脚的小灯进行显示,然后将这些引脚记为1,其他引脚(包括dp端口)记为0,得到11110010,再倒着写,写成01001111,转化为16进制数0x4f,然后P0取0x4f
主函数内容如下

whlie(1)
{ 
    P2_4=1;
    P2_3=0;
    P2_2=0;
    P0=0x4f;
}

即可对一个数码管进行控制。

而在实际应用中,通常用函数实现位选,用数组实现段选

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];
}

这样,前面提到的主函数内容就可以简化为

whlie(1)
{
   Nixie(3,3);  
}

以下均省略该数组和该函数。

2.如何控制多个数码管

1.多个数码管依次显示

这里先定义一个延时函数,单位为ms

void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--){
		i = 2;
		j = 239;

		do
		{
			while (--j);
		} while (--i);
	}
}

然后若想实现第一,第二,第三数码管依次显示1,2,3,间隔为0.1s,则主函数内容为

while(1)
{
  Nixie(1,1);
  Delay(100);
  Nixie(2,2);
  Delay(100);
  Nixie(3,3);
  Delay(100);
}

2.多个数码管“同时”显示

虽然单片机同时只能控制一个数码管,但我们可以使单片机快速依次显示多个数码管,间隔小于肉眼分辨间隔,这样就可以实现多个数码管“同时”显示。

while(1)
{
  Nixie(1,1);
  Nixie(2,2);
  Nixie(3,3);
}

下载上述代码并启动单片机,我们可以发现数码管出现“残影”。理想情况下单片机进行以下流程:

段选->位选->段选->位选->段选->位选

但是单片机运行速度很快,导致进行下一位段选时,下一位位选数据还没到,数码管就只能对上一个位选数据进行显示,从而造成“残影”
故我们要在下一位段选前要清除位选数据,实现消影。在子函数中进行如下修改

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=0xff;//清除数据
}

3.部分数码管动态显示,部分数码管静态显示

如果我们想让第七个数码管一直显示0,第八个数码管每一秒从0加到9,到9一秒后再归0呢?

如果直接加入自定义的延时函数

unsigned char num = 0;
void main()
{
    while(1)
    {
     if(num==10)
     {
      num=0;
     }
     Nixie(7,0);
     Nixie(8,num);
     Delay(1000);
     num++;
    }
}

会发现不但第八个数码管显示异常,而且第七个数码管在闪烁,明显不符合预期。

所以我们要换个思路想一想。

我们可以发现,在数码管显示的子函数中,不计程序执行代码的时间,每一次显示一个数码管,就要经历一个Delay(1),即要经历1ms。所以我们可以利用这个来进行计时,不仅可以保证部分数码管持续显示,还能进行部分数码管动态显示。

由计算可知,一次While循环要用2ms,1s总共经历500个while。故定义一个变量time,每经历1个while就记一次时,time等于500时num再加一。

unsigned char num = 0;
unsigned int time = 0;
void main()
{
    while(1)
    {	
        Nixie(7,0);
        if(num==10)
        {
        num=0;
        }
        Nixie(8,num);
        time++;
        if(time==500)
        {
            time=0;
            num++;
        }
    }
}

下载并运行,数码管如我们所想的那些运行。

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值