单片机原理及应用:数码管的动态扫描显示、余晖效应与消影

发布时间:2023年12月31日

动态显示

动态显示是一种一位一位地轮流点亮各位数码管的显示方式。 当数码管显示位数较多时,静态显示所占的I/O口多 ,这时常采用动态显示。为节省I/O口,通常将所有显示器段码线相应段并联在一起,由一个8位I/O口控制,称为“段选”;各显示位公共端分别由另一单独I/O口线控制,称为“位选”。在某一时段只选中一位数码管的位选端并送出相应的字型编码,在下一时段按顺序选通另外 一位数码管,并送出相应的字型编码。依此规律循环下去,即可使各位数码管分别间断地显示出相应的字符,这一过程称为动态扫描显示。
我们在进行动态显示时,可以通过调整单片机的延时函数,来让数字顺序出现或同时出现。
下面用8只数码管滚动显示的案例来说明动态显示的效果。
#include<reg52.h>
#include<intrins.h>		//要用到库函数,先调包
#define uchar unsigned char
#define uint unsigned int
uchar code dis_code[]={0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80};              		                           //共阳数码管段码表
void  delay(uint t)				//可自定义延时函数,调用时给t赋值即可
{								//延时倍率是t乘200
	uchar i;
	while(t--) for(i=0;i<200;i++);
}
	 //从左到右点亮数码管
     void  main()
{	
	uchar j=0x80;		    //最左位赋值1
	while(1)
  {	uchar i;
	for(i=0;i<8;i++)
	{	   
	       j=_crol_(j,1);	//库函数左移
		   //j=_cror_(j,1);		//库函数右移
	       P0=dis_code[i];	//P0口输出段码
	       P2=j;			//P2口输出位码
	       delay(180);		//数码管顺序显示
		   //delay(2);		//数码管同时显示
		   //P0 = 0xff;		//数码管全灭消影
	}
  }
}

/*	 //从右往左倒数
     void  main()
{	
	uchar j=0x01;		    //最左位开始点亮
	while(1)
  {	uchar i;
	for(i=0;i<8;i++)
	{	   
		   j=_cror_(j,1);		//库函数右移
	       P0=dis_code[7-i];	//要注意数组索引从0开始,所以要用7-i
	       P2=j;			
	       delay(180);		
	}
  }
} */ 
这次编写代码也犯了个啼笑皆非的错误,贴出来让大伙笑一笑引以为戒。
结果我编译了好多次都没通过,实际上看到完整的电路图大家就明白了,我赋值的0x80,这个1在最左端,实际上是一组端口的第8个引脚,之前流水灯展示的时候都是把第一个引脚对应的LED放在最右侧,所以才有的从右到左流水灯,现在引脚的“左右”和数码管排列的左右正好相反,自然左移位码就达到了右移点亮数码管的效果了。希望我的错误能给大家一个提醒,在写代码和做仿真的时候一定要认真仔细,不然就会弄巧成拙。

看到这里可能有小伙伴要问了,这样来看数码管的原理和流水灯也没什么不同,怎么样才能让数字同时出现呢。这就要用到我们人眼的余晖效应了。

余晖效应

余晖效应,即视觉暂留现象,是当人眼所看到的影像消失后,人眼仍能继续保留其影像0.1-0.4秒左右图像的情况。原因是眼睛依靠晶状体成像,感光细胞感光,并且将光信号转换为神经电流,传回大脑引起人体视觉,而感光细胞的感光需要感光色素,感光色素的形成消耗一定时间,这就形成了视觉暂留的机理。

从效果图上可以看到,数码管的点亮速度甚至超过了计算机截屏的速度,以至于截图也呈现出视觉暂留现象。

#include <reg52.h>
unsigned char code Tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C};//段码,共阴极真值表
unsigned char code Col[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};  //位码,类似于点亮流水灯
void Delay()
{
  unsigned char i;
     for(i=0;i<250;i++);   //第二类延时函数
}

void main()                
{
  unsigned char j;
  while(1)
  {
    
    for(j=1;j<7;j++)	  //段码位码都采用数组法,要注意j初值1
	{
      P0=Tab[j];          //段选j,因为不显示0
      P1=Col[j-1];        //位选j-1
      Delay();
      P1=0xff;               //关位选,防止出现鬼影
	  //P0=0;				 //关掉段选也可以,给低电平,
	}
  }
}

这里出现了第2类延时函数,单独的一个for循环,数量级为百,即0.1ms,用前面代码中提到的自定义延时函数也可以,传入个位数参数即可。相较于前面的移位符,数组法明显没有那么复杂。效果如图所示:

消影?

“影”指的是当切换一个数码管的数字时,由于数码管刷新频率有限,液晶分子需要一定的时间来重新排列,这可能会导致前一个数码管数字的残影留在屏幕上。我们可以通过切断段选或位选的方式来消除残影。

代码如图所示

两种方法采取一种即可,但要注意是共阴极接法还是共阳极,有可能一不小心把数码管全都打开了。

视频演示

数码管动态显示循环点亮和视觉暂留

以上就是本篇文章的全部内容了,感谢观看。?

文章来源:https://blog.csdn.net/qq_62530454/article/details/135303872
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。