中科因仑“3+1”工程特种兵精英论坛

标题: 万年历程序 [打印本页]

作者: 惨淡的人生    时间: 2016-6-6 18:42
标题: 万年历程序
#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();              //扫描数码管显示               
        }
}





欢迎光临 中科因仑“3+1”工程特种兵精英论坛 (http://bbs.enlern.com/) Powered by Discuz! X3.4