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

📄 clk.c

📁 基于51单片机的多功能数字钟。时间
💻 C
字号:
#include<reg51.h>

#define	IIC_WRITE	0xa0					//24C04 EEPROM 写命令和读命令
#define	IIC_READ	0xa1

sbit  P10=P1^0;
sbit  P11=P1^1;
sbit  P12=P1^2;
sbit  P13=P1^3;
sbit  P14=P1^4;
sbit  P15=P1^5;

sbit	SCL=P1^6;
sbit	SDA=P1^7;

sbit  key0=P0^0;
sbit  key1=P0^1;
sbit  key2=P0^2;
sbit  key3=P0^3;
sbit  key4=P0^4;

unsigned char led_mask=0xff,mask_temp,led_num=0;
  //led_mask 用低六位作led标志位//led_num 闪烁间隔的中断次数       
unsigned char 	key0_mark=0,key1_mark=0,key2_mark=0,key3_mark=0;   		//每个按键的标识
unsigned int	key0_count=0,key1_count=0,key2_count=0,key3_count=0;	//每键按下 间隔的中断数
unsigned int	temp_count0=0,music_count=0;

bit  ph=1,flash=0,clk_begin=0,clk_off=0,agenda_begin=0;
bit	wr_mark=0,clk_save=0;

unsigned char error=0;

unsigned int  n=0;
unsigned char sec=0,min=0,h=0,year=06,mon=05,day=24;
unsigned char idata led=0,led_buf[6],buf[6];												
unsigned char idata	clk1_h=12,clk1_m=00,clk1_num=1,clk1_music=1,		//闹钟和议程
				clk2_h=24,clk2_m=30,clk2_num=2,clk2_music=2,
				agenda_year=06,agenda_mon=01,agenda_day=0,agenda_h=8,agenda_num=3;
unsigned char	music=0;

code unsigned char led_map[]={0x3F,0x06,0x5B,0x4F,0x66,
   0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x76,0x73 };
code unsigned char mon_day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};   //闰年与非闰年
code unsigned char mon_day1[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
//延时,主要用于IIC程序
void delay(unsigned int n)
{
	unsigned int i;
	for (i=n;i>0;i--) {}
}
 
time0() interrupt 1	   using 0
{                                           //T0计时器中断程序    //对时分秒针计数
	n++;
	if(n>=5002)								//5000次为1秒,5002为矫误差
    {	
   		sec++;
    	n=0;
	}
    if(sec>=60)
    {
	 	min++;
       	sec=0;
		clk_begin=0;						//闹铃最长1 分钟
		clk_off=0;
		wr_mark=1;
	}

    if(min>=60)
    {
		h++;
        min=0;
		agenda_begin=0;       //隔一小时查agenda;
	}
    if(h>=24)
    {
   		h=0;
        day++;
		if(year%4==0)
		{
			if(day>mon_day1[mon])	
			{
				day=1;
				mon++;
				if(mon>12)
				{
					mon=1;
					year++;
				}
			}
		}
		else if (day>mon_day[mon])
		{
			day=1;
			mon++;
			if(mon>12)	
			{
				mon=1;
				year++;
    		}   
		}  
    }   
}

t1display() interrupt 3   using 1				  //显示数码管
{											   
	 
    TH1=0xf0;										// 1/24显示  4ms中断
    TL1=0X5f;

	if((key3==0)&&(key0_mark!=0)&&(key0_mark!=1))
	{
		P2=led_buf[led]|0x80;
	}
	else	P2=led_buf[led]; 
	led_num++;

	switch (led)
	{
	case 0:
			P15=0;
			P10=1;
		break;
	case 1:
			P10=0;
    	    P11=1;
		break;
	case 2:
			P11=0;
 	        P12=1;
		break;
	case 3:
			P12=0;
            P13=1;
		break;
    case 4:
			P13=0;
            P14=1;
		break;
    case 5:
			P14=0;
            P15=1;
		break;
	default:
	    break;
	}
	

	if(led_num<=125&&flash)   					//闪烁once each 1s 
		P1=P1&led_mask;		
	if(led_num>125)	
	{
		led_num=0; 
		flash=~flash;
	}											
//-----------------------------------查询闹钟
	if(clk1_h==h&&clk1_m==min&&clk_off==0)	
		clk_begin=1;

	if(clk2_h==h&&clk2_m==min&&clk_off==0)
		clk_begin=1;	

	if(agenda_year==year&&agenda_mon==mon&&agenda_day==day&&agenda_h==h&&agenda_begin==0&&clk_off==0)	//隔一个小时再查
	{
		agenda_begin=1;
		clk_begin=1;
	}
	
	if(clk_begin&&clk_off==0)
	{
		music_count++;
		if(clk1_h==h&&clk1_m==min)	music=clk1_music;

		else if(clk2_h==h&&clk2_m==min)	music=clk2_music;
		else music=3;

		switch (music)
		{
			case 1:
				if(music_count%5==0)	
				{
					ph=~ph;
					music_count=0;
				}
				break;
			case 2:
				if(music_count%50==0)	
				{
					ph=~ph;
					music_count=0;
				}
				break; 
			case 3:
				ph=~ph;
				break;
			default:
				ph=1;
				break;				
		}
	}
	key4=ph;									 //clock
//------------------------------------------------------
	led++;										//led 片选清零
	if(led>=6)	 led=0;	 


	if(key0==1)	key0_count=0;					 //对延时计数清零
	if(key1==1)	key1_count=0;
	if(key2==1)	key2_count=0;
	if(key3==1)	key3_count=0;
	
	if(key3==0)
	{
		key3_count++;
		if(key3_count==20)
		{
			if(clk_off==0)	clk_off=1;
			if((key0_mark!=0)&&(key0_mark!=1))	clk_save=1;
		}
	}
	if(key0==0)	
	{	
		key0_count++;
		if(key0_count==20)	key0_mark+=1;
		if(key0_mark==6)	key0_mark=0;	
	}

	if(key1==0)
	{	
		key1_count++;													  //agenda 只闪烁 1,2;
		if(key1_count==20)	key1_mark+=1;								  //clk 只闪烁1,2,4

		if ((key0_mark==4||key0_mark==5)&&key1_mark==3)		key1_mark=0;
		if ((key0_mark==2||key0_mark==3)&&key1_mark==3)		key1_mark=4;
			
		if ((key0_mark==0||key0_mark==1||key0_mark==4||key0_mark==5)&&key1_mark==4)		key1_mark=0;
		if(key1_mark==5)	key1_mark=0;	
	}
		if ((key0_mark==4||key0_mark==5)&&key1_mark==4)	key1_mark=0;	//除bug agenda 闪4
//调整加一或连加
	if(key2==0)
	{
		key2_count++;
		if(((key2_count==20)||((key2_count>=450)&&(key2_count%150==0)))&&(key0_mark==0))
		{

			switch (key1_mark)
			{
				case 1:
						sec=0;
						break;
				case 2:
						{min++;
						if(min>=60)	min=0; }
						break;
				case 3:
						{h++;
						if(h>=24)	h=0; }
						break;
				default:
						break;
								
			}
		}
		 
		if(((key2_count==20)||((key2_count>=450)&&(key2_count%150==0)))&&(key0_mark==1))
		{
			switch (key1_mark)
			{
				case 1:
						day++;
						if(year%4==0)
						{
							if(day>mon_day1[mon])	day=1;
						}
						else if (day>mon_day[mon])	day=1;
						break;
				case 2:
						mon++;
						if(mon>12)	mon=1;
						break;
				case 3:
						year++;
						break;
				default:
						break;
								
			}
			if(key2_count>=450)	year=06;
		}

		if(((key2_count==20)||((key2_count>=450)&&(key2_count%150==0)))&&(key0_mark==2))
		{

			switch (key1_mark)
			{
				case 1:
						clk1_m++;
						if(clk1_m>=60)	clk1_m=0;	
						break;
				case 2:
						clk1_h++;
						if(clk1_h>=24)	clk1_h=0; 
						break;
				case 4:
						clk1_music++;
						if(clk1_music>=3)	clk1_music=0; 
						break;
				default:
						break;
								
			}
		}

		if(((key2_count==20)||((key2_count>=450)&&(key2_count%150==0)))&&(key0_mark==3))
		{

			switch (key1_mark)
			{
				case 1:
						clk2_m++;
						if(clk2_m>=60)	clk2_m=0;	
						break;
				case 2:
						clk2_h++;
						if(clk2_h>=24)	clk2_h=0; 
						break;
				case 4:
						clk2_music++;
						if(clk2_music>=3)	clk2_music=0; 
						break;
				default:
						break;
								
			}
		}

		if(((key2_count==20)||((key2_count>=500)&&(key2_count%125==0)))&&(key0_mark==4))
		{
													//agenda 不调整music
			switch (key1_mark)
			{

				case 1:
						agenda_mon++;
						if(agenda_mon>12)	agenda_mon=1; 
						break;
				case 2:
						agenda_year++;	
						if((key2_count>=450)&&(key2_count%150==0))	agenda_year=06;
						break;
				default:
						break;
								
			}
		}

		if(((key2_count==20)||((key2_count>=500)&&(key2_count%125==0)))&&(key0_mark==5))
		{
													//agenda 不调整music
			switch (key1_mark)
			{

				case 1:
						agenda_h++;
						if(agenda_h>=24)	agenda_h=0; 
						break;
				case 2:
						agenda_day++;
						if(agenda_year%4==0)	
						{
							if(agenda_day>mon_day1[agenda_mon])	agenda_day=1;							
						}
						else if	(agenda_day>mon_day[agenda_mon])	agenda_day=1;	
						break;
				default:
						break;
								
			}
		}
	}

	if(((key0==0)||(key1==0)||(key2==0)||(key3==0))==1)	temp_count0=0;	//只要有键按下,则不启动回复
	if(((key0==1)&&(key1==1)&&(key2==1)&&(key3==1))==1)	temp_count0++;	//没有键按下,则启动回复
	if(temp_count0>=2500)
	{							           //10s  以后回到显示时间
		temp_count0=0;
		key0_mark=0;
		key1_mark=0;
		key2_mark=0;
		key3_mark=0;

	}
}
//------------------------------------------------------------------------------

void start()
{
	SDA=1;
	SCL=1;
	delay(2);
	SDA=0;
	delay(2);
	SCL=0;
}

void stop()
{
	SDA=0;
	SCL=1;
	delay(1);
	SDA=1;
	delay(2);
	SDA=0;
}
unsigned char	outbyte(unsigned char value)	 //MCU 输出一个字节到2404
{
	unsigned char	i;
	unsigned char	ack=0;
	for(i=0x80;i>0;i>>=1)
	{
		if(i&value)
		{
		SDA=1;	
		SCL=1;
		delay(2);
		SCL=0;
		//SDA=0;
		}	  //********
		else	
		{
			SDA=0;
			SCL=1;
			delay(2);
			SCL=0;
		}

	}
	SDA=1;
	SCL=1;
	delay(2);
	ack=SDA;
	SCL=0;
	delay(1);

	return	ack;
}

unsigned char inbyte(unsigned char ack)		  //2404输入一个字节到MCU

{
	unsigned char i,val=0;
	SDA=1;
	for (i=0x80;i>0;i>>=1)
	{
		SCL=1;
		if(SDA==1)	val=val|i;
		delay(1);
		SCL=0;
	}

	if(!ack)	//mack();
	{	
		SCL=0;
		SDA=0;		  //MCU 把SDA拉低
		SCL=1;
		delay(2);
		SCL=0;
	}
	else	//muack();
	{
		SCL=0;
		SDA=1;
		SCL=1;
		delay(2);
		SCL=0;
	}

	return	val;

}

//连写函数
//add为读起始地址,ptr数据保存指针,writelen为写入数据长度
unsigned char writebyteseq(unsigned int add,unsigned char *ptr,unsigned int writelen)
{
 	unsigned char ack=0;
 	unsigned char templ;
 	unsigned int i;
 	templ=(unsigned char)(add%256);

 	start();   
 	ack+=outbyte(IIC_WRITE);   
 	ack+=outbyte(templ);

	for(i=0;i<writelen;i++)
 	{
  		ack+=outbyte(*(ptr+i));
  		delay(10);
  	}
   	error=ack;
 	stop();

    return ack; 
}
void readbyteseq(unsigned int add,unsigned char *ptr,unsigned int readlen )
{
	unsigned char ack=0;
 	unsigned char temph,templ;
 	unsigned int i;

 	temph=(unsigned char)(add/256);
 	templ=(unsigned char)(add%256);

    for (i=0;i<readlen;i++)
	{
 		start();   
 		ack+=outbyte(IIC_WRITE);   
 		ack+=outbyte(templ+i);

 		start();   
 		ack+=outbyte(IIC_READ);	

		*(ptr+i)=inbyte(1);	

		stop();
	}	 
}
//------------------------------------------------------------------------------                                                  
main()  													                                                         
{
	unsigned char idata  time_date[5],time_temp[5],clk_data[10],clk_temp[10]; 
	unsigned char ack=0;
    TMOD=0x12;
    TH0=0x38;
    TL0=0x38;
    TH1=0xf0;
    TL1=0X5f;
   // IE=0X8A;
    IP=0x02;
    EA=1;
    ET0=1;
    ET1=1;
    TR0=1;
    TR1=1;

	readbyteseq(0x10,time_temp,5);										//从EEPBROM读出已存的时间日期
	delay(40);	
	min=time_temp[0];
	h=time_temp[1];
	day=time_temp[2];
	mon=time_temp[3];
	year=time_temp[4]; 


	readbyteseq(0x40,clk_data,10);										//从EEPBROM读出已存的闹钟设置
	delay(40);	
	clk1_music=clk_data[0];
	clk1_m=clk_data[1];
	clk1_h=clk_data[2];

	clk2_music=clk_data[3];
	clk2_m=clk_data[4];
	clk2_h=clk_data[5];
    
	agenda_year=clk_data[6];
	agenda_mon=clk_data[7];
	agenda_day=clk_data[8];
	agenda_h=clk_data[9];
		                             
	while(1)
  	{
		if((min+1)%5==0&&wr_mark==1)									//每隔一段时间就存时间		
		{
			time_date[0]=min;
			time_date[1]=h;
			time_date[2]=day;
			time_date[3]=mon;
			time_date[4]=year;

			ack=writebyteseq(0x10,time_date,5);
			delay(40);
			
			wr_mark=0;
		}

		if(clk_save==1)													//按key3之后若无闹铃响则存闹铃设置
		{
			clk_temp[0]=clk1_music;
			clk_temp[1]=clk1_m;
			clk_temp[2]=clk1_h;

			clk_temp[3]=clk2_music;
			clk_temp[4]=clk2_m;
			clk_temp[5]=clk2_h;
			
			clk_temp[6]=agenda_year;
			clk_temp[7]=agenda_mon;
			clk_temp[8]=agenda_day;
			clk_temp[9]=agenda_h;

			ack=writebyteseq(0x40,clk_temp,10);
			delay(40);
			
			clk_save=0;
		}
	   
		//---------------------------------------------------------------------
		if(key0_mark==0)
		{														  //将时间值赋给数码管
		
		
			buf[0]=h/10;										
			buf[1]=h%10;
			buf[2]=min/10;
			buf[3]=min%10;
			buf[4]=sec/10;
			buf[5]=sec%10;

		}
		if(key0_mark==1)										//将日期值赋给数码管
		{
			buf[0]=year/10;										
			buf[1]=year%10;
			buf[2]=mon/10;
			buf[3]=mon%10;
			buf[4]=day/10;
			buf[5]=day%10;     									  
		}
		if(key0_mark==2)			   						//将第一组闹钟值赋给数码管
		{
			buf[0]=clk1_num;										
			buf[1]=clk1_music;
			buf[2]=clk1_h/10;
			buf[3]=clk1_h%10;
			buf[4]=clk1_m/10;
			buf[5]=clk1_m%10; 			  
		}
		if(key0_mark==3)								//将第二组闹钟值赋给数码管
		{
			buf[0]=clk2_num;										
			buf[1]=clk2_music;
			buf[2]=clk2_h/10;
			buf[3]=clk2_h%10;
			buf[4]=clk2_m/10;
			buf[5]=clk2_m%10; 
		}
		if(key0_mark==4)
		{
			buf[0]=agenda_num;										
			buf[1]=3;
			buf[2]=agenda_year/10;
			buf[3]=agenda_year%10;
			buf[4]=agenda_mon/10;
			buf[5]=agenda_mon%10; 
		}
		if(key0_mark==5)
		{
			buf[0]=agenda_num+1;										
			buf[1]=3;
			buf[2]=agenda_day/10;
			buf[3]=agenda_day%10;
			buf[4]=agenda_h/10;
			buf[5]=agenda_h%10; 
		}

//------------------------------------------------------------------
		
		if(key1_mark==1)	led_mask=0xcf;                    //选择闪烁数码管         
		if(key1_mark==2)	led_mask=0xf3;
		if(key1_mark==3)	led_mask=0xfc;
		if(key1_mark==4)	led_mask=0xfd;
		if(key1_mark==0)	led_mask=0xff; 	
		
//-----------------------------------------调整在中断子程序,判断在主函数

	if(key0_mark==1)
	{
		if(year%4==0)					  ///4月31日!!
		{
			if(day>mon_day1[mon])	day=mon_day1[mon];
		}
		else if (day>mon_day[mon])	day=mon_day[mon];
	}
	if((key0_mark==4)||(key0_mark==5))
	{
		if(agenda_year%4==0)					  ///4月31日!!
		{
			if(agenda_day>mon_day1[agenda_mon])	agenda_day=mon_day1[agenda_mon];
		}
		else if (agenda_day>mon_day[agenda_mon])	agenda_day=mon_day[agenda_mon];
	}
//------------------------------------------------------------------		

		led_buf[0]=led_map[buf[0]];				                  //将显示值赋给数码管
  		led_buf[1]=led_map[buf[1]];
  		led_buf[2]=led_map[buf[2]];
  		led_buf[3]=led_map[buf[3]];
  		led_buf[4]=led_map[buf[4]];
  		led_buf[5]=led_map[buf[5]];			
	}
}

⌨️ 快捷键说明

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