⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dzb.c

📁 这是我看了《十天学会单片机》(郭天祥的教程)第十课时写的
💻 C
字号:
/*
这是我看了《十天学会单片机》(郭天祥的教程)第十课时写的,综合了矩阵键盘,串口通信,数码管
动态显示,定时器中断的简单时钟程序。用51电子网买的298元80C51单片机学习板
(http://www.51dz.com/n.asp?id=12519&i=xie343706382)测试时请将p1口用排线连到CZ2上,控制8位
数码管用。P0口用来检测矩阵键盘的,P3.0和P3.1是串口通信用,控制74H164N芯片段选8位数码管。
数码管显示内容为时分秒个两位,按下K16为设置按钮,按一下调节秒数,再按一下调节分钟,再按一
下调节小时。再按下退出,走时。调节时按K1至K10分别代表0到9。
我的QQ343706382,希望有喜欢单片机的朋友。和我联系。


*/

#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char//宏定义字符型
#define uint unsigned int//宏定义长整型
uchar temp,num,keyzhi;//定义两个变量
							//keyzhi,是键盘返回值用来判断按下什么键子了temp和num也是键盘扫描用的临时变量
uchar code table[]={//定义字串数组数码管显示用分别是 0123456789_和全灭,这个数码管是共阳极的
0x12,0xfa,0x1c,0x98,
0xf0,0x91,0x11,0xda,
0x10,0x90,0xbf,0xff};

uchar code table2[]={//字串数组 数码管段位用,通74HC164N芯片控制8个数码管,的段显示
0x80,0x40,0x20,0x10,
0x08,0x04,0x02,0x01};


uint count,gnj,wz;//count,用来计算时间,count++18次是一秒。
							 //gnj,功能键值gnj值为1,设置秒数,为2,设置分钟,为3设置小时。
						
char nian,yue,tian,shi,fen,miao,xingqi;//分别代表年月日时分秒星期。
							
						//变量定义结束


void delay()//延时函数,很短的延时
{ ;; }

void delay1(uint x)//延时函数
{
	uint a,b;
	for(a=x;a>0;a--)for(b=110;b>0;b--);
}

void xianshi(uchar s,uchar f,uchar m)//显示函数,显示格式为,小时,分钟,秒
{
	uint ssw,sgw,fsw,fgw,msw,mgw;//分别代表小时,分钟,秒钟的十位和个位
	if(m>59)//如果秒数大于59,就显示光标 点闪烁
	{
		if(wz==1)
		{
      	msw=10;
 	   	mgw=miao%10;
		}
		else
		{
		 	msw=miao/10;
		 	mgw=10;
      } 
	}
	else
	{
		msw=m/10;
		mgw=m%10;
	}
	
	if(f>59)
	{
		if(wz==1)
		{
      	fsw=10;
 	   	fgw=fen%10;
		}
		else
		{
		 	fsw=fen/10;
		 	fgw=10;
		}
	}
	else
	{
		fsw=f/10;
		fgw=f%10;
	}
	
	if(s>24)
	{
		if(wz==1)
		{
      	ssw=10;
 	   	sgw=shi%10;
		}
		else
		{
		 	ssw=shi/10;
		 	sgw=10;
		}
	}
	else
	{
		ssw=s/10;
		sgw=s%10;
	}
	REN=1;//打开74H164N芯片写入口
	SBUF=table2[0];//发送数据,数码管第一位亮
	delay();
	P1=table[ssw];//显示小时的十位
	delay1(3);
	P1=0xff;      //消除数码管光影。
	SBUF=table2[1];
	delay();
	P1=table[sgw];//小时的个位
	delay1(3);
	P1=0xff;
	
	SBUF=table2[2];
	delay();
	P1=table[fsw];
	delay1(3);
	P1=0xff;
	SBUF=table2[3];
	delay();
	P1=table[fgw];
	delay1(3);
	P1=0xff;
	
	SBUF=table2[4];
	delay();
	P1=table[msw];
	delay1(3);
	P1=0xff;
	SBUF=table2[5];
	delay();
	P1=table[mgw];
	delay1(3);
	P1=0xff;
	
/*	SBUF=table2[6];//调试时用的,
	delay();
	P1=table[gnj];//显示功能键的值
	delay1(3);
	P1=0xff;
	SBUF=table2[7];
	delay();
	P1=table[keyzhi];//显示按键的值
	delay1(3);
	P1=0xff;
*/	
	REN=0;
}






uchar keyscan() //键盘扫描程序 利用P0口的4×4的矩阵键盘。
{
	P0=0xfe;
	temp=P0;
	num=0;
	if (temp!=0xfe)
	{
		delay1(5);
		temp=P0;
		if (temp!=0xfe)
		{
		     switch(temp)
						{
							case 0xee:num=16;
								break;
							case 0xde:num=12;
								break;
							case 0xbe:num=8;
								break;
							case 0x7e:num=4;
								break;
						}

						
		}
		while(temp!=0xfe){temp=P0;}

	}

	if (num==16)//判断是否要调整时间
	{
		gnj++;
		if(gnj==4)gnj=0;
		num=0;
		TR0=0;//关定时器
	}
	P0=0xfd;
	temp=P0;
	if (temp!=0xfd)
	{
		delay1(5);
		temp=P0;
		if (temp!=0xfd)
		{
		     switch(temp)
						{
							case 0xed:num=15;
								break;
							case 0xdd:num=11;
								break;
							case 0xbd:num=7;
								break;
							case 0x7d:num=3;
								break;
						}
		}
		while(temp!=0xfd){temp=P0;}

	}	

	P0=0xfb;
	temp=P0;
	if (temp!=0xfb)
	{
		delay1(5);
		temp=P0;
		if (temp!=0xfb)
		{
		     switch(temp)
						{
							case 0xeb:num=14;
								break;
							case 0xdb:num=10;
								break;
							case 0xbb:num=6;
								break;
							case 0x7b:num=2;
								break;
						}
		}
		while(temp!=0xfb){temp=P0;}

	}

	P0=0xf7;
	temp=P0;
	if (temp!=0xf7)
	{
		delay1(5);
		temp=P0;
		if (temp!=0xf7)
		{
		     switch(temp)
						{
							case 0xe7:num=13;
								break;
							case 0xd7:num=9;
								break;
							case 0xb7:num=5;
								break;
							case 0x77:num=1;
								break;
						}
		}
		while(temp!=0xf7){temp=P0;}

	}

P0=0xff;
return num;

}//键盘扫描程序over




