51单片机小白零基础教程——数码管的动态显示(以及一些程序的扩展)

数码管的动态显示


数码管的动态显示:数码管的动态显示又叫做数码管的动态扫描。动态显示的特点是:将所有位数码管段选线并联在一起,,由位选控制是哪一位数码管有效。所谓动态扫描显示即轮流向各位数码管送出字型码和相应的位选,利用发光管的余晖和人眼视觉暂留作用,使人感觉好像各位数码管同时都在显示,而实际上多位数码管是一位一位轮流显示的,只是轮流的速度比较快,人眼已经无法分辨出来。

关于数码管以及74HC573锁存器的分析放在这,有详细的分析过程,请自行查看https://blog.csdn.net/chrisbum/article/details/115583779?spm=1001.2014.3001.5502

设计要求:在实验板上,第一个数码管显示数字0,时间为1ms,然后关闭它,立即让第二个数码管显示1,时间为1ms,再关闭它,直到最后一个数码管显示7,时间同样为1ms,关闭它再回来显示第一个数码管,一直循环下去。

方法1(比较常规)
程序:

#include 	//51单片机头文件

sbit WE = P2^7;		//位选信号的锁存器控制 位定义 WE为标识符 代表着位选 P2^7为地址符 	申明U8锁存器的锁存端
sbit DU = P2^6;		//段选信号的锁存器控制 位定义 DU为标识符 代表着段选 P2^7为地址符 	申明U9锁存器的锁存端

#define uchar unsigned char  //宏定义(预处理指令,不是语句,后面不用加分号)其中直接用uchar替换了unsigned char 此时我们可以用uchar num等价于unsigned char num;
#define uint unsigned int	 //宏定义(用法和上面类似)

uchar code table[] = {	 //显示0~f的码表
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};

void delay(uint z)  //延时函数
{
	unsigned int x,y;
	for(x = z;x>0;x--)
		for(y=144;y>0;y--);
}

int main() //主函数
{
	while(1) //大循环
	{
		P0 = 0xff;  //在进行位选择时候,先关闭所有显示,防止打开位选时,P0口还保持原来的数据 
		WE = 1;  //打开U8锁存器 
		P0 = 0xfe;	//第1个数码管显示
		WE = 0;  //关闭U8锁存器
	    DU = 1;  //打开U9锁存器
		P0 = table[0]; //调用数组
		delay(1);  //调用延时函数

		P0 = 0xff; 
		WE = 1;   
		P0 = 0xfd;	//第2个数码管显示
		WE = 0;  
	    DU = 1;  
		P0 = table[1]; //调用数组,显示数字
		delay(1);  //调用延时函数

		P0 = 0xff; 
		WE = 1;   
		P0 = 0xfb;	//第3个数码管显示
		WE = 0;  
	    DU = 1;  
		P0 = table[2]; //调用数组,显示数字2
		delay(1);  //调用延时函数

		P0 = 0xff; 
		WE = 1;   
		P0 = 0xf7;	//第4个数码管显示
		WE = 0;  
	    DU = 1;  
		P0 = table[3]; //调用数组,显示数字3
		delay(1);  //调用延时函数

		P0 = 0xff; 
		WE = 1;   
		P0 = 0xef;	//第5个数码管显示
		WE = 0;  
	    DU = 1;  
		P0 = table[4]; //调用数组,显示数字4
		delay(1);  //调用延时函数

		P0 = 0xff; 
		WE = 1;   
		P0 = 0xdf;	//第6个数码管显示
		WE = 0;  
	    DU = 1;  
		P0 = table[5]; //调用数组,显示数字5
		delay(1);  //调用延时函数

		P0 = 0xff; 
		WE = 1;   
		P0 = 0xbf;	//第7个数码管显示
		WE = 0;  
	    DU = 1;  
		P0 = table[6]; //调用数组,显示数字6
		delay(1);  //调用延时函数

		P0 = 0xff; 
		WE = 1;   
		P0 = 0x7f;	//第8个数码管显示
		WE = 0;  
	    DU = 1;  
		P0 = table[7]; //调用数组,显示数字7
		delay(1);  //调用延时函数
	}
}

效果:
51单片机小白零基础教程——数码管的动态显示(以及一些程序的扩展)_第1张图片
需要注意程序段中有一行程序为:

P0 = 0xff;  //在进行位选择时候,先关闭所有显示,防止打开位选时,P0口还保持原来的数据 

这条语句有一个专业的名字叫”消影“
”消影“:在刚送完段选数据后,P0口仍然保持着上次段选的数据,接下来要执行打开位选锁存器的命令后,原来保持在P0口的段选数据将立即通过位选锁存器直接加在数码管上,接下来才是再次通过P0口给位选锁存器送入位选数据,虽然这个过程很短暂,但是在数码管高速显示状态下,会出现数码管乱码的现象,加上”消影“后,在开启位选锁存器后,P0口全为高电平,所以哪个数码管都不后亮,所以”消影“很重要。

方法2(代码格式比较简单)
程序:

#include 	//51单片机头文件
#define uchar unsigned char  //宏定义(预处理指令,不是语句,后面不用加分号)其中直接用uchar替换了unsigned char 此时我们可以用uchar num等价于unsigned char num;
#define uint unsigned int	 //宏定义(用法和上面类似)

sbit DU = P2^6;		//段选信号的锁存器控制
sbit WE = P2^7;		//位选信号的锁存器控制

uchar num;

uchar code WEI [] = {
0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f};	 //数码管各位的码表

uchar code DUAN [] ={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};	//0-f的码表

void delay(uint z)
{
	uint x,y;
	for(x = z;x>0;x--)
		for(y = 144;y>0;y--);  
}							   //延时函数

void main()
{
	while(1)
	{
		for(num=0;num<8;num++)
		{
			P0 = 0xff;	 //在进行位选择时候,先关闭所有显示,防止打开位选时,P0口还保持原来的数据  
			WE = 1;
			P0 = WEI[num];
			WE = 0;
 
			DU = 1;
			P0 = DUAN[num];
			DU = 0;
			delay(1);	 //时间间隔短,这是关键(所谓的同时显示,只是间隔较短而已,利用人眼的余辉效应,觉得每个数码管都一直在亮)。
		 }
	}
}

效果:
51单片机小白零基础教程——数码管的动态显示(以及一些程序的扩展)_第2张图片

进阶显示1
设计要求:
在单片机上,让第一位数码管显示数字1,接着让第二位数码管显示数字2,以此类推,最后让第八个数码管显示数字7。

程序:

#include 
#define uchar unsigned char
#define uint unsigned int

sbit DU = P2^6;		//段选信号的锁存器控制
sbit WE = P2^7;		//位选信号的锁存器控制

uchar num;
uchar code WEI[] = {
0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f};
						//数码管各位的码表
uchar code DUAN[] = {
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,};
						//0-7的码表
void delay(uint z)		//延时函数
{
	uint x,y;
	for(x = z;x>0;x--)
		for(y = 144;y>0;y--);
}

void main()			   //主函数
{
	while(1)		   //大循环
	{
		for(num=0;num<8;num++) //进行for循环,在num大于等于8之前一直执行花括号中的内容,直到循环结束
		{	   
			P0 = 0xff;          //消影
			WE = 1;			   //打开位选锁存器
			P0 = WEI[num];	   //调用数组
			WE = 0;			   //关闭位选锁存器
	  
			DU = 1;			   //打开段选锁存器
			P0 = DUAN[num];	   //调用数组
			DU = 0;			   //关闭段选锁存器
			delay(500);		   //延时函数 注意:小括号内的数越大数码管显示的时候给人带来的视觉缓存就越大
		 }
	}
}

效果:

你可能感兴趣的:(单片机,编程语言,c语言)