#include <reg52.h> 
#include<intrins.h> 
/*********************宏定义DS1302寄存器读写地址*************************/ 
#define WRITE_SECOND               0x80 
#define WRITE_MINUTE               0x82 
#define WRITE_HOUR                 0x84 
#define WRITE_DAY                   0x86 
#define WRITE_MONTH                0x88 
#define WRITE_WEEK                 0x8A 
#define WRITE_YEAR                 0x8C 
#define WRITE_TIMER_FLAG           0xC0 
 
#define READ_SECOND                0x81 
#define READ_MINUTE                0x83 
#define READ_HOUR                  0x85 
#define READ_DAY                   0x87 
#define READ_MONTH                 0x89 
#define READ_WEEK                  0x8B 
#define READ_YEAR                  0x8D 
#define READ_TIMER_FLAG            0xC1 
#define WRITE_PROTECT              0x8E 
/**************************************************************************/ 
unsigned char  Data_YEAR[4]={2,0,0,0};//存储阳历年的信息 
unsigned char  Data_MONTH[2]={0,0}; //存储阳历月的信息 
unsigned char  Data_DAY[2]={0,0};     //存储阳历日的信息 
unsigned char  Data_HOUR[2]={0,0};    //存储时的信息 
unsigned char  Data_MINUTE[2]={0,0};  //存储分的信息 
unsigned char  Data_SECOND[2]={0,0};  //存储秒的信息 
unsigned char  Data_WEEK=0;           //存储星期的信息 
unsigned char  Data_TEMPERATUER[2]={0,0};//存储温度 
 
unsigned char  Data_YEAR_Y[4]={0,0,0,0};//存储阴历年的信息 
unsigned char  Data_MONTH_Y[2]={0,0};   //存储阴历月的信息 
unsigned char  Data_DAY_Y[2]={0,0};     //存储阴历日的信息 
 
/***************************初始化时间***********************************/ 
unsigned char Year = 10,Mon = 7,Day =1,Hour=12,Min=18,Sec = 40,Week = 4; 
 
/****************************标志位定义***********************************/ 
unsigned char timer_flag_rom = 0x20;//设置掉电走时标志(timer_flag_rom初始化时写入rom下次与timer_flag比较)   
/***********************************************/ 
 
/********DS1302与MCU连接脚及驱动程序中用到的累加器定义************/ 
//位寻址寄存器定义 
sbit ACC_7 = ACC^7; 
//管脚定义 
sbit SCLK = P1^2;                   // DS1302时钟信号         7脚 
sbit DIO  = P1^1;                   // DS1302数据信号         6脚 
sbit CE   = P1^0;                   // DS1302片选             5脚 
/*************************************************************/ 
/***********十进制转换为十六进制子程序***************************/ 
/*****函数名称:unsigned char O_to_H(unsigned char n) 
******功能:    十进制转换为十六进制 
******参数传递:有,十进制数n 
******返回值:  有,转换后的十六进制数 
******创建时间:2010.7.1 
******修改时间: 
******/  
/************************************************************************/ 
unsigned char O_to_H(unsigned char n) 
{ 
    unsigned char temp1; 
 
    temp1 =  n/10*16 + n%10; 
     
    return(temp1); 
} 
/*******************************************************/ 
/***************地址、数据发送子程序*****************************/ 
/*****函数名称:void Write1302 (unsigned char addr,dat) 
******功能:    串行发送地址、数据,先发低位,且在上升沿发送 
******参数传递:有,地址和数据 
******返回值:  无 
******创建时间:2010.7.1 
******修改时间: 
******/  
/*************************************************************/ 
void Write1302 (unsigned char addr,dat)      
{ 
       unsigned char i,temp; 
 
       CE=0;                         //CE引脚为低,数据传送中止 
       SCLK=0;                       //清零时钟总线 
       CE = 1;                       //CE引脚为高,逻辑控制有效 
 
       //发送地址 
       for ( i=8; i>0; i-- )         //循环8次移位 
       { 
              SCLK = 0; 
              temp = addr; 
              DIO = (bit)(temp&0x01);    //每次传输低字节 
              addr >>= 1;                //右移一位 
              SCLK = 1; 
       } 
              
 
       //发送数据 
       for ( i=8; i>0; i-- ) 
       {      
              SCLK = 0; 
              temp = dat; 
              DIO = (bit)(temp&0x01); 
              dat >>= 1; 
              SCLK = 1; 
       } 
 
       CE = 0; 
} 
/********************************************************************/ 
/***********************数据读取子程序*****************************/ 
/*****函数名称:unsigned char Read1302 ( unsigned char addr ) 
******功能:    串行读取数据,先发低位,且在下降沿发送 
******参数传递:有,地址 
******返回值:  有,读取的数据 
******创建时间:2010.7.1 
******修改时间: 
******/  
/****************************************************/ 
 
unsigned char Read1302 ( unsigned char addr ) 
 
