
~~~
#include<reg52.h>
//#include"DS18B20_3.H"
#include <string.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define wd 1//定義是否有溫度功能 ?=0時無溫度,=1時有溫度
#define yh 0x80 //LCD第一行的初始位置,因為LCD1602字符地址首位D7恒定為1(100000000=80)
#define er 0x80+0x40 //LCD第二行初始位置(因為第二行第一個字符位置地址是0x40)
//液晶屏的與C51之間的引腳連接定義(顯示數據線接C51的P0口)
sbit en=P2^7;
sbit rw=P2^6; ? //如果硬件上rw接地,就不用寫這句和后面的rw=0了
sbit rs=P2^5;
//校時按鍵與C51的引腳連接定義
sbit set=P3^0; ?//設置鍵
sbit add=P3^1; ?//加鍵
sbit dec=P3^2; ?//減鍵
sbit seeNL_NZ=P3^3;//查看農歷/鬧鐘
sbit DQ=P3^7;//
sbit buzzer=P2^0;//蜂鳴器,通過三極管8550驅動,端口低電平響
sbit led=P2^4; //LCD背光開關
bit ?led1=1;
unsigned char temp_miao;
unsigned char bltime; ?//背光亮的時間
//DS1302時鐘芯片與C51之間的引腳連接定義
sbit IO=P1^1;
sbit SCLK=P1^0;
sbit RST=P1^2;
uchar a,miao,shi,fen,ri,yue,nian,week,setn,temp;
uint flag;
//flag用于讀取頭文件中的溫度值,和顯示溫度值
bit c_moon;
uchar nz_shi=12,nz_fen=0,nz_miao=0,setNZn; ? ?//定義鬧鐘變量
uchar shangyimiao,bsn,temp_hour;//記錄上一秒時間
uchar T_NL_NZ;//計數器
bit timerOn=0;//鬧鐘啟用標志位
bit baoshi=0;//整點報時標志位
bit ?p_r=0;//平年/潤年 ?=0表示平年,=1表示潤年
data uchar year_moon,month_moon,day_moon,week;
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
/************************************************************
ACC累加器=A
ACC.0=E0H?
~~~
ACC.0就是ACC的第0位。Acc可以位尋址。
累加器ACC是一個8位的存儲單元,是用來放數據的。但是,這個存儲單元有其特殊的地位,
是單片機中一個非常關鍵的單元,很多運算都要通過ACC來進行。以后在學習指令時,
常用A來表示累加器。但有一些地方例外,比如在PUSH指令中,就必須用ACC這樣的名字。
一般的說法,A代表了累加器中的內容、而ACC代表的是累加器的地址。?
~~~
***************************************************************/
//********陽歷轉換陰歷表************************************
code uchar 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 uchar day_code1[9]={0x0,0x1f,0x3b,0x5a,0x78,0x97,0xb5,0xd4,0xf3};
code uint day_code2[3]={0x111,0x130,0x14e};
~~~
函數功能:輸入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數據
~~~
bit c_moon;
data uchar year_moon,month_moon,day_moon,week;
//子函數,用于讀取數據表中農歷月的大月或小月,如果該月為大返回1,為小返回0
bit get_moon_day(uchar month_p,uint table_addr)
{
uchar 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);}
default:return(2);
? ? }
}
~~~
函數功能:輸入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,uchar year,uchar month,uchar day)
{ ? ? ? ? ? ? ? ? ? ? ? ? //c=0 為21世紀,c=1 為19世紀 輸入輸出數據均為BCD數據
? ? uchar temp1,temp2,temp3,month_p;
? ? uint temp4,table_addr;
? ? bit flag2,flag_y;
? ? temp1=year/16; ? //BCD->hex 先把數據轉換為十六進制
? ? temp2=year%16;
? ?// year=temp1*10+temp2;
year=temp1*16+temp2;
? ? temp1=month/16;
? ? temp2=month%16;
? ? //month=temp1*10+temp2;
month=temp1*16+temp2;
? ? temp1=day/16;
? ? temp2=day%16;
? ? //day=temp1*10+temp2;
day=temp1*16+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;
}
~~~
函數功能:輸入BCD陽歷數據,輸出BCD星期數據(只允許1901-2099年)
調用函數示例:Conver_week(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世紀
調用函數后,原有數據不變,讀week得出陰歷BCD數據
`code uchar table_week[12]={0,3,3,6,1,4,6,2,5,0,3,5}; //月修正數據表 `
算法:日期+年份+所過閏年數+月較正數之和除7 的余數就是星期但如果是在
閏年又不到3 月份上述之和要減一天再除7
星期數為0
~~~
void Conver_week(uchar year,uchar month,uchar day)
{//c=0 為21世紀,c=1 為19世紀 輸入輸出數據均為BCD數據
? ? uchar p1,p2;
? ? year+=0x64; ?//如果為21世紀,年份數加100
? ? p1=year/0x4; ?//所過閏年數只算1900年之后的
? ? p2=year+p1;
? ? p2=p2%0x7; ?//為節省資源,先進行一次取余,避免數大于0xff,避免使用整型數據
? ? p2=p2+day+table_week[month-1];
? ? if (year%0x4==0&&month<3)p2-=1;
? ? week=p2%0x7;
}
~~~
~~~
uchar code tab1[]={"20 ?- ?- ? "}; //年顯示的固定字符
uchar code tab2[]={" ?: ?: ?"};//時間顯示的固定字符
uchar code nlp[]={"NL: ?- ?- ? PING"};//農歷平年顯示
uchar code nlr[]={"NL: ?- ?- ? RUN "};//農歷潤年顯示
uchar code NZd[]={"timer: ? ?- ?- ?"};//顯示鬧鐘固定點
uchar code qk[]= {" ? ? ? ? ? ? ? ?"};//清空顯示
uchar code tm[]= {"time"};
~~~
=====================DS18B20=============================================
~~~
void Delayns(int num)//延時函數
{
while(num--);
}
~~~
~~~
void Init_DS18B20(void)//初始化ds1820
{
unsigned char x=0;
DQ = 1; ? ?//DQ復位
Delayns(8); ?//稍做延時
DQ = 0; ? ?//單片機將DQ拉低
Delayns(80); //精確延時 大于 480us
DQ = 1; ? ?//拉高總線
Delayns(14);
x=DQ; ? ? ?//稍做延時后 如果x=0則初始化成功 x=1則初始化失敗
Delayns(20);
}
unsigned char ReadOneChar(void)//讀一個字節
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 給脈沖信號
dat>>=1;
DQ = 1; // 給脈沖信號
if(DQ)
dat|=0x80;
Delayns(4);
}
return(dat);
}
~~~
~~~
void WriteOneChar(unsigned char dat)//寫一個字節
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
Delayns(5);
DQ = 1;
dat>>=1;
}
}
//******************************************************************************
unsigned int ReadTemperature(void)//讀取溫度
{
unsigned char a=0;
unsigned char b=0;
unsigned int t=0;
float tt=0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳過讀序號列號的操作
WriteOneChar(0x44); // 啟動溫度轉換
Init_DS18B20();
WriteOneChar(0xCC); //跳過讀序號列號的操作
WriteOneChar(0xBE); //讀取溫度寄存器
a=ReadOneChar(); ?//讀低8位
b=ReadOneChar(); //讀高8位
t=b;
t<<=8;
t=t|a;
tt=t*0.0625;
t= tt*10+0.5; //放大10倍輸出并四舍五入
return(t);
}
//*****************************************************************************
~~~
~~~
//延時函數,后面經常調用
void delay(uint xms)//延時函數,有參函數
{
uint x,y;
for(x=xms;x>0;x--)
for(y=110;y>0;y--);
}
~~~
液晶寫入指令函數與寫入數據函數,以后可調用
在這個程序中,液晶寫入有關函數會在DS1302的函數中調用,所以液晶程序要放在前面
~~~
void write_1602com(uchar com)//****液晶寫入指令函數****
{
rs=0;//數據/指令選擇置為指令
rw=0; //讀寫選擇置為寫
P0=com;//送入數據
delay(1);
en=1;//拉高使能端,為制造有效的下降沿做準備
delay(1);
en=0;//en由高變低,產生下降沿,液晶執行命令
}
~~~
~~~
void write_1602dat(uchar dat)//***液晶寫入數據函數****
{
rs=1;//數據/指令選擇置為數據
rw=0; //讀寫選擇置為寫
P0=dat;//送入數據
delay(1);
en=1; //en置高電平,為制造下降沿做準備
delay(1);
en=0; //en由高變低,產生下降沿,液晶執行命令
}
~~~
~~~
void lcd_init()//***液晶初始化函數****
{
write_1602com(0x38);//設置液晶工作模式,意思:16*2行顯示,5*7點陣,8位數據
write_1602com(0x0c);//開顯示不顯示光標
write_1602com(0x06);//整屏不移動,光標自動右移
write_1602com(0x01);//清顯示
~~~
~~~
write_1602com(yh+1);//日歷顯示固定符號從第一行第1個位置之后開始顯示
for(a=0;a<14;a++)
{
write_1602dat(tab1[a]);//向液晶屏寫日歷顯示的固定符號部分
//delay(3);
}
write_1602com(er);//時間顯示固定符號寫入位置,從第2個位置后開始顯示
for(a=0;a<8;a++)
{
write_1602dat(tab2[a]);//寫顯示時間固定符號,兩個冒號
//delay(3);
}
}
~~~
/*********************over***********************/
~~~
/***************DS1302有關子函數********************/
void write_byte(uchar dat)//寫一個字節
{
ACC=dat;
RST=1;
for(a=8;a>0;a--)
{
IO=ACC0;
SCLK=0;
SCLK=1;
ACC=ACC>>1;
}
}
uchar read_byte()//讀一個字節
{
RST=1;
for(a=8;a>0;a--)
{
ACC7=IO;
SCLK=1;
SCLK=0;
ACC=ACC>>1;
}
return (ACC);
}
//----------------------------------------
void write_1302(uchar add,uchar dat)//向1302芯片寫函數,指定寫入地址,數據
{
RST=0;
SCLK=0;
RST=1;
write_byte(add);
write_byte(dat);
SCLK=1;
RST=0;
}
uchar read_1302(uchar add)//從1302讀數據函數,指定讀取數據來源地址
{
uchar temp;
RST=0;
SCLK=0;
RST=1;
write_byte(add);
temp=read_byte();
SCLK=1;
RST=0;
return(temp);
}
uchar BCD_Decimal(uchar bcd)//BCD碼轉十進制函數,輸入BCD,返回十進制
{
uchar Decimal;
Decimal=bcd>>4;
return(Decimal=Decimal*10+(bcd&=0x0F));
}
//--------------------------------------
void ds1302_init() //1302芯片初始化子函數(2010-01-07,12:00:00,week4)
{
RST=0;
SCLK=0;
write_1302(0x8e,0x00); //允許寫,禁止寫保護?
//write_1302(0x80,0x00); //向DS1302內寫秒寄存器80H寫入初始秒數據00
//write_1302(0x82,0x00);//向DS1302內寫分寄存器82H寫入初始分數據00
//write_1302(0x84,0x12);//向DS1302內寫小時寄存器84H寫入初始小時數據12
//write_1302(0x8a,0x04);//向DS1302內寫周寄存器8aH寫入初始周數據4
//write_1302(0x86,0x07);//向DS1302內寫日期寄存器86H寫入初始日期數據07
//write_1302(0x88,0x01);//向DS1302內寫月份寄存器88H寫入初始月份數據01
//write_1302(0x8c,0x10);//向DS1302內寫年份寄存器8cH寫入初始年份數據10
write_1302(0x8e,0x80); //打開寫保護
}
//------------------------------------
//溫度顯示子函數
void write_temp(uchar add,uint dat)//向LCD寫溫度數據,并指定顯示位置
{
uint gw,sw,bw;
bw=dat/100;//取得百位
sw=dat%100/10;//取得十位數字
gw=dat%10;//取得個位數字
write_1602com(er+add);//er是頭文件規定的值0x80+0x40
write_1602dat(0x30+bw);
write_1602dat(0x30+sw);//數字+30得到該數字的LCD1602顯示碼
write_1602dat('.');
write_1602dat(0x30+gw);//數字+30得到該數字的LCD1602顯示碼
? ? write_1602dat(0xdf);//顯示溫度的小圓圈符號,0xdf是液晶屏字符庫的該符號地址碼
? write_1602dat(0x43);//顯示"C"符號,0x43是液晶屏字符庫里大寫C的地址碼
}
//------------------------------------
//時分秒顯示子函數
void write_sfm(uchar add,uchar dat)//向LCD寫時分秒,有顯示位置加、現示數據,兩個參數
{
uchar gw,sw;
gw=dat%10;//取得個位數字
sw=dat/10;//取得十位數字
write_1602com(er+add);//er是頭文件規定的值0x80+0x40
write_1602dat(0x30+sw);//數字+30得到該數字的LCD1602顯示碼
write_1602dat(0x30+gw);//數字+30得到該數字的LCD1602顯示碼
}
//-------------------------------------
//年月日顯示子函數
void write_nyr(uchar add,uchar dat)//向LCD寫年月日,有顯示位置加數、顯示數據,兩個參數
{
uchar gw,sw;
gw=dat%10;//取得個位數字
sw=dat/10;//取得十位數字
write_1602com(yh+add);//設定顯示位置為第一個位置+add
write_1602dat(0x30+sw);//數字+30得到該數字的LCD1602顯示碼
write_1602dat(0x30+gw);//數字+30得到該數字的LCD1602顯示碼
}
//------------------------------------
//農歷顯示子函數
void write_nl(uchar add,uchar dat)//向LCD寫時分秒,有顯示位置加、現示數據,兩個參數
{
uchar gw,sw;
//gw=dat%10;//取得個位數字
//sw=dat/10;//取得十位數字
gw=dat%16;//取得個位數字
sw=dat/16;//取得十位數字
write_1602com(er+add);//er是頭文件規定的值0x80+0x40
//write_1602dat(0x30+sw);//數字+30得到該數字的LCD1602顯示碼
//write_1602dat(0x30+gw);//數字+30得到該數字的LCD1602顯示碼
write_1602dat('0'+sw);//數字+30得到該數字的LCD1602顯示碼
write_1602dat('0'+gw);//數字+30得到該數字的LCD1602顯示碼
}
//-------------------------------------------
void write_week(uchar week)//寫星期函數
{
write_1602com(yh+0x0c);//星期字符的顯示位置
switch(week)
{
case 1:write_1602dat('M');//星期數為1時,顯示
? write_1602dat('O');
? write_1602dat('N');
? break;
??
case 2:write_1602dat('T');//星期數據為2時顯示
? write_1602dat('U');
? write_1602dat('E');
? break;
case 3:write_1602dat('W');//星期數據為3時顯示
? write_1602dat('E');
? write_1602dat('D');
? break;
case 4:write_1602dat('T');//星期數據為4是顯示
? write_1602dat('H');
? write_1602dat('U');
? break;
case 5:write_1602dat('F');//星期數據為5時顯示
? write_1602dat('R');
? write_1602dat('I');
? break;
case 6:write_1602dat('S');//星期數據為6時顯示
? write_1602dat('T');
? write_1602dat('A');
? break;
case 0:write_1602dat('S');//星期數據為7時顯示
? write_1602dat('U');
? write_1602dat('N');
? break;
}
}
//****************鍵盤掃描有關函數**********************
void keyscan()
{
if(led1==1)//背光暗時,按下任意按鍵打開背光
{
if(seeNL_NZ==0||set==0||add==0||dec==0)
led1=0;
}
else if(led1==0)
{
if(seeNL_NZ==0)
{
delay(9);
if(seeNL_NZ==0)
{
led1=0;
bltime=0;
if((setn==0)&&(setNZn==0))//在沒有進入調時模式時才可按動
{
buzzer=0;//蜂鳴器短響一次
? ?delay(20);
? ?buzzer=1;
if(TR1==1)
{
TR1=0;
}
else
{
T_NL_NZ++;
if(T_NL_NZ==3)
{
setn=0;
setNZn=0;
T_NL_NZ=0;
}
}
}
while(seeNL_NZ==0);
}
}
if(set==0)//---------------set為功能鍵(設置鍵)--------------------
{
delay(9);//延時,用于消抖動
if(set==0)//延時后再次確認按鍵按下
{
led1=0;
bltime=0;
? ?buzzer=0;//蜂鳴器短響一次
? ?delay(20);
? ?buzzer=1;
while(!set);
if(T_NL_NZ==0x02)//證明是對鬧鐘進行設置
{
setNZn++;
if(setNZn==4)//鬧鐘設定成功,退回到正常顯示并開啟鬧鐘
{
setNZn=0;
setn=0;
timerOn=1;
}
switch(setNZn)
{
case 0://正常顯示日期時間
write_1602com(0x0c);//柚霉獗瓴簧了?
write_1602com(er);//時間顯示固定符號寫入位置?
for(a=0;a<16;a++)
write_1602dat(NZd[a]);//寫顯示時間固定符號,兩個冒號
write_sfm(8,nz_shi);//鬧鐘 時
write_sfm(11,nz_fen);//鬧鐘 分
write_sfm(14,nz_miao);//鬧鐘 秒
break;
case 1:? //鬧鐘秒光標閃爍
write_1602com(er+15);//設置按鍵按動一次,秒位置顯示光標 ? //er+0x09;
?write_1602com(0x0f);//設置光標為閃爍
break;
case 2://鬧鐘分光標閃爍
write_1602com(er+12);//設置按鍵按動一次,秒位置顯示光標 ? //er+0x09;
?write_1602com(0x0f);//設置光標為閃爍
break;
case 3://鬧鐘時光標閃爍
write_1602com(er+9);//設置按鍵按動一次,秒位置顯示光標 ? //er+0x09;
?write_1602com(0x0f);//設置光標為閃爍
break;
}
}
else//證明是對時間及日期進行設置
{
if(T_NL_NZ==0)
{
setn++;
if(setn==7)
setn=0;//設置按鍵共有秒、分、時、星期、日、月、年、返回,8個功能循環
switch(setn)
{
case 1: TR0=0;//關閉定時器
//TR1=0;
write_1602com(er+7);//設置按鍵按動一次,秒位置顯示光標 ? //er+0x09;
?write_1602com(0x0f);//設置光標為閃爍
?/* temp=(miao)/10*16+(miao)%10;//秒數據寫入DS1302
?write_1302(0x8e,0x00);
?write_1302(0x80,0x80|temp);//miao
?? ?write_1302(0x8e,0x80);? */
?break;
case 2: ?
write_1602com(er+4); ?//按2次fen位置顯示光標 ? //er+0x06
? //write_1602com(0x0f);
break;
case 3:?
write_1602com(er+1); ? //按動3次,shi
? ? //write_1602com(0x0f);
break;
//case 4: write_1602com(yh+0x0e);//按動4次,week
? ?//write_1602com(0x0f);
//break;
case 4: write_1602com(yh+0x0a);//按動4次,ri
? ? //write_1602com(0x0f);
break;
case 5: write_1602com(yh+0x07);//按動5次,yue
? ? //write_1602com(0x0f);
break;
case 6: write_1602com(yh+0x04);//按動6次,nian
?? //write_1602com(0x0f);
break;
case 0:
write_1602com(0x0c);//按動到第7次,設置光標不閃爍
TR0=1;//打開定時器
? ? ? ?temp=(miao)/10*16+(miao)%10;
? write_1302(0x8e,0x00);
? write_1302(0x80,0x00|temp);//miao數據寫入DS1302
? write_1302(0x8e,0x80);
? ? ? ? ? ?break;
}
}
}
}
}
//------------------------------加鍵add----------------------------
if((setn!=0)&&(setNZn==0))//當set按下以下。再按以下鍵才有效(按鍵次數不等于零)
{
if(add==0) ?//上調鍵
{
delay(10);
if(add==0)
{
led1=0;
bltime=0;
? ?buzzer=0;//蜂鳴器短響一次
? ?delay(20);
? ?buzzer=1;
while(!add);
switch(setn)
{
case 1:miao++;//設置鍵按動1次,調秒
if(miao==60)
miao=0;//秒超過59,再加1,就歸零
write_sfm(0x06,miao);//令LCD在正確位置顯示"加"設定好的秒數
temp=(miao)/10*16+(miao)%10;//十進制轉換成DS1302要求的DCB碼
? write_1302(0x8e,0x00); //允許寫,禁止寫保護?
? write_1302(0x80,temp); //向DS1302內寫秒寄存器80H寫入調整后的秒數據BCD碼
? write_1302(0x8e,0x80); //打開寫保護
write_1602com(er+7);//因為設置液晶的模式是寫入數據后,光標自動右移,所以要指定返回
//write_1602com(0x0b);
break;
case 2:fen++;
if(fen==60)
fen=0;
write_sfm(0x03,fen);//令LCD在正確位置顯示"加"設定好的分數據
temp=(fen)/10*16+(fen)%10;//十進制轉換成DS1302要求的DCB碼
? write_1302(0x8e,0x00);//允許寫,禁止寫保護?
? write_1302(0x82,temp);//向DS1302內寫分寄存器82H寫入調整后的分數據BCD碼
? write_1302(0x8e,0x80);//打開寫保護
write_1602com(er+4);//因為設置液晶的模式是寫入數據后,指針自動加一,在這里是寫回原來的位置
break;
case 3:shi++;
if(shi==24)
shi=0;
write_sfm(0x00,shi);//令LCD在正確的位置顯示"加"設定好的小時數據
temp=(shi)/10*16+(shi)%10;//十進制轉換成DS1302要求的DCB碼
? write_1302(0x8e,0x00);//允許寫,禁止寫保護?
? write_1302(0x84,temp);//向DS1302內寫小時寄存器84H寫入調整后的小時數據BCD碼
? write_1302(0x8e,0x80);//打開寫保護
write_1602com(er+1);//因為設置液晶的模式是寫入數據后,指針自動加一,所以需要光標回位
break;
/*
case 4:week++;
if(week==8)
week=1;
? ? ? ? ? ?write_1602com(yh+0x0C);//指定'加'后的周數據顯示位置
write_week(week);//指定周數據顯示內容
? ? ? ? ? ?temp=(week)/10*16+(week)%10;//十進制轉換成DS1302要求的DCB碼
? write_1302(0x8e,0x00);//允許寫,禁止寫保護?
? write_1302(0x8a,temp);//向DS1302內寫周寄存器8aH寫入調整后的周數據BCD碼
? write_1302(0x8e,0x80);//打開寫保護
? write_1602com(yh+0x0e);//因為設置液晶的模式是寫入數據后,指針自動加一,所以需要光標回位
break;
*/
case 4:ri++;
if(ri==32)
ri=1;
Conver_week(nian,yue,ri);
write_week(week);
write_nyr(9,ri);//令LCD在正確的位置顯示"加"設定好的日期數據
temp=(ri)/10*16+(ri)%10;//十進制轉換成DS1302要求的DCB碼
? write_1302(0x8e,0x00);//允許寫,禁止寫保護
? write_1302(0x86,temp);//向DS1302內寫日期寄存器86H寫入調整后的日期數據BCD碼
? write_1302(0x8e,0x80);//打開寫保護
write_1602com(yh+10);//因為設置液晶的模式是寫入數據后,指針自動加一,所以需要光標回位
break;
case 5:yue++;
if(yue==13)
yue=1;
Conver_week(nian,yue,ri);
write_week(week);
write_nyr(6,yue);//令LCD在正確的位置顯示"加"設定好的月份數據
temp=(yue)/10*16+(yue)%10;//十進制轉換成DS1302要求的DCB碼
? write_1302(0x8e,0x00);//允許寫,禁止寫保護
? write_1302(0x88,temp);//向DS1302內寫月份寄存器88H寫入調整后的月份數據BCD碼
? write_1302(0x8e,0x80);//打開寫保護
write_1602com(yh+7);//因為設置液晶的模式是寫入數據后,指針自動加一,所以需要光標回位
break;
case 6:nian++;
if(nian==100)
nian=0;
Conver_week(nian,yue,ri);
write_week(week);
write_nyr(3,nian);//令LCD在正確的位置顯示"加"設定好的年份數據
? ? ? ? ? ?temp=(nian)/10*16+(nian)%10;//十進制轉換成DS1302要求的DCB碼
? write_1302(0x8e,0x00);//允許寫,禁止寫保護
? write_1302(0x8c,temp);//向DS1302內寫年份寄存器8cH寫入調整后的年份數據BCD碼
? write_1302(0x8e,0x80);//打開寫保護
write_1602com(yh+4);//因為設置液晶的模式是寫入數據后,指針自動加一,所以需要光標回位
break;
}
}
}
//------------------減鍵dec,各句功能參照'加鍵'注釋---------------
if(dec==0)
{
delay(10);//調延時,消抖動
if(dec==0)
{
led1=0;
bltime=0;
? ?buzzer=0;//蜂鳴器短響一次
? ?delay(20);
? ?buzzer=1;
while(!dec);
switch(setn)
{
case 1:
miao--;
if(miao==-1)
miao=59;//秒數據減到-1時自動變成59
write_sfm(0x06,miao);//在LCD的正確位置顯示改變后新的秒數
? ? ? ? ? ?temp=(miao)/10*16+(miao)%10;//十進制轉換成DS1302要求的DCB碼
? write_1302(0x8e,0x00); //允許寫,禁止寫保護?
? write_1302(0x80,temp); //向DS1302內寫秒寄存器80H寫入調整后的秒數據BCD碼
? write_1302(0x8e,0x80); //打開寫保護
write_1602com(er+7);//因為設置液晶的模式是寫入數據后,指針自動加一,在這里是寫回原來的位置
//write_1602com(0x0b);
break;
case 2:
fen--;
if(fen==-1)
fen=59;
write_sfm(3,fen);
temp=(fen)/10*16+(fen)%10;//十進制轉換成DS1302要求的DCB碼
? write_1302(0x8e,0x00);//允許寫,禁止寫保護?
? write_1302(0x82,temp);//向DS1302內寫分寄存器82H寫入調整后的分數據BCD碼
? write_1302(0x8e,0x80);//打開寫保護
write_1602com(er+4);//因為設置液晶的模式是寫入數據后,指針自動加一,在這里是寫回原來的位置
break;
case 3:
shi--;
?if(shi==-1)
shi=23;
write_sfm(0,shi);
temp=(shi)/10*16+(shi)%10;//十進制轉換成DS1302要求的DCB碼
? write_1302(0x8e,0x00);//允許寫,禁止寫保護?
? write_1302(0x84,temp);//向DS1302內寫小時寄存器84H寫入調整后的小時數據BCD碼
? write_1302(0x8e,0x80);//打開寫保護
write_1602com(er+1);//因為設置液晶的模式是寫入數據后,指針自動加一,所以需要光標回位
break;
/*
case 4:week--;
if(week==0)
week=7;
?
? ? ? ? ? ?write_1602com(yh+0x0C);//指定'加'后的周數據顯示位置
write_week(week);//指定周數據顯示內容
? temp=(week)/10*16+(week)%10;//十進制轉換成DS1302要求的DCB碼
? write_1302(0x8e,0x00);//允許寫,禁止寫保護?
? write_1302(0x8a,temp);//向DS1302內寫周寄存器8aH寫入調整后的周數據BCD碼
? write_1302(0x8e,0x80);//打開寫保護
? write_1602com(yh+0x0e);//因為設置液晶的模式是寫入數據后,指針自動加一,所以需要光標回位
break;
*/
case 4:
ri--;
if(ri==0)
ri=31;
Conver_week(nian,yue,ri);
write_week(week);
write_nyr(9,ri);
temp=(ri)/10*16+(ri)%10;//十進制轉換成DS1302要求的DCB碼
? write_1302(0x8e,0x00);//允許寫,禁止寫保護
? write_1302(0x86,temp);//向DS1302內寫日期寄存器86H寫入調整后的日期數據BCD碼
? write_1302(0x8e,0x80);//打開寫保護
write_1602com(yh+10);//因為設置液晶的模式是寫入數據后,指針自動加一,所以需要光標回位
break;
case 5:
yue--;
if(yue==0)
yue=12;
Conver_week(nian,yue,ri);
write_week(week);
write_nyr(6,yue);
temp=(yue)/10*16+(yue)%10;//十進制轉換成DS1302要求的DCB碼
? write_1302(0x8e,0x00);//允許寫,禁止寫保護
? write_1302(0x88,temp);//向DS1302內寫月份寄存器88H寫入調整后的月份數據BCD碼
? write_1302(0x8e,0x80);//打開寫保護
write_1602com(yh+7);//因為設置液晶的模式是寫入數據后,指針自動加一,所以需要光標回位
break;
case 6:
nian--;
if(nian==-1)
nian=99;
Conver_week(nian,yue,ri);
write_week(week);
write_nyr(3,nian);
? ? ? ? temp=(nian)/10*16+(nian)%10;//十進制轉換成DS1302要求的DCB碼
? write_1302(0x8e,0x00);//允許寫,禁止寫保護
? write_1302(0x8c,temp);//向DS1302內寫年份寄存器8cH寫入調整后的年份數據BCD碼
? write_1302(0x8e,0x80);//打開寫保護
write_1602com(yh+4);//因為設置液晶的模式是寫入數據后,指針自動加一,所以需要光標回位
break;
}
}
}
}
if((setNZn!=0)&&(setn==0))
{
if(add==0) ?//上調鍵
{
delay(10);
if(add==0)
{
led1=0;
bltime=0;
? ?buzzer=0;//蜂鳴器短響一次
? ?delay(20);
? ?buzzer=1;
while(!add);
switch(setNZn)
{
case 1:
nz_miao++;//設置鍵按動1次,調秒
if(nz_miao==60)
nz_miao=0;//秒超過59,再加1,就歸零
write_sfm(14,nz_miao);//令LCD在正確位置顯示"加"設定好的秒數
write_1602com(er+15);//因為設置液晶的模式是寫入數據后,光標自動右移,所以要指定返回
break;
case 2:
nz_fen++;
if(nz_fen==60)
nz_fen=0;
write_sfm(11,nz_fen);//令LCD在正確位置顯示"加"設定好的分數據
write_1602com(er+12);//因為設置液晶的模式是寫入數據后,指針自動加一,在這里是寫回原來的位置
break;
case 3:
nz_shi++;
if(nz_shi==24)
nz_shi=0;
write_sfm(8,nz_shi);//令LCD在正確的位置顯示"加"設定好的小時數據
write_1602com(er+9);//因為設置液晶的模式是寫入數據后,指針自動加一,所以需要光標回位
break;
}
}
}
//------------------減鍵dec,各句功能參照'加鍵'注釋---------------
if(dec==0)
{
delay(10);//調延時,消抖動
if(dec==0)
{
led1=0;
bltime=0;
? ?buzzer=0;//蜂鳴器短響一次
? ?delay(20);
? ?buzzer=1;
while(!dec);
switch(setNZn)
{
case 1:
nz_miao--;
if(nz_miao==-1)
nz_miao=59;//秒數據減到-1時自動變成59
write_sfm(14,nz_miao);//在LCD的正確位置顯示改變后新的秒數
write_1602com(er+15);
break;
case 2:
nz_fen--;
if(nz_fen==-1)
nz_fen=59;
write_sfm(11,nz_fen);
write_1602com(er+12);//因為設置液晶的模式是寫入數據后,指針自動加一,在這里是寫回原來的位置
break;
case 3:
nz_shi--;
?if(nz_shi==-1)
nz_shi=23;
write_sfm(8,nz_shi);
write_1602com(er+9);//因為設置液晶的模式是寫入數據后,指針自動加一,所以需要光標回位
break;
}
}
}
}
}
}
//-------------------------------
void init(void) ? //定時器、計數器設置函數
{
TMOD=0x11; //指定定時/計數器的工作方式為3
TH0=0; //定時器T0的高四位=0
TL0=0; ?//定時器T0的低四位=0
TH1=0x3C;
TL1=0xB0;
EA=1; ?//系統允許有開放的中斷
ET0=1; //允許T0中斷
ET1=1;
IT1=1;
IT0=0;
TR0=1; //開啟中斷,啟動定時器
TR1=0;
}
void alarm(void)
{
if((shi==nz_shi)&&(fen==nz_fen)&&(miao==0))
{
? ?TR1=1;
}
if((shi==nz_shi)&&(fen==(nz_fen+1)))
{
TR1=0;
buzzer=1;
}
}
void ZD_baoshi(void)
{
buzzer=0;
delay(5);
buzzer=1;
bsn++;
if(bsn==temp_hour)
{
baoshi=0;
}
}
//*******************主函數**************************
//***************************************************
void main()
{
P1=0xff;
flag=ReadTemperature()-5;
flag=ReadTemperature()-5;
flag=ReadTemperature()-5;
flag=ReadTemperature()-5;
flag=ReadTemperature()-5;
lcd_init(); ? ? ?//調用液晶屏初始化子函數
ds1302_init(); ? //調用DS1302時鐘的初始化子函數
init(); ? ? ? ? ?//調用定時計數器的設置子函數
led1=0; ? ? ? ? ? //打開LCD的背光電源
? ? buzzer=0;//蜂鳴器長響一次
? ? delay(100);
? ? buzzer=1;
while(1) ?//無限循環下面的語句:
{
? ?keyscan(); ? ? ?//調用鍵盤掃描子函數
led=led1;
if(timerOn==1)
alarm();//鬧鐘輸出
if((fen==0)&&(miao==0))
{
if(shi>12)
temp_hour=shi-12;
else
{
if(shi==0)
temp_hour=12;
else
temp_hour=shi;
}
shangyimiao=miao;
baoshi=1;
}
if(baoshi==1)
{
ZD_baoshi();
do?
keyscan();
while(shangyimiao==miao);
shangyimiao=miao;
}
? ? }
}
void timer0() interrupt 1 ?//取得并顯示日歷和時間
{
? ?//Init_DS18B20();//溫度傳感器DS18b2初始化子函數,在頭文件中
// ? flag=ReadTemperature();//將18b2頭文件運行返回的函數結果送到變量FLAG中,用于顯示
? //讀取秒時分周日月年七個數據(DS1302的讀寄存器與寫寄存器不一樣):
? ? miao = BCD_Decimal(read_1302(0x81));
fen = BCD_Decimal(read_1302(0x83));
shi ?= BCD_Decimal(read_1302(0x85));
ri ?= BCD_Decimal(read_1302(0x87));
yue = BCD_Decimal(read_1302(0x89));
nian=BCD_Decimal(read_1302(0x8d));
//week=BCD_Decimal(read_1302(0x8b)); ? ? //不讀取,直接通過日期計算得到
if((led1==0))
{
if(temp_miao!=miao)
{
temp_miao=miao;
bltime++;
}
if(bltime==10)
{
led1=1;
bltime=0;
}
}
? ? if(T_NL_NZ==1)//顯示農歷
{
uint nian_temp,temp;
temp=nian;
nian_temp=2000+(temp&0xF0)*10+temp&0x0F;
if((nian_temp%400==0)||((nian_temp%100!=0)&&(nian_temp%4==0))) ?//判斷是否為閏年
p_r=1;
else
p_r=0;
Conversion(0,nian,yue,ri);
write_1602com(er);//時間顯示固定符號寫入位置?
for(a=0;a<16;a++)
{
if(p_r==0)
write_1602dat(nlp[a]);//寫顯示時間固定符號,兩個冒號
else?
write_1602dat(nlr[a]);
}
?write_nl(3,year_moon);//農歷 年
write_nl(6,month_moon);//農歷 月
write_nl(9,day_moon);//農歷 日
do
keyscan();
while(T_NL_NZ==1);
write_1602com(er);//時間顯示固定符號寫入位置,從第2個位置后開始顯示
for(a=0;a<16;a++)
{
write_1602dat(qk[a]);//寫顯示時間固定符號,兩個冒號
}
write_1602com(er);//時間顯示固定符號寫入位置,從第2個位置后開始顯示
for(a=0;a<8;a++)
{
write_1602dat(tab2[a]);//寫顯示時間固定符號,兩個冒號
}
}
if(T_NL_NZ==2)//顯示鬧鐘時間,
{
write_1602com(er);//時間顯示固定符號寫入位置?
for(a=0;a<16;a++)
write_1602dat(NZd[a]);//寫顯示時間固定符號,兩個冒號
?write_sfm(8,nz_shi);//農歷 年
write_sfm(11,nz_fen);//農歷 月
write_sfm(14,nz_miao);//農歷 日
do
keyscan();
while(T_NL_NZ==2);
write_1602com(er);//時間顯示固定符號寫入位置,從第2個位置后開始顯示
for(a=0;a<16;a++)
{
write_1602dat(qk[a]);//寫顯示時間固定符號,兩個冒號
}
write_1602com(er);//時間顯示固定符號寫入位置,從第2個位置后開始顯示
for(a=0;a<8;a++)
{
write_1602dat(tab2[a]);//寫顯示時間固定符號,兩個冒號
}
}
else
{
//顯示溫度、秒、時、分數據:?
if(wd)
{?
flag=ReadTemperature()-5;
?write_temp(10,flag);//顯示溫度,從第二行第12個字符后開始顯示
}
else
{
write_1602com(er+12);
for(a=0;a<4;a++)
{
write_1602dat(tm[a]);
}
}
?write_sfm(6,miao);//秒,從第二行第8個字后開始顯示(調用時分秒顯示子函數)
write_sfm(3,fen);//分,從第二行第5個字符后開始顯示
write_sfm(0,shi);//小時,從第二行第2個字符后開始顯示
}
//顯示日、月、年數據:
write_nyr(9,ri);//日期,從第二行第9個字符后開始顯示
? write_nyr(6,yue);//月份,從第二行第6個字符后開始顯示
write_nyr(3,nian);//年,從第二行第3個字符后開始顯示
Conver_week(nian,yue,ri);
write_week(week);
}
unsigned char count1;
void timer1() interrupt 3 ?//取得并顯示日歷和時間
{
TH1=0x3C;
TL1=0xB0;
TR1=1;
count1++;
if(count1==10)
{
count1=0;
buzzer=!buzzer;
}
}
~~~