单片机学习9——数码管动态显示

#include

#define uchar unsigned char
#define uint unsigned int

sbit dula=P0^6;
sbit wela=P0^7;

uchar num, duan_num, wei_num;

uchar code table_duan[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,
0x7d,0x07,0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};

uchar code table_wei[]={
0xfe,0xfc,0xfb,0xf7,0xef,0xdf};

void display();

void main()
{
    //打开定时器中断
	EA=1;
	ET0=1;
	//设置定时器工作模式
	TMOD=0x01;
	//十六位定时器,就使用65536,装初值
	TH0=(65536-50000)/256;
	TL0=(65536-50000)%256;
	//启动定时器,有几种启动方式
	TR0=1;

	while(1)
	{
		if(num==20)	  //是否到了1s
		{
		 	num=0;
			if(duan_num==6)
			{
				duan_num=0;
			}
			if(wei_num==6)
			{
			 	wei_num=0;
			}
			display();
			duan_num++;
			wei_num++;
		}	
	}
}

//中断函数不需要声明和调用
void time0() interrupt 1
{
	TH0=(65536-50000)/256;
	TL0=(65536-50000)%256;
	num++;	
}

void display()
{
	P0=table_duan[duan_num+1];
	dula=1;
	dula=0;
	P0=table_wei[wei_num];
	wela=1;
	wela=0;
}

程序加载到单片机中,看到数码管是1个个地显示,第一个数码管显示1,第二个数码管显示2,……1秒钟显示一个数码管。

然后老师将程序进行修改。

#include

#define uchar unsigned char
#define uint unsigned int

sbit dula=P0^6;
sbit wela=P0^7;

uchar num, duan_num, wei_num;

uchar code table_duan[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,
0x7d,0x07,0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};

uchar code table_wei[]={
0xfe,0xfc,0xfb,0xf7,0xef,0xdf};

void display();

void main()
{
    //打开定时器中断
	EA=1;
	ET0=1;
	//设置定时器工作模式
	TMOD=0x01;
	//十六位定时器,就使用65536,装初值
	TH0=(65536-500)/256;
	TL0=(65536-500)%256;
	//启动定时器,有几种启动方式
	TR0=1;

	while(1)
	{
		if(num==2)	  //是否到了1s
		{
		 	num=0;
			if(duan_num==6)
			{
				duan_num=0;
			}
			if(wei_num==6)
			{
			 	wei_num=0;
			}
			display();
			duan_num++;
			wei_num++;
		}	
	}
}

//中断函数不需要声明和调用
void time0() interrupt 1
{
	TH0=(65536-500)/256;
	TL0=(65536-500)%256;
	num++;	
}

单片机学习9——数码管动态显示_第1张图片

这个就是动态扫描。

每个数码管是1ms的显示间隔。我们从原来的1s,除以1000,得到1ms。

动态显示的特点是将所有数码管的段选线并联在一起,由位选线控制室哪一位数码管有效。这样就没有并要为每一位数码管配一个锁存器,大大简化了硬件电路。选亮数码管采用动态扫描显示。

所谓动态扫描,即是通过分时轮流送出字形码和相应的位选,使各个数码管轮流收控显示。在轮流显示的过程中,每一位数码管的点亮时间为1~2ms,由于人的视觉暂留现象及发光二极管的余晖效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一个稳定的显示资料,不会有闪烁感,动态显示的效果和静态显示是一样的,能够节省大量的I/O口,而且功耗降低。

数码管的消隐:

单片机学习9——数码管动态显示_第2张图片

延迟函数的测试:

单片机学习9——数码管动态显示_第3张图片

3位数码管显示秒数。从0到999。

#include

#define uchar unsigned char
#define uint unsigned int

sbit dula=P0^6;
sbit wela=P0^7;

uchar num, duan_num, wei_num;
uint disnum;

uchar code table_duan[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,
0x7d,0x07,0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};

uchar code table_wei[]={
0xfe,0xfc,0xfb,0xf7,0xef,0xdf};

void display(uint);
void delay(uchar);

void main()
{
	//delay(10);
    //打开定时器中断
	EA=1;
	ET0=1;
	//设置定时器工作模式
	TMOD=0x01;
	//十六位定时器,就使用65536,装初值
	TH0=(65536-50000)/256;
	TL0=(65536-50000)%256;
	//启动定时器,有几种启动方式
	TR0=1;

	while(1)
	{
		if(num==20)	  //是否到了1s
		{
		 	num=0;
			if(disnum==1000)
			{
			 	disnum=0;
			}
			disnum++;	
		}
		display(disnum);	
	}
}

//中断函数不需要声明和调用
void time0() interrupt 1
{
	TH0=(65536-50000)/256;
	TL0=(65536-50000)%256;
	num++;	
}

void display(uint disnum)
{
	P0=table_duan[disnum/100];
	dula=1;
	dula=0;
	P0=table_wei[0];
	wela=1;
	wela=0;
	delay(10);

	P0=table_duan[disnum%100/10];
	dula=1;
	dula=0;
	P0=table_wei[1];
	wela=1;
	wela=0;
	delay(10);

	P0=table_duan[disnum%100%10];
	dula=1;
	dula=0;
	P0=table_wei[2];
	wela=1;
	wela=0;
	delay(10);
}

void delay(uchar x)
{
	uchar a, b;
	for(a=x;a>0;a--)
	{
	 	for(b=200;b>0;b--);
	}	
}

 delay(),这个函数的功能是数码管的间接延时。1个数码管点亮保持一段时间,然后点亮第二个数码管,再延迟保持一段时间,然后再点亮第三个数码管。这样反复运行。

disnum其实应该使用sec更加合适。

delay这个时间不要太长。正常要控制在10ms之内。

单片机学习9——数码管动态显示_第4张图片

你可能感兴趣的:(单片机,单片机)