{ 
       unsigned char i,temp,dat1,dat2; 
 
       CE=0; 
       SCLK=0; 
       CE = 1; 
       //发送地址 
       for ( i=8; i>0; i-- )                      //循环8次移位 
 
       {      
              SCLK = 0; 
              temp = addr; 
              DIO = (bit)(temp&0x01);             //每次传输低字节 
              addr >>= 1;                         //右移一位 
              SCLK = 1; 
 
       } 
 
       //读取数据 
       for ( i=8; i>0; i-- ) 
       { 
              ACC_7=DIO; 
              SCLK = 1; 
              ACC>>=1; 
              SCLK = 0; 
       } 
       CE=0; 
       dat1=ACC; 
       dat2=dat1/16;                           //数据进制转换 
       dat1=dat1%16;                         //十六进制转十进制 
       dat1=dat1+dat2*10;        
 
       return (dat1); 
} 
/***********************************************************************/ 
/*********************初始化DS1302子程序*****************************/ 
/*****函数名称:void DS1302init(void)  
******功能:    DS1302初始化,时分秒,年月日,周,和RAM(0xC0) 
******参数传递:无 
******返回值:  无 
******创建时间:2010.7.1 
******修改时间: 
******/  
/******************************************************************/ 
void DS1302init(void) 
{  
       Write1302 (WRITE_PROTECT,0x00);                //禁止写保护 
       Write1302 (WRITE_SECOND,O_to_H(Sec));          //秒位初始化 
       Write1302 (WRITE_MINUTE,O_to_H(Min));          //分钟初始化 
       Write1302 (WRITE_HOUR,O_to_H(Hour));           //小时初始化 
       Write1302 (WRITE_DAY,O_to_H(Day));             //日初始化 
       Write1302 (WRITE_MONTH,O_to_H(Mon));         //月初始化 
       Write1302 (WRITE_WEEK,O_to_H(Week));          //周初始化 
       Write1302 (WRITE_YEAR,O_to_H(Year));           //年初始化 
 
       Write1302 (WRITE_TIMER_FLAG,timer_flag_rom);  //设置掉电走时标志 
 
       Write1302 (WRITE_PROTECT,0x80);                //允许写保护 
 
} 
/*****************获取日期的值并放入对应的数组********************/ 
void GetData(void) 
{ 
     Data_YEAR[0]=2; 
     Data_YEAR[1]=0; 
     Data_YEAR[2]=Read1302(READ_YEAR)/10; 
     Data_YEAR[3]=Read1302(READ_YEAR)%10; 
      
     Data_MONTH[0]=Read1302(READ_MONTH)/10; 
     Data_MONTH[1]=Read1302(READ_MONTH)%10; 
 
     Data_DAY[0]=Read1302(READ_DAY)/10; 
     Data_DAY[1]=Read1302(READ_DAY)%10; 
 
         Data_HOUR[0]=Read1302(READ_HOUR)/10; 
     Data_HOUR[1]=Read1302(READ_HOUR)%10; 
      
     Data_MINUTE[0]=Read1302(READ_MINUTE)/10; 
         Data_MINUTE[1]=Read1302(READ_MINUTE)%10; 
   
     Data_SECOND[0]=Read1302(READ_SECOND)/10; 
     Data_SECOND[1]=Read1302(READ_SECOND)%10; 
 
     Data_WEEK=Read1302(READ_WEEK); 
} 
/************************************************************* 
数码管 
******************************************************************/ 
/*********************数码管管脚与MCU的连接*************************/ 
sbit DAT=P0^0; 
sbit CLK=P0^1; 
sbit LED1=P0^2; 
sbit LED2=P0^3; 
sbit LED3=P0^4; 
sbit LED4=P0^5; 
sbit LED5=P0^6; 
sbit LED6=P0^7; 
sbit LED7=P2^7; 
sbit LED8=P2^6; 
sbit LED9=P2^5; 
 
unsigned char code table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xFF};//数码管的码段 
/*************************延时函数******************************/ 
void delay(unsigned int Delay)  //延时 
{ unsigned  int ty; 
  for(;Delay>0;Delay--) 
    { 
      for(ty=0;ty<1;ty++) 
       {;} 
} 
} 
/*************74HC164的驱动函数***************************/ 
void sendchar(unsigned char byte) 
{ 
   unsigned char ch,i; 
   ch=table[byte]; 
   for(i=0;i<8;i++)//8位数据传输完毕后才给数码管显示 
{  
    if(0x80==(ch&0x80))DAT=1; 
    else DAT=0; 
    CLK=0; 
    CLK=1; 
    ch<<=1; 
} 
} 
/******************数码管扫描显示函数****************************/ 
void SMGdisp(void) 
{ 
 
sendchar(Data_YEAR[0]);//阳历年的第一位 
sendchar(Data_HOUR[0]);//时的高位 
sendchar(Data_YEAR_Y[0]);//阴历年的第一位 
LED1=0; 
delay(100); 
LED1=1; 
 
sendchar(Data_YEAR[1]);//阳历年的第二位 
sendchar(Data_HOUR[1]);//时的低位 
sendchar(Data_YEAR_Y[1]);//阴历年的第二位 
LED2=0; 
delay(100); 
LED2=1; 
 
sendchar(Data_YEAR[2]);//阳历年的第三位 
sendchar(Data_MINUTE[0]);//分的高位 
sendchar(Data_YEAR_Y[2]);//阴历年的第三位 
LED3=0; 
delay(100); 
LED3=1; 
 
sendchar(Data_YEAR[3]);//阳历年的第四位 
sendchar(Data_MINUTE[1]);//分的低位 
sendchar(Data_YEAR_Y[3]);//阴历年的第四位 
LED4=0; 
delay(100); 
LED4=1; 
 
sendchar(Data_MONTH[0]);//阳历月的高位 
sendchar(Data_SECOND[0]);//秒的高位 
sendchar(Data_MONTH_Y[0]);//阴历月的高位 
LED5=0; 
delay(100); 
LED5=1; 
 
sendchar(Data_MONTH[1]);//阳历月的低位 
sendchar(Data_SECOND[1]);//秒的低位 
sendchar(Data_MONTH_Y[1]);//阴历月的低位 
LED6=0; 
delay(100); 
LED6=1; 
 
sendchar(Data_DAY[0]);        //阳历日的高位 
sendchar(Data_TEMPERATUER[0]);//温度的高位 
sendchar(Data_DAY_Y[0]);      //阴历日的高位 
LED7=0; 
delay(100); 
LED7=1; 
 
sendchar(Data_DAY[1]);        //阳历日的低位 
sendchar(Data_TEMPERATUER[1]);//温度的低位 
sendchar(Data_DAY_Y[1]);      //阴历日的低位 
LED8=0; 
delay(100); 
LED8=1; 
 
sendchar(Data_WEEK);//星期 
sendchar(10);       //电路中没有数码管随便发送的数据 
sendchar(10);       //电路中没有数码管随便发送的数据 
LED9=0; 
delay(100); 
LED9=1;  
} 
/***************************************** 
按键 
***************************************/ 
/**********按键和MCU的接口********************/ 
sbit ChooseKey=P3^2; 
sbit UpKey=P3^3; 
sbit DownKey=P3^4; 
 
unsigned char ChooseID=0;//按键所用到的全局变量 
/******************按键用到的延时*******************/ 
void delay1ms (unsigned char b)//1ms 
{ 
for(b;b>0;b--) 
{unsigned int i; 
  for(i=0;i<300;i++) 
   {;} 
} 
} 
/*********************************************************** 
DS18B20 
************************************************************/ 
/*******************DS18B20和MCU的接口********************/ 
sbit DQ=P1^3;//定义单片机接ds18b20的数据端 
 
unsigned int temper;//DS18B20用到的全局变量 
 
/*******************延时********************************/ 
void NOP(void) 
{ 
 
        _nop_();_nop_(); 
 
} 
 
void Delay15us(void)//精确延时15us(单片机精灵) 
{ 
    unsigned char a; 
    for(a=12;a>0;a--); 
} 
 
void Delay10us(void)//精确延时10us(单片机精灵) 
{ 
    unsigned char a,b; 
    for(b=3;b>0;b--) 
    for(a=1;a>0;a--); 
}   
/***************************************************** 
ds18b20复位,返回0,设备正常,返回1,没有设备或设备不正常 
***********************************************/ 
bit resetpulse(void) 
{ 
   unsigned char i; 
   bit RstFlag; 
   RstFlag=1; 
   DQ=0; 
   for(i=0;i<40;i++)//480us延时 
   { 
     Delay15us(); 
   } 
 
     DQ=1; 
 
   for(i=0;i<4;i++)//15~60us延时 
   { 
     Delay15us(); 
   } 
 
   for(i=0;i<16;i++)//60~240us延时 
   { 
     Delay15us(); 
     if(DQ==0) 
     RstFlag=0; 
   } 
 
   for(i=0;i<16;i++) 
   { 
     Delay15us(); 
   } 
return(RstFlag); 
} 
 
/************************************************ 
18b20的读写命令都是低位在先,所以发送或读取数值,首先发送或读取的是数据的最低位 
**************************************************/ 
void writecommandtods18b20(unsigned char command)//ds18b20写命令 
{ 
unsigned char i; 
   DQ=1; 
   NOP(); 
for(i=0;i<8;i++) 
{ 
   DQ=0; 
   Delay15us(); 
   DQ=command&0x1;//低位在先 
   Delay15us(); 
   Delay15us(); 
   Delay15us(); 
   DQ=1; 
   command=command>>1; 
   NOP(); 
} 
} 
 
unsigned char readdatafromds18b20(void)//ds18b20读命令 
{ 
unsigned char i; 
unsigned char temp; 
temp=0; 
   
DQ=1; 
   NOP(); 
for(i=0;i<8;i++) 
{ 
   DQ=0; 
   Delay10us(); 
   DQ=1; 
   NOP(); 
   temp=temp>>1; 
   if(DQ==1) 
   { 
    temp=temp+0x80;//先读到最高位,再依次右移 
   } 
   Delay15us(); 
   Delay15us(); 
   Delay15us(); 
} 
 
    return(temp); 
} 
 
void GetTemperature(void) 
{ 
        unsigned char tem1,tem2; 
        float aaa; 
        while(resetpulse()==1);  //复位 
        writecommandtods18b20(0xCC);//跳过ROM 
        writecommandtods18b20(0x44);//温度转换 
        while(resetpulse()==1);  //复位 
        writecommandtods18b20(0xCC); 
        writecommandtods18b20(0xBE); 
        tem1=readdatafromds18b20(); 
        tem2=readdatafromds18b20(); 
        aaa=(tem2*256+tem1)*6.25; 
 
        temper=(int)aaa; 
        Data_TEMPERATUER[0]=temper/1000; 
        Data_TEMPERATUER[1]=temper%1000/100; 
 
} 
 
/********************阳历转换阴历***********************************/ 
code unsigned char year_code[597]={ 
                    0x04,0xAe,0x53,    //1901 0 
                    0x0A,0x57,0x48,    //1902 3 
                    0x55,0x26,0xBd,    //1903 6 
                    0x0d,0x26,0x50,    //1904 9 
                    0x0d,0x95,0x44,    //1905 12 
                    0x46,0xAA,0xB9,    //1906 15 
                    0x05,0x6A,0x4d,    //1907 18 
                    0x09,0xAd,0x42,    //1908 21 
                    0x24,0xAe,0xB6,    //1909 
                    0x04,0xAe,0x4A,    //1910 
                    0x6A,0x4d,0xBe,    //1911 
                    0x0A,0x4d,0x52,    //1912 
                    0x0d,0x25,0x46,    //1913 
                    0x5d,0x52,0xBA,    //1914 
                    0x0B,0x54,0x4e,    //1915 
                    0x0d,0x6A,0x43,    //1916 
                    0x29,0x6d,0x37,    //1917 
                    0x09,0x5B,0x4B,    //1918 
                    0x74,0x9B,0xC1,    //1919 
                    0x04,0x97,0x54,    //1920 
                    0x0A,0x4B,0x48,    //1921 
                    0x5B,0x25,0xBC,    //1922 
                    0x06,0xA5,0x50,    //1923 
                    0x06,0xd4,0x45,    //1924 
                    0x4A,0xdA,0xB8,    //1925 
                    0x02,0xB6,0x4d,    //1926 
                    0x09,0x57,0x42,    //1927 
                    0x24,0x97,0xB7,    //1928 
                    0x04,0x97,0x4A,    //1929 
                    0x66,0x4B,0x3e,    //1930 
                    0x0d,0x4A,0x51,    //1931 
                    0x0e,0xA5,0x46,    //1932 
                    0x56,0xd4,0xBA,    //1933 
                    0x05,0xAd,0x4e,    //1934 
                    0x02,0xB6,0x44,    //1935 
                    0x39,0x37,0x38,    //1936 
                    0x09,0x2e,0x4B,    //1937 
                    0x7C,0x96,0xBf,    //1938 
                    0x0C,0x95,0x53,    //1939 
                    0x0d,0x4A,0x48,    //1940 
                    0x6d,0xA5,0x3B,    //1941 
                    0x0B,0x55,0x4f,    //1942 
                    0x05,0x6A,0x45,    //1943 
                    0x4A,0xAd,0xB9,    //1944 
                    0x02,0x5d,0x4d,    //1945 
                    0x09,0x2d,0x42,    //1946 
                    0x2C,0x95,0xB6,    //1947 
                    0x0A,0x95,0x4A,    //1948 
                    0x7B,0x4A,0xBd,    //1949 
                    0x06,0xCA,0x51,    //1950 
                    0x0B,0x55,0x46,    //1951 
                    0x55,0x5A,0xBB,    //1952 
                    0x04,0xdA,0x4e,    //1953 
                    0x0A,0x5B,0x43,    //1954 
                    0x35,0x2B,0xB8,    //1955 
                    0x05,0x2B,0x4C,    //1956 
                    0x8A,0x95,0x3f,    //1957 
                    0x0e,0x95,0x52,    //1958 
                    0x06,0xAA,0x48,    //1959 
                    0x7A,0xd5,0x3C,    //1960 
                    0x0A,0xB5,0x4f,    //1961 
                    0x04,0xB6,0x45,    //1962 
                    0x4A,0x57,0x39,    //1963 
                    0x0A,0x57,0x4d,    //1964 
                    0x05,0x26,0x42,    //1965 
                    0x3e,0x93,0x35,    //1966 
                    0x0d,0x95,0x49,    //1967 
                    0x75,0xAA,0xBe,    //1968 
                    0x05,0x6A,0x51,    //1969 
                    0x09,0x6d,0x46,    //1970 
                    0x54,0xAe,0xBB,    //1971 
                    0x04,0xAd,0x4f,    //1972 
                    0x0A,0x4d,0x43,    //1973 
                    0x4d,0x26,0xB7,    //1974 
                    0x0d,0x25,0x4B,    //1975 
                    0x8d,0x52,0xBf,    //1976 
                    0x0B,0x54,0x52,    //1977 
                    0x0B,0x6A,0x47,    //1978 
                    0x69,0x6d,0x3C,    //1979 
                    0x09,0x5B,0x50,    //1980 
                    0x04,0x9B,0x45,    //1981 
                    0x4A,0x4B,0xB9,    //1982 
                    0x0A,0x4B,0x4d,    //1983 
                    0xAB,0x25,0xC2,    //1984 
                    0x06,0xA5,0x54,    //1985 
                    0x06,0xd4,0x49,    //1986 
                    0x6A,0xdA,0x3d,    //1987 
                    0x0A,0xB6,0x51,    //1988 
                    0x09,0x37,0x46,    //1989 
                    0x54,0x97,0xBB,    //1990 
                    0x04,0x97,0x4f,    //1991 
                    0x06,0x4B,0x44,    //1992 
                    0x36,0xA5,0x37,    //1993 
                    0x0e,0xA5,0x4A,    //1994 
                    0x86,0xB2,0xBf,    //1995 
                    0x05,0xAC,0x53,    //1996 
                    0x0A,0xB6,0x47,    //1997 
                    0x59,0x36,0xBC,    //1998 
                    0x09,0x2e,0x50,    //1999 294 
                    0x0C,0x96,0x45,    //2000 297 
                    0x4d,0x4A,0xB8,    //2001 
                    0x0d,0x4A,0x4C,    //2002 
                    0x0d,0xA5,0x41,    //2003 
                    0x25,0xAA,0xB6,    //2004 
                    0x05,0x6A,0x49,    //2005 
                    0x7A,0xAd,0xBd,    //2006 
                    0x02,0x5d,0x52,    //2007 
                    0x09,0x2d,0x47,    //2008 
                    0x5C,0x95,0xBA,    //2009 
                    0x0A,0x95,0x4e,    //2010 
                    0x0B,0x4A,0x43,    //2011 
                    0x4B,0x55,0x37,    //2012 
                    0x0A,0xd5,0x4A,    //2013 
                    0x95,0x5A,0xBf,    //2014 
                    0x04,0xBA,0x53,    //2015 
                    0x0A,0x5B,0x48,    //2016 
                    0x65,0x2B,0xBC,    //2017 
                    0x05,0x2B,0x50,    //2018 
                    0x0A,0x93,0x45,    //2019 
                    0x47,0x4A,0xB9,    //2020 
                    0x06,0xAA,0x4C,    //2021 
                    0x0A,0xd5,0x41,    //2022 
                    0x24,0xdA,0xB6,    //2023 
                    0x04,0xB6,0x4A,    //2024 
                    0x69,0x57,0x3d,    //2025 
                    0x0A,0x4e,0x51,    //2026 
                    0x0d,0x26,0x46,    //2027 
                    0x5e,0x93,0x3A,    //2028 
                    0x0d,0x53,0x4d,    //2029 
                    0x05,0xAA,0x43,    //2030 
                    0x36,0xB5,0x37,    //2031 
                    0x09,0x6d,0x4B,    //2032 
                    0xB4,0xAe,0xBf,    //2033 
                    0x04,0xAd,0x53,    //2034 
                    0x0A,0x4d,0x48,    //2035 
                    0x6d,0x25,0xBC,    //2036 
                    0x0d,0x25,0x4f,    //2037 
                    0x0d,0x52,0x44,    //2038 
                    0x5d,0xAA,0x38,    //2039 
                    0x0B,0x5A,0x4C,    //2040 
                    0x05,0x6d,0x41,    //2041 
                    0x24,0xAd,0xB6,    //2042 
                    0x04,0x9B,0x4A,    //2043 
                    0x7A,0x4B,0xBe,    //2044 
                    0x0A,0x4B,0x51,    //2045 
                    0x0A,0xA5,0x46,    //2046 
                    0x5B,0x52,0xBA,    //2047 
                    0x06,0xd2,0x4e,    //2048 
                    0x0A,0xdA,0x42,    //2049 
                    0x35,0x5B,0x37,    //2050 
                    0x09,0x37,0x4B,    //2051 
                    0x84,0x97,0xC1,    //2052 
                    0x04,0x97,0x53,    //2053 
                    0x06,0x4B,0x48,    //2054 
                    0x66,0xA5,0x3C,    //2055 
                    0x0e,0xA5,0x4f,    //2056 
                    0x06,0xB2,0x44,    //2057 
                    0x4A,0xB6,0x38,    //2058 
                    0x0A,0xAe,0x4C,    //2059 
                    0x09,0x2e,0x42,    //2060 
                    0x3C,0x97,0x35,    //2061 
                    0x0C,0x96,0x49,    //2062 
                    0x7d,0x4A,0xBd,    //2063 
                    0x0d,0x4A,0x51,    //2064 
                    0x0d,0xA5,0x45,    //2065 
                    0x55,0xAA,0xBA,    //2066 
                    0x05,0x6A,0x4e,    //2067 
                    0x0A,0x6d,0x43,    //2068 
                    0x45,0x2e,0xB7,    //2069 
                    0x05,0x2d,0x4B,    //2070 
                    0x8A,0x95,0xBf,    //2071 
                    0x0A,0x95,0x53,    //2072 
                    0x0B,0x4A,0x47,    //2073 
                    0x6B,0x55,0x3B,    //2074 
                    0x0A,0xd5,0x4f,    //2075 
                    0x05,0x5A,0x45,    //2076 
                    0x4A,0x5d,0x38,    //2077 
                    0x0A,0x5B,0x4C,    //2078 
                    0x05,0x2B,0x42,    //2079 
                    0x3A,0x93,0xB6,    //2080 
                    0x06,0x93,0x49,    //2081 
                    0x77,0x29,0xBd,    //2082 
                    0x06,0xAA,0x51,    //2083 
                    0x0A,0xd5,0x46,    //2084 
                    0x54,0xdA,0xBA,    //2085 
                    0x04,0xB6,0x4e,    //2086 
                    0x0A,0x57,0x43,    //2087 
                    0x45,0x27,0x38,    //2088 
                    0x0d,0x26,0x4A,    //2089 
                    0x8e,0x93,0x3e,    //2090 
                    0x0d,0x52,0x52,    //2091 
                    0x0d,0xAA,0x47,    //2092 
                    0x66,0xB5,0x3B,    //2093 
                    0x05,0x6d,0x4f,    //2094 
                    0x04,0xAe,0x45,    //2095 
                    0x4A,0x4e,0xB9,    //2096 
                    0x0A,0x4d,0x4C,    //2097 
                    0x0d,0x15,0x41,    //2098 
                    0x2d,0x92,0xB5,    //2099 
}; 
///月份数据表 
code unsigned char day_code1[9]={0x0,0x1f,0x3b,0x5a,0x78,0x97,0xb5,0xd4,0xf3}; 
code unsigned int day_code2[3]={0x111,0x130,0x14e}; 
 
bit c_moon; 
data unsigned char year_moon,month_moon,day_moon; 
/*子函数,用于读取数据表中农历月的大月或小月,如果该月为大返回1,为小返回0*/ 
bit 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);} 
    } 
} 
/* 
函数功能:输入BCD阳历数据,输出BCD阴历数据(只允许1901-2099年) 
调用函数示例:Conversion(c_sun,year_sun,month_sun,day_sun) 
如:计算2004年10月16日Conversion(0,0x4,0x10,0x16); 
c_sun,year_sun,month_sun,day_sun均为BCD数据,c_sun为世纪标志位,c_sun=0为21世 
纪,c_sun=1为19世纪 
调用函数后,原有数据不变,读c_moon,year_moon,month_moon,day_moon得出阴历BCD数据 
*/ 
void Conversion(bit c,unsigned char year,unsigned char month,unsigned char day) 
{   //c=0 为21世纪,c=1 为19世纪 输入输出数据均为BCD数据 
    unsigned char temp1,temp2,temp3,month_p; 
    unsigned int temp4,table_addr; 
    bit flag2,flag_y; 
    temp1=year/16;   //BCD->hex 先把数据转换为十六进制 
    temp2=year%16; 
    year=temp1*10+temp2; 
    temp1=month/16; 
    temp2=month%16; 
    month=temp1*10+temp2; 
    temp1=day/16; 
    temp2=day%16; 
    day=temp1*10+temp2; 
    //定位数据表地址 
    if(c==0){                    
        table_addr=(year+0x64-1)*0x3; 
    } 
    else { 
        table_addr=(year-1)*0x3; 
    } 
    //定位数据表地址完成 
    //取当年春节所在的公历月份 
    temp1=year_code[table_addr+2]&0x60;  
    temp1=_cror_(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 (month<10){  
        temp4=day_code1[month-1]+day-1; 
    } 
    else{ 
        temp4=day_code2[month-10]+day-1; 
    } 
    if ((month>0x2)&&(year%0x4==0)){  //如果公历月大于2月并且该年的2月为闰月,天数加1 
        temp4+=1; 
    } 
    //计算公历日离当年元旦的天数完成 
    //判断公历日在春节前还是春节后 
    if (temp4>=temp3){ //公历日在春节后或就是春节当日使用下面代码进行运算 
        temp4-=temp3; 
        month=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=_cror_(temp2,4);  //从数据表中取该年的闰月月份,如为0则该年无闰月 
        while(temp4>=temp1){ 
            temp4-=temp1; 
            month_p+=1; 
            if(month==temp2){ 
            flag_y=~flag_y; 
            if(flag_y==0)month+=1; 
            } 
            else month+=1; 
            flag2=get_moon_day(month_p,table_addr); 
            if(flag2==0)temp1=0x1d; 
            else temp1=0x1e; 
        } 
        day=temp4+1; 
    } 
    else{  //公历日在春节前使用下面代码进行运算 
        temp3-=temp4; 
        if (year==0x0){year=0x63;c=1;} 
        else year-=1; 
        table_addr-=0x3; 
        month=0xc; 
        temp2=year_code[table_addr]&0xf0; 
        temp2=_cror_(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)month-=1; 
            if(month==temp2)flag_y=~flag_y; 
            flag2=get_moon_day(month_p,table_addr); 
            if(flag2==0)temp1=0x1d; 
            else temp1=0x1e; 
         } 
        day=temp1-temp3+1; 
    } 
    c_moon=c;                 //HEX->BCD ,运算结束后,把数据转换为BCD数据 
    temp1=year/10; 
    temp1=_crol_(temp1,4); 
    temp2=year%10; 
    year_moon=temp1|temp2; 
    temp1=month/10; 
    temp1=_crol_(temp1,4); 
    temp2=month%10; 
    month_moon=temp1|temp2; 
    temp1=day/10; 
    temp1=_crol_(temp1,4); 
    temp2=day%10; 
    day_moon=temp1|temp2; 
} 
 
void GetYinliData(void)  //提取阴历的年/月/日 
{ 
Conversion(0,O_to_H(Read1302(READ_YEAR)),O_to_H(Read1302(READ_MONTH)),O_to_H(Read1302(READ_DAY)));//取出的为BCD码 
Data_YEAR_Y[0]=2; 
Data_YEAR_Y[1]=0; 
Data_YEAR_Y[2]=year_moon/16; 
Data_YEAR_Y[3]=year_moon%16; 
 
Data_MONTH_Y[0]=month_moon/16; 
Data_MONTH_Y[1]=month_moon%16; 
 
Data_DAY_Y[0]=day_moon/16; 
Data_DAY_Y[1]=day_moon%16; 
 
} 
 
/******************IO口初始化***************************/ 
void IOinit(void) 
{ 
; 
} 
 
 
void main(void) 
{ 
        IOinit();    //IO口初始化 
    DS1302init();//DS1302初始化 
 
        while(1) 
        { 
/**********************年(1)\月(2)\日(3)\星期(4)\时(5)\分(6)\秒(7)选择键***********************/ 
     if(ChooseKey==0)//选择按键是否按下 
     { 
                 delay1ms (10);//去抖 
             if(ChooseKey==0) 
                { 
                 ChooseID++; 
         if(ChooseID==7)//如果用到了秒调整,则这里ChooseID==8 
                   {ChooseID=0;} 
                while (ChooseKey==0);//等待按键释放         
         }                 
            } 
/***********************选择年*************************************/ 
        if(ChooseID==1) 
                { 
                        if(UpKey==0)//向上按键是否按下 
                        { 
                                 delay1ms (10);//去抖 
                             if(UpKey==0) 
                                {  
                    Year=Read1302(READ_YEAR);                     //先读取年 
                                        Year++; 
                                        if(Year>50){Year=0;} 
                                        Write1302 (WRITE_PROTECT,0x00);                //禁止写保护 
                                        Write1302 (WRITE_YEAR,O_to_H(Year));            //年写入 
                    Write1302 (WRITE_PROTECT,0x80);                //允许写保护 
                    while (UpKey==0);                              //等待按键释放         
                                } 
                         } 
             if(DownKey==0)//向下按键是否按下 
                        { 
                                 delay1ms (10);//去抖 
                             if(DownKey==0) 
                                { 
                    Year=Read1302(READ_YEAR);                     //先读取年 
                                        Year--; 
                                        if(Year==255){Year=50;} //需要注意,Year是unsigned char型的当它等于0的时候再减1则为255。 
                                        Write1302 (WRITE_PROTECT,0x00);                //禁止写保护 
                                        Write1302 (WRITE_YEAR,O_to_H(Year));           //年写入 
                    Write1302 (WRITE_PROTECT,0x80);                //允许写保护 
                                        while (DownKey==0);                            //等待按键释放         
                                } 
                         } 
                } 
/***********************************选择月***********************************/ 
if(ChooseID==2) 
                { 
                        if(UpKey==0)//向上按键是否按下 
                        { 
                                 delay1ms (10);//去抖 
                             if(UpKey==0) 
                                { 
                    Mon=Read1302(READ_MONTH);                     //先读取月 
                                        Mon++; 
                                        if(Mon>12){Mon=1;} 
                                        Write1302 (WRITE_PROTECT,0x00);                //禁止写保护 
                                        Write1302 (WRITE_MONTH,O_to_H(Mon));           //年写入 
                    Write1302 (WRITE_PROTECT,0x80);                //允许写保护 
                    while (UpKey==0);                              //等待按键释放         
                                } 
                         } 
             if(DownKey==0)//向下按键是否按下 
                        { 
                                 delay1ms (10);//去抖 
                             if(DownKey==0) 
                                { 
                    Mon=Read1302(READ_MONTH);                     //先读取月 
                                        Mon--; 
                                        if(Mon==0){Mon=12;} 
                                        Write1302 (WRITE_PROTECT,0x00);                //禁止写保护 
                                        Write1302 (WRITE_MONTH,O_to_H(Mon));           //年写入 
                    Write1302 (WRITE_PROTECT,0x80);                //允许写保护 
                                        while (DownKey==0);                            //等待按键释放         
                                } 
                         } 
                } 
/***********************************选择日***********************************/ 
if(ChooseID==3) 
                { 
                        if(UpKey==0)//向上按键是否按下 
                        { 
                                 delay1ms (10);//去抖 
                             if(UpKey==0) 
                                { 
                    Day=Read1302(READ_DAY);                     //先读取日 
                                        Day++; 
                    switch(Read1302(READ_MONTH)) 
                                        { 
                                        case 1://属于一个月中有31天的调整 
                                    case 3: 
                                    case 5: 
                                        case 7: 
                                        case 8: 
                                        case 10: 
                                        case 12:                                                       
                                    if(Day>31){Day=1;}//到32归1 
                                                break; 
                                        case 4://属于一个月中有30天的调整 
                                    case 6: 
                                        case 9: 
                                    case 11: 
                                        if(Day>30){Day=1;}//到31归1 
                                                break;           
                                        case 2://属于2月份根据是平的还是闰年来调整 
                                        if(0==(Read1302(READ_YEAR)%4))//如果是闰年.则 
                                        { 
                                        if(Day>29){Day=1;}//到30归1 
                                        } 
                                    else//是平年,则 
                                        { 
                                        if(Day>28){Day=1;}//到29归1 
                                        } 
                                        break; 
                    } 
                                        Write1302 (WRITE_PROTECT,0x00);                //禁止写保护 
                                        Write1302 (WRITE_DAY,O_to_H(Day));           //年写入 
                    Write1302 (WRITE_PROTECT,0x80);                //允许写保护 
                    while (UpKey==0);                              //等待按键释放         
                                } 
                         } 
             if(DownKey==0)//向下按键是否按下 
                        { 
                                 delay1ms (10);//去抖 
                             if(DownKey==0) 
                                { 
                    Day=Read1302(READ_DAY);                     //先读取日 
                                        Day--; 
                    switch(Read1302(READ_MONTH)) 
                                        { 
                                        case 1:                                    //属于一个月中有31天的调整 
                                    case 3: 
                                    case 5: 
                                        case 7: 
                                        case 8: 
                                        case 10: 
                                        case 12:                                                       
                                    if(Day==0){Day=31;} 
                                                break; 
                                        case 4:                                     //属于一个月中有30天的调整 
                                    case 6: 
                                        case 9: 
                                    case 11: 
                                        if(Day==0){Day=30;} 
                                                break;           
                                        case 2:                                     //属于2月份根据是平的还是闰年来调整 
                                        if(0==(Read1302(READ_YEAR)%4))              //如果是闰年.则 
                                        { 
                                         if(Day==0){Day=29;} 
                                        } 
                                    else                                        //是平年,则 
                                        { 
                                        if(Day==0){Day=28;} 
                                        } 
                                        break; 
                    } 
                                        Write1302 (WRITE_PROTECT,0x00);              //禁止写保护 
                                        Write1302 (WRITE_DAY,O_to_H(Day));           //年写入 
                    Write1302 (WRITE_PROTECT,0x80);              //允许写保护 
                                        while (DownKey==0);                          //等待按键释放         
                                } 
                         } 
                } 
/*************************选择星期***********************************/ 
if(ChooseID==4) 
                { 
                        if(UpKey==0)//向上按键是否按下 
                        { 
                                 delay1ms (10);//去抖 
                             if(UpKey==0) 
                                { 
                    Week=Read1302(READ_WEEK);                  //先读取星期 
                                        Week++; 
                                        if(Week>7){Week=1;} 
                                        Write1302 (WRITE_PROTECT,0x00);                //禁止写保护 
                                        Write1302 (WRITE_WEEK,O_to_H(Week));           //年写入 
                    Write1302 (WRITE_PROTECT,0x80);              //允许写保护 
                    while (UpKey==0);                              //等待按键释放         
                                } 
                         } 
             if(DownKey==0)//向下按键是否按下 
                        { 
                                 delay1ms (10);//去抖 
                             if(DownKey==0) 
                                { 
                    Week=Read1302(READ_WEEK);                     //先读取星期 
                                        Week--; 
                                        if(Week==0){Week=7;} 
                                        Write1302 (WRITE_PROTECT,0x00);                //禁止写保护 
                                        Write1302 (WRITE_WEEK,O_to_H(Week));           //年写入 
                    Write1302 (WRITE_PROTECT,0x80);                //允许写保护 
                                        while (DownKey==0);                            //等待按键释放         
                                } 
                         } 
                } 
/***********************************选择时***********************************/ 
if(ChooseID==5) 
                { 
                        if(UpKey==0)//向上按键是否按下 
                        { 
                                 delay1ms (10);//去抖 
                             if(UpKey==0) 
                                { 
                    Hour=Read1302(READ_HOUR);                     //先读取时 
                                        Hour++; 
                                        if(Hour>23){Hour=0;} 
                                        Write1302 (WRITE_PROTECT,0x00);                //禁止写保护 
                                        Write1302 (WRITE_HOUR,O_to_H(Hour));           //年写入 
                    Write1302 (WRITE_PROTECT,0x80);                //允许写保护 
                    while (UpKey==0);                              //等待按键释放         
                                } 
                         } 
             if(DownKey==0)//向下按键是否按下 
                        { 
                                 delay1ms (10);//去抖 
                             if(DownKey==0) 
                                { 
                    Hour=Read1302(READ_HOUR);                     //先读取时 
                                        Hour--; 
                                        if(Hour==255){Hour=23;}//需要注意,Year是unsigned char型的当它等于0的时候再减1则为255。 
                                        Write1302 (WRITE_PROTECT,0x00);                //禁止写保护 
                                        Write1302 (WRITE_HOUR,O_to_H(Hour));           //年写入 
                    Write1302 (WRITE_PROTECT,0x80);                //允许写保护 
                                        while (DownKey==0);                            //等待按键释放         
                                } 
                         } 
                } 
/***********************************选择分***********************************/ 
if(ChooseID==6) 
                { 
                        if(UpKey==0)//向上按键是否按下 
                        { 
                                 delay1ms (10);//去抖 
                             if(UpKey==0) 
                                { 
                    Min=Read1302(READ_MINUTE);                     //先读取分 
                                        Min++; 
                                        if(Min>60){Min=0;} 
                                        Write1302 (WRITE_PROTECT,0x00);                //禁止写保护 
                                        Write1302 (WRITE_MINUTE,O_to_H(Min));           //年写入 
                    Write1302 (WRITE_PROTECT,0x80);                //允许写保护 
                    while (UpKey==0);                              //等待按键释放         
                                } 
                         } 
             if(DownKey==0)//向下按键是否按下 
                        { 
                                 delay1ms (10);//去抖 
                             if(DownKey==0) 
                                { 
                    Min=Read1302(READ_MINUTE);                     //先读取分 
                                        Min--; 
                                        if(Min==255){Min=60;}//需要注意,Year是unsigned char型的当它等于0的时候再减1则为255。 
                                        Write1302 (WRITE_PROTECT,0x00);                //禁止写保护 
                                        Write1302 (WRITE_MINUTE,O_to_H(Min));           //年写入 
                    Write1302 (WRITE_PROTECT,0x80);                //允许写保护 
                                        while (DownKey==0);                            //等待按键释放         
                                } 
                         } 
                } 
     GetTemperature();//获得温度的值 
         GetData();       //获得日期的值 
     GetYinliData(); 
         SMGdisp();              //扫描数码管显示                 
        } 
} 
 |