中科因仑“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