使用keilC51和Protues的基于七段数码管的单片机仿真系统,以及怎么让单片机一秒一秒计时。(超级详细,每一步的步骤)

目录

一、Keil新建项目

1. 项目创建

 2. 用前调试

3. 软件部分代码

 4. 最后

二、Protues创建

1. 新建项目 

2.  硬件电路图

三、仿真结果 

四、几个小疑问

1. 怎么计1秒钟


一、Keil新建项目

1. 项目创建

打开keil

点击project

项目名称可以自己起,不用加后缀,路径放到自己找得到的地方。

搜索AT89C51------>点击OK

 

点击是

 

点击

 

新建.c文件(如果用c语言编程的话)

 

 2. 用前调试

点击(管它叫锤子)

我一般用12MHz

 

选OUTPUT,勾上,选OK

 

3. 软件部分代码

#include<reg51.h>
#define uChar unsigned char
#define uInt unsigned int
uChar a[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; 
uChar b[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; 
uChar second=50,minute=59,hour=16,year=22,month=12,day=25,count;
sbit Key1 = P3^0; //减一
sbit Key2 = P3^1; //调位
sbit Key3 = P3^2; //加一 
sbit Key4 = P3^3; //切换  
sbit Buzzer=P1^1;
/*********************延迟函数********************/
void Delay(uInt t)
{
	while(t)
	{
		t--;
	}
}
/*********************时分秒显示函数*******************/ 
void Dispaly1(uChar second,uChar minute,uChar hour)
{
	/*********************第一位数码管*********************/
	P2=b[0];
	P0=a[hour/10];
	Delay(10);
	/*********************第二位数码管*********************/
	P2=b[1];
	P0=a[hour%10];
	Delay(10);
	/*********************第三位数码管*********************/
	P2=b[2]; 
	P0=0x40; 
	Delay(10);
	/*********************第四位数码管*********************/
	P2=b[3]; 
	P0=a[minute/10]; 
	Delay(10);
	/*********************第五位数码管*********************/
	P2=b[4];
	P0=a[minute%10]; 
	Delay(10);
	/*********************第六位数码管*********************/
	P2=b[5]; 
	P0=0x40; 
	Delay(10);
	/*********************第七位数码管*********************/
	P2=b[6]; 
	P0=a[second/10]; 
	Delay(10);
	/*********************第八位数码管*********************/
	P2=b[7];; 
	P0=a[second%10]; 
	Delay(10);
}
/*********************年月日显示函数********************/
void Dispaly2(uChar year,uChar month,uChar day)
{

		P2=b[0]; 
		P0=a[year/10]; 
		Delay(10);

		P2=b[1]; 
		P0=a[year%10]; 
		Delay(10);

		P2=b[2]; 
		P0=0x40; 
		Delay(10);

		P2=b[3]; 
		P0=a[month/10]; 
		Delay(10);

		P2=b[4]; 
		P0=a[month%10]; 
		Delay(10);

		P2=b[5]; 
		P0=0x40; 
		Delay(10);
			
		P2=b[6];
		P0=a[day/10];
		Delay(10);

		P2=b[7];
		P0=a[day%10];
		Delay(10);
}
/*********************时钟按键扫描函数*********************/
void Keyscan1()
{
	static uChar i=0,j=0; 

	/*时钟数值加一减一功能*/
	
	if(Key2==0) 
	{
		Delay(10); 
		if(Key2==0)
		while(!Key2);
		i++;
		j++; 
	}
	
	// 加加
	if(j%4==1)
	{
		if(Key3==0)
		{
			Delay(10); 
			if(Key3==0)
			while(!Key3);
			second++;
			if(second==60)// 如果满60秒,分钟加一,秒钟清零,下边逻辑相同
			{
				second=00;
				minute++;
			}
		}
	}
	if(j%4==2)
	{	
		if(Key3==0)
		{
			Delay(10); 
			if(Key3==0)
			while(!Key3);
			minute++;
			if(minute==60)
			{
				minute=00;
				hour++;
			} 
		}
	}
	if(j%4==3)
	{
		if(Key3==0)
		{ 
			Delay(10); 
			if(Key3==0)
			while(!Key3);
			hour++;
			if(hour==24)
			{
				hour=00; 
				day++;
			}
		}
	}
	
	// 减减
	if(i%4==1)
	{
		if(Key1==0)
		{
			Delay(10); 
			if(Key1==0)
			while(!Key1);
			second--;
			if(second==0)
			{
				second=60;
				minute--;
			}
		}
	}
	if(i%4==2)
	{	
		if(Key1==0)
		{
			Delay(10); 
			if(Key1==0)
			while(!Key1);
			minute--;
			if(minute==0)
			{
				minute=0;
				hour--;
			}
		}
	}
	if(i%4==3)
	{
		if(Key1==0)
		{ 
			Delay(10); 
			if(Key1==0)
			while(!Key1);
			hour--;
			if(hour==0)
			{
				hour=0;
				day--;
			}
		}
	}	
}
/*日期按键扫描函数*/
void Keyscan2()
{
	static uChar n=0,m=0; 
	/*日期加一减一功能*/
	
	if(Key2==0) 
	{
		Delay(10); 
		if(Key2==0)
		while(!Key2);
		n++;
		m++; 
	}

	// 加加
	if(n%4==1)
	{
		if(Key3==0)
		{
			Delay(10); 
			if(Key3==0)
			while(!Key3);
			day++;
			if(day==30)
			{
				day=0;
				month++;
			}
		}
	}
	if(n%4==2)
	{
		if(Key3==0)
		{ 
			Delay(10); 
			if(Key3==0)
			while(!Key3);
			month++;
			if(month==12)
			{
				month=1;
				year++;
			}				
		}
	}
	if(n%4==3)
	{
		if(Key3==0)
		{ 
			Delay(10); 
			if(Key3==0)
			while(!Key3);
			year++;
			if(year==99)
			year=0; 
		}
	}
	
	// 减减
	if(m%4==1)
	{
		if(Key1==0)
		{
			Delay(10); 
			if(Key1==0)
			while(!Key1);
			day--;
			if(day==0)
			{
				day=30;
				month--;
			}
		}
	}
	if(m%4==2)
	{
		if(Key1==0)
		{ 
			Delay(10); 
			if(Key1==0)
			while(!Key1);
			month--;
			if(month==0)
			{
				month=12;
				year--;	
			}		
		}
	}
	if(m%4==3)
	{
		if(Key1==0)
		{ 
			Delay(10); 
			if(Key1==0)
			while(!Key1);
			year--;
			if(year==0)
			year=1; 
		}
	}
}


/***************主函数***************************/

void main()
{						
		TMOD=0x01; 	 /*定时器以方式一工作*/
		TH0=(65536-10000)/256;
		TL0=(65536-10000)%256;/*10ms计时*/
		EA=1;
		ET0=1;/*允许定时器0中断*/
		TR0=1;/*打开定时器0*/
		while(1)
		{
			static uChar h=0;
			/*时钟和日期切换功能*/ 
			if(Key4==0) 
			{
				Delay(10); 
				if(Key4==0)
				while(!Key4);
				h++;
			}
			if(h%2==0)/*如果按键偶数次则显示时钟*/
			{
				Dispaly1(second,minute,hour);
				Keyscan1(); 
			}

			if(h%2==1)/*如果按键奇数次则显示日期*/ 
			{
				Dispaly2(year,month,day);
				Keyscan2();
			}
		}
}
/**********************中断函数**************************/
void time0_int(void) interrupt 1
{
	TH0=(65536-10000)/256;
	TL0=(65536-10000)%256;
	count++;
	if(count==100)
	{
		count=0;
		second++;
		if(second==60)
		{
			second=0;
			minute++;
			if(minute==60)
			{
				minute=0;
				hour++;
				if(hour==24)
				{
					hour=0;
					day++;
					if(day==30)
					{
						day=0;
						month++;
						if(month==12)
						{
							month=0;
							year++;
							if(year==99)
							{
							year=0;
							}
						}
					}
				}
			}
		}
	}
	/*判断整点提醒*/
	if(second==00&&minute==00)								   
	Buzzer=1;
	else
	Buzzer=0;
}

 4. 最后

点击

二、Protues创建

1. 新建项目 

一路next到finish

2.  硬件电路图

三、仿真结果 

 双击单片机,找到.hex后缀的文件(在keil生成的Object文件夹下)

记得同样的晶振频率12MHz

点击确定

仿真结果

按键4控制日期、时间的切换,按键2负责选位,按键1 进行减操作,按键3进行加操作

 显示时间

显示日期

 

 调整时间

调整日期

 

四、几个小疑问

1. 怎么计1秒钟

TH0=(65536-10000)/256; 		
TL0=(65536-10000)%256;/*10ms计时*/

 定时器工作原理:

如果你选的单片机的晶振一定,比如12MHZ来说吧,机器周期是1us,就是说每1us产生一次计数,就拿50ms来说,这是你想要的计时,意思是,对机器周期进行50000计数就可以得到我想要的,可T0是一个可以对机器周期能进行65536次计数,也就是说我想要的50MS不能让T0溢出,怎么办,那么先给这个定时器里面放些数,放多少,就是我们想要的50MS在加上一个多少就能等于65536,也就是65536和50000的差值,这个值就是我们说的初值。

为什么除以256,因为我们的计时器是两个8位组成的,那么要把那些差值装进这两个8位,那么低8位最多能装256个机器周期,那么256计满了就用高8位的,就是说低8位满一次高8位加1,那么高8位装多少,低8位就满了几次,算法就是用差值除一下256取其整数,剩下的,就是还剩了小于256次数的就放在低8位,就是差值的余数。如果我要放一个超过256的数,肯定是超过先放高八位,把剩下的部分放在低八位中了,TH0=(65536-50000)/256就是把T0中放不下的部分放在TL0中,再把剩下的部分放在TH0中。

void timer(0) interrupt 1

TH0=(65536-10000)/256;

TL0=(65536-10000)%256;

flag++;

if(flag==20)//当定时到1秒时执行花括号里面的语句

{}

}

猜你喜欢

转载自blog.csdn.net/hjl011006/article/details/128505838