void init()//初始化函数
{
	nian=2009;
	yue=1;
	tian=14;
	xingqi=3;
	shi=23;//小时
	fen=59;//分钟
	miao=58;//秒钟
	

	TMOD=0x01;//设置定时器工作模式
	TH0=(65536-51000)/256;//装初值让它5毫秒中断一次count++
	TL0=(65536-51000)%256;
	EA=1;//打开总中断
	ET0=1;//开定时器中断
	TR0=1;//开定时器
}

int runnian(int nian)//计算闰年函数
{
	if((nian%400==0) || (nian%100!=0) && (nian%4==0))
	{
		return 1;
 	}
	else
	{
		return 0; 
   }
}

int suanxingqi(int y,int m,int d)//计算星期函数
{
	int w;
	if(m<2)m=m+12;
	w= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7;
	return w;
}

void main()//主函数
{
	uint san;//这个变量是用来显示闪烁效果的
	init();//初始化
   wz=1;
	while(1)//进入大循环
	{
		if(gnj!=0)//判断设置键
		{
			wz=1;
			while(gnj==1)//功能键=1时设置秒钟
			{
				
			   if(san<30)//闪烁显示秒
				{
					xianshi(shi,fen,miao);
				}
				if(san>40)
				{
					xianshi(shi,fen,70);//让显示函数,在秒的位置显示点
				}
		
	         san++;
				if(san>60)
				{
					san=0;
	         }
				keyzhi=keyscan();//调用键盘
				
				if((keyzhi!=0)&&(keyzhi<11))//判断键盘在1到10之间
				{
					
					if(wz==1)//wz用来控制设置的是十位还是个位
					{
						miao=(keyzhi-1)*10;//设置秒十位
						if(miao>59)miao=50;
						keyzhi=0;
						
					}
					if(wz==2)
					{
						miao=miao+keyzhi-1;//设置个位
						keyzhi=0;
						wz=0;
						gnj++;
						
					}
					wz++;
				 }
				
			}
				wz=1;
 			while(gnj==2)//设置分钟
			{
				
			   if(san<20)
				{
					xianshi(shi,fen,miao);
				}
				if(san>40)
				{
					xianshi(shi,70,miao);
				}
		
	         san++;
				if(san>60)
				{
					san=0;
	         }
				keyzhi=keyscan();
				
				if((keyzhi!=0)&&(keyzhi<11))
				{
					
					if(wz==1)
					{
						fen=(keyzhi-1)*10;
						if(fen>59)fen=50;
						keyzhi=0;
						
					}
					if(wz==2)
					{
						fen=fen+keyzhi-1;
						keyzhi=0;
						wz=0;
						gnj++;
						
					}
					wz++;
				 }
				
			 }	
         wz=1;
			while(gnj==3)//设置小时
			{
				
			   if(san<20)
				{
					xianshi(shi,fen,miao);
				}
				if(san>40)
				{
					xianshi(70,fen,miao);
				}
		
	         san++;
				if(san>60)
				{
					san=0;
	         }
				keyzhi=keyscan();
				
				if((keyzhi!=0)&&(keyzhi<11))
				{
					
					if(wz==1)
					{
						shi=(keyzhi-1)*10;
						if(shi>20)shi=20;
						keyzhi=0;
						
					}
					if(wz==2)
					{
						shi=shi+keyzhi-1;
						if(shi>23)shi=23;
						keyzhi=0;
						wz=0;
						gnj=0;

					}
					wz++;
				 }
				
			 }
	
		}
		else
		{
			TR0=1;//打开定时器
		}
		keyzhi=keyscan();//扫描键盘
		xianshi(shi,fen,miao);//显示时分秒
	}

}

void timer0() interrupt 1//定时器函数
{
	TH0=(65536-51189)/256;
	TL0=(65536-51190)%256;
	count++;
	if(count==18)//加到18正好1秒中
	{
			
		count=0;

		
		miao++;//秒加一
		if(miao==60)//60秒加一分
		{
			miao=0;
			fen++;
			if(fen==60)//60分加一小时
			{
				fen=0;
				shi++;
				if(shi==24)//到24小时加以天
				{
					shi=0;
					tian++;
					if((tian==28)&&runnain(nian)&&(yue==2))
					{
						tian=1;
						yue++;
					}
					if((tian==29)&&(yue==2))
					{
						tian=1;
						yue++
					}
					if(tan==30)
					{
						if((yue==4)||(yue==6)||(yue==9)||(yue==11))
						{
							tian=1;
							yue++;
						}
					}
					if(tian==31)
					{
						tian=1;
						yue++;
						if(yue==13)
						{
							yue=1;
							nian++;

						}
	      		}

				}
			}
		}
	}	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -