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

📄 time._c

📁 mega128做的ds12887的时钟
💻 _C
字号:
#ifndef _CPU
#define _CPU
#include <cpu.h>
#endif

#ifndef _GXM1286435
#define _GXM1286435
#include <gxm1286435.h>
#endif

#ifndef _KU
#define _KU
#include <ku.h>
#endif


unsigned char year,month,day,hour,minute,week,second,flag,key,bl_flag=0,set_flag=0;
signed char temperature;
unsigned char c_moon,year_moon,month_moon,day_moon;
#pragma data:code
const unsigned char day_code1[]={0x0,0x1f,0x3b,0x5a,0x78,0x97,0xb5,0xd4,0xf3};
const unsigned int day_code2[]={0x111,0x130,0x14e};
const unsigned char date[]={"年月日温度星期日一二三四五六"};
const unsigned char num[]={"0123456789:+-"};
#pragma data:data


unsigned char get_moon_day(unsigned char month_p,unsigned int table_addr)
{
unsigned char temp;
    switch(month_p)
	{
        case 1:{
		        temp=year_code[table_addr]&0x08;
                if(temp==0)
			    return(0);
			    else 
			    return(1);
				}
        case 2:{
		        temp=year_code[table_addr]&0x04;
                if(temp==0)
				return(0);
				else 
				return(1);
				}
        case 3:{
		        temp=year_code[table_addr]&0x02;
                if(temp==0)
				return(0);
				else 
				return(1);
				}
        case 4:{
		        temp=year_code[table_addr]&0x01;
                if(temp==0)
				return(0);
				else 
				return(1);
				}
        case 5:{
		        temp=year_code[table_addr+1]&0x80;
                if(temp==0) 
			    return(0);
			    else return(1);
			    }
        case 6:{
		        temp=year_code[table_addr+1]&0x40;
                if(temp==0)
				return(0);
				else return(1);
				}
        case 7:{
		        temp=year_code[table_addr+1]&0x20;
                if(temp==0)
				return(0);
				else 
				return(1);
				}
        case 8:{
		        temp=year_code[table_addr+1]&0x10;
                if(temp==0)
				return(0);
				else 
				return(1);
				}
        case 9:{
		        temp=year_code[table_addr+1]&0x08;
                if(temp==0)
				return(0);
				else 
				return(1);
				}
        case 10:{
		        temp=year_code[table_addr+1]&0x04;
                if(temp==0)
				return(0);
				else 
				return(1);
				}
        case 11:{
		        temp=year_code[table_addr+1]&0x02;
                if(temp==0)
				return(0);
				else 
				return(1);
				}
        case 12:{
		        temp=year_code[table_addr+1]&0x01;
                if(temp==0)
				return(0);
				else 
				return(1);
				}
        case 13:{
		        temp=year_code[table_addr+2]&0x80;
                if(temp==0)
				return(0);
				else
				return(1);
				}
    }
}


void Conversion(unsigned char c,unsigned char year1,unsigned char month1,unsigned char day1)
{ //c=0 为21世纪,c=1 为19世纪 输入输出数据均为BCD数据
    unsigned char temp1,temp2,temp3,month_p;
    unsigned int temp4,table_addr;
    unsigned char flag2,flag_y;
    /*temp1=year1/16;   //BCD->hex 先把数据转换为十六进制
    temp2=year1%16;
    year1=temp1*10+temp2;
    temp1=month1/16;
    temp2=month1%16;
    month1=temp1*10+temp2;
    temp1=day1/16;
    temp2=day1%16;
    day1=temp1*10+temp2;*/
    //定位数据表地址
    if(c==0)
	{                   
        table_addr=(year1+0x64-1)*0x3;
    }
    else 
	{
        table_addr=(year1-1)*0x3;
    }
    //定位数据表地址完成
    //取当年春节所在的公历月份
    temp1=year_code[table_addr+2]&0x60; 
    temp1=temp1>>5;
    //取当年春节所在的公历月份完成
    //取当年春节所在的公历日
    temp2=year_code[table_addr+2]&0x1f; 
    //取当年春节所在的公历日完成
    // 计算当年春年离当年元旦的天数,春节只会在公历1月或2月
    if(temp1==0x1){  
        temp3=temp2-1;  
    }  
    else{
        temp3=temp2+0x1f-1;        
    }
    // 计算当年春年离当年元旦的天数完成
    //计算公历日离当年元旦的天数,为了减少运算,用了两个表
    //day_code1[9],day_code2[3]
    //如果公历月在九月或前,天数会少于0xff,用表day_code1[9],
    //在九月后,天数大于0xff,用表day_code2[3]
    //如输入公历日为8月10日,则公历日离元旦天数为day_code1[8-1]+10-1
    //如输入公历日为11月10日,则公历日离元旦天数为day_code2[11-10]+10-1
    if (month1<10){ 
        temp4=day_code1[month1-1]+day1-1;
    }
    else{
        temp4=day_code2[month1-10]+day1-1;
    }
    if ((month1>0x2)&&(year1%0x4==0)){  //如果公历月大于2月并且该年的2月为闰月,天数加1
        temp4+=1;
    }
    //计算公历日离当年元旦的天数完成
    //判断公历日在春节前还是春节后
    if (temp4>=temp3){ //公历日在春节后或就是春节当日使用下面代码进行运算
        temp4-=temp3;
        month1=0x1;
        month_p=0x1;  //month_p为月份指向,公历日在春节前或就是春节当日month_p指向首月
        flag2=get_moon_day(month_p,table_addr); //检查该农历月为大小还是小月,大月返回1,小月返回0
        flag_y=0;
        if(flag2==0)temp1=0x1d; //小月29天
        else temp1=0x1e; //大小30天
        temp2=year_code[table_addr]&0xf0;
        temp2=temp2>>4;  //从数据表中取该年的闰月月份,如为0则该年无闰月
        while(temp4>=temp1){
            temp4-=temp1;
            month_p+=1;
            if(month1==temp2){
            flag_y=~flag_y;
            if(flag_y==0)month1+=1;
            }
            else month1+=1;
            flag2=get_moon_day(month_p,table_addr);
            if(flag2==0)temp1=0x1d;
            else temp1=0x1e;
        }
        day1=temp4+1;
    }
    else{  //公历日在春节前使用下面代码进行运算
        temp3-=temp4;
        if (year1==0x0){year1=0x63;c=1;}
        else year1-=1;
        table_addr-=0x3;
        month1=0xc;
        temp2=year_code[table_addr]&0xf0;
        temp2=temp2>>4;
        if (temp2==0)month_p=0xc; 
        else month_p=0xd; //
        /*
        month_p为月份指向,如果当年有闰月,一年有十三个月,月指向13,
无闰月指向12
        */
        flag_y=0;
        flag2=get_moon_day(month_p,table_addr);
        if(flag2==0)
		temp1=0x1d;
        else
		 temp1=0x1e;
        while(temp3>temp1)
		{
            temp3-=temp1;
            month_p-=1;
            if(flag_y==0)month1-=1;
            if(month1==temp2)flag_y=~flag_y;
            flag2=get_moon_day(month_p,table_addr);
            if(flag2==0)temp1=0x1d;
            else temp1=0x1e;
         }
        day1=temp1-temp3+1;
    }
    c_moon=c;                 //HEX->BCD ,运算结束后,把数据转换为BCD数据
/* temp1=year1/10;
    temp1=temp1<<4;
    temp2=year1%10;
    year_moon=temp1|temp2;
    temp1=month1/10;
    temp1=temp1<<4;
    temp2=month1%10;
    month_moon=temp1|temp2;
    temp1=day1/10;
    temp1=temp1<<4;
    temp2=day1%10;
    day_moon=temp1|temp2;*/
	year_moon=year1;
	month_moon=month1;
	day_moon=day1;
}

void wr_runyear()
{
Conversion(0,year,month,day);
wr_char(0x88,"农历");
switch(month_moon)
{
   case 1: wr_char(0x8a,"正月");break;
   case 2: wr_char(0x8a,"二月");break;	      
   case 3: wr_char(0x8a,"三月");break;
   case 4: wr_char(0x8a,"四月");break;
   case 5: wr_char(0x8a,"五月");break;
   case 6: wr_char(0x8a,"六月");break;
   case 7: wr_char(0x8a,"七月");break;
   case 8: wr_char(0x8a,"八月");break;
   case 9: wr_char(0x8a,"九月");break;
   case 10: wr_char(0x8a,"十月");break;
   case 11: wr_char(0x8a,"冬月");break;
   case 12: wr_char(0x8a,"腊月");break; 	

}
switch(day_moon)
{
   case 1: wr_char(0x8c,"初一");break;
   case 2: wr_char(0x8c,"初二");break;	      
   case 3: wr_char(0x8c,"初三");break;
   case 4: wr_char(0x8c,"初四");break;
   case 5: wr_char(0x8c,"初五");break;
   case 6: wr_char(0x8c,"初六");break;
   case 7: wr_char(0x8c,"初七");break;
   case 8: wr_char(0x8c,"初八");break;
   case 9: wr_char(0x8c,"初九");break;
   case 10: wr_char(0x8c,"初十");break;	
   case 11: wr_char(0x8c,"十一");break;	
   case 12: wr_char(0x8c,"十二");break;	
   case 13: wr_char(0x8c,"十三");break;	
   case 14: wr_char(0x8c,"十四");break;	
   case 15: wr_char(0x8c,"十五");break;	
   case 16: wr_char(0x8c,"十六");break;	
   case 17: wr_char(0x8c,"十七");break;	
   case 18: wr_char(0x8c,"十八");break;	
   case 19: wr_char(0x8c,"十九");break;	
   case 20: wr_char(0x8c,"二十");break;	
   case 21: wr_char(0x8c,"廿一");break;	
   case 22: wr_char(0x8c,"廿二");break;		
   case 23: wr_char(0x8c,"廿三");break;		
   case 24: wr_char(0x8c,"廿四");break;		
   case 25: wr_char(0x8c,"廿五");break;		
   case 26: wr_char(0x8c,"廿六");break;		
   case 27: wr_char(0x8c,"廿七");break;		
   case 28: wr_char(0x8c,"廿八");break;		
   case 29: wr_char(0x8c,"廿九");break;		
   case 30: wr_char(0x8c,"三十");break;			

}

}

void bl_con()
{
if(bl_flag)
{
bl_on;
bl_flag=0;
}
else
{
bl_flag=1;
bl_off;
}
delay(2100);
}
void delay_1ms()
{
 unsigned int i;
for(i=1;i<(8*143-2);i++) //8为晶振频率
;
}
void delay_nms(unsigned int n)
{
unsigned int i;
for(i=0;i<n;i++)
delay_1ms();
}


unsigned int star_ad()
{
unsigned int i;
unsigned char j;
ADCSRA|=1<<ADSC;//启动adc
do
{
j=ADCSRA;
j&=0x10;
}while(j==0); 
i=ADC&0x03ff;
return(i);
}

signed char tem_rd(unsigned int x)
{
unsigned int l;
signed char k;
float j;
j=(float)x*30/(1023-(float)x);
l=sizeof(adlist)/sizeof(adlist[0]);
if(j>adlist[0]||j<adlist[l])
return(0xff);
else
{
for(k=0;k<l;k++)
{
if(j>adlist[k])
break;
}
if((adlist[k-1]-j)>=(j-adlist[k]))
;
else
k--;
k=k-20;
return(k);
}
}

void ds12887_int()  //DS12887初始化
{
unsigned char i;
do
{
i=ds_ra;
i&=0x80;
          }while(i);
ds_ra=0b10100000;
ds_rb=0b00100110;
ds_rc=0b00000000;
ds_second_alarm=0xff;
ds_minute_alarm=0xff;
ds_hour_alarm=0xff;
}

void ds12887_rd()  //ds12887读
{
unsigned char i;
do
{
i=ds_ra;
i&=0x80;
}while(i);

   year=ds_year;

   month=ds_month;

   day=ds_day;

   hour=ds_hour;

   minute=ds_minute;

   week=ds_week;


}

void ds12887_wr()   //ds12887写
{
unsigned char i;
do
{
i=ds_ra;
i&=0x80;
}while(i);
  ds_year=year;
  ds_month=month;
  ds_day=day;
  ds_hour=hour;
  ds_minute= minute;
  ds_week=week;
}


void wr_date()  //更改显示内容
{

wr_comm(0x80);
wr_data(num[2]);
wr_data(num[0]);
wr_data(num[year/10]);
wr_data(num[year%10]);
wr_data(date[0]);
wr_data(date[1]);
wr_data(num[month/10]);
wr_data(num[month%10]);
wr_data(date[2]);
wr_data(date[3]);
wr_data(num[day/10]);
wr_data(num[day%10]);
wr_data(date[4]);
wr_data(date[5]);
wr_comm(0x90);
wr_data(date[10]);
wr_data(date[11]);
wr_data(date[12]);
wr_data(date[13]);
wr_data(date[13+2*week-1]);
wr_data(date[13+2*week]);
}
void wr_time()
{
wr_comm(0x94);
wr_data(num[hour/10]);
wr_data(num[hour%10]);
if(flag==0)
{
flag++;
wr_data(num[10]);
}
else
{
 flag=0;
 wr_data(0x20);
 }
wr_data(num[minute/10]);
wr_data(num[minute%10]);
    }
	
void wr_tem()
{
unsigned char i;
wr_comm(0x98);
wr_data(date[6]);
wr_data(date[7]);
wr_data(date[8]);
wr_data(date[9]);
wr_data(num[10]);
if(temperature==0)
wr_data(0x20);
else
{
if(temperature>0)
wr_data(num[11]);
else
wr_data(num[12]);
}

i=abs(temperature);
wr_data(num[i/10]);
wr_data(num[i%10]);

wr_data(0xa1);
wr_data(0xe6);

      }

#pragma interrupt_handler int0_isr:2
void int0_isr(void)
{
unsigned char i;
unsigned int j;
CLI();
i=ds_rc;//清ds12887中断
second=ds_second;
if(second)
{
j=star_ad();
temperature=tem_rd(j);
if(temperature==0xff)
{
wr_time();
wr_char(0x98,"温度有错");
}
else
{
wr_time();
wr_tem();
}
}
else
{
if(hour==0&&minute==0)
wr_runyear();
ds12887_rd();
j=star_ad();
temperature=tem_rd(j);
if(temperature==0xff)
{
wr_time();
wr_char(0x98,"温度有错");
}
else
{
wr_time();
wr_tem();
}
wr_date();
wr_time();
}
SEI();

}

void int_int0()
{//启动外中断0
CLI();
MCUCR = 0x00;
EICRA = 0x00; 
EICRB = 0x00; 
EIMSK = 0x01;
}  

void int_bus()
{
//启动总线功能
MCUCR|=1<<SRE;
XMCRA=0b00001110;
XMCRB=0b10000000;
}  

void set_key()
{
set_flag++;
if(set_flag==1)
CLI();

if(set_flag==7)
{
second=0;
ds12887_wr();
ds_second=second;
set_flag=0;
SEI();

}
delay(2100);
}

void set_sub()
{
switch(set_flag)
{
case 1: 
{if(year==0)
year=99;
else
year--;
break;}
case 2: 
{if(month==1)
month=12;
else
month--;
break;}
case 3: 
{if(day==1)
day=31;
else
day--;
break;}
case 4: 
{if(week==1)
week=7;
else
week--;
break;}
case 5: 
{if(hour==0)
hour=59;
else
hour--;
break;}
case 6: 
{if(minute==0)
minute=59;
else
minute--;
break;}
default:  break;
}
wr_date();
wr_time();
delay(2100);
}
void set_add()
{
switch(set_flag)
{
case 1: 
{if(year==99)
year=0;
else
year++;
break;}
case 2: 
{if(month==12)
month=1;
else
month++;
break;}
case 3: 
{if(day==31)
day=1;
else
day++;
break;}
case 4: 
{if(week==7)
week=1;
else
week++;
break;}
case 5: 
{if(hour==59)
hour=0;
else
hour++;
break;}
case 6: 
{if(minute==59)
minute=0;
else
minute++;
break;}
default:  break;
}
wr_date();
wr_time();
delay(2100);
}

	  
void main()
{

int_port();
lcd_int();
all_off();
int_int0();
int_bus();
ds12887_int();
ds12887_rd();
wr_date();
wr_time();
wr_runyear();
SEI();
while(1)
{
key=PIND|0x0f;
if(~key)
{
delay_nms(21);
key=PIND|0x0f;
if(~key)
{
key&=0xf0;
switch(key)
{
case 0xe0:  bl_con();break;
case 0xd0:  set_sub();break;
case 0xb0:  set_add();break;
case 0x70:  set_key();break;
default:  break;
}
}
}

}
}

⌨️ 快捷键说明

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