一个计算万年历的简单程序
万年历程序

•/*********************************************************************************** *************•C51写的公历转农历,并驱动LCM-12864汉字液晶显示。
•author: cth•本程序参考了网上部分程序,在这里感谢所有无私奉献的朋友!•全程注释,有耐心就慢慢看!•************************************************************************************ ************/••#include <reg52.h>•#include <intrins.h>•#include <stdio.h>•#define uint unsigned int•#define uchar unsigned char•char sec,min,hour,day,month,year,week; //定义全局变量,秒,分,时,日,月,年和星期•bit century; //定义世纪位:0为20世纪,1为19世纪。
•//此时初始日期为2006年8月13日,即此程序完成日期!••/**************************************C51写的公历转农历和星期•**************************************••公历是全世界通用的历法以地球绕太阳的一周为一年一年365 天分为12 个月1 3 5 7 8 10 12 月为•31 天2 月为28 天其余月份为30 天事实上地球绕太阳一周共365 天5 小时48 分46 秒比公历一年多出5 小时48•分46 秒为使年误差不累积公历年用闰年法来消除年误差由于每年多出5 小时48 分46 秒每4 年累计多出23•小时15 分4 秒接近1 天天文学家就规定每4 年有一个闰年把2 月由28 天改为29 天凡是公历年代能被4 整除•的那一年就是闰年但是这样一来每4 年又少了44 分56 秒为了更准确地计时天文学家又规定凡能被100 整除•的年份只有能被400 整除才是闰年即每400 年要减掉3 个闰年经过这样处理后实际上每400 年的误差只有2 小时•53 分20 秒已相当准确了•农历与公历不同农历把月亮绕地球一周作为一月因为月亮绕地球一周不是一整天所以农历把月分为大月和小•月大月30 天小月29 天通过设置大小月使农历日始终与月亮与地球的位置相对应为了使农历的年份与公历年•相对应农历通过设置闰月的办法使它的平均年长度与公历年相等农历是中国传统文化的代表之一并与农业生产联•系密切中国人民特别是广大农民十分熟悉并喜爱农历•公历与农历是我国目前并存的两种历法各有其固有的规律农历与月球的运行相对应其影响因素多它的大小•月和闰月与天体运行有关计算十分复杂且每年都不一致因此要用单片机实现公历与农历的转换用查表法是最方•便实用的办法•51 系列单片机因其在功能上能满足大部份对速度要求不高的应用场合的要求且价格低廉开发工具普及程度高•是目前应用最多的单片机之一本文介绍一种用51 单片机实现从1901 年到2099 年2199 年公历日到农历日及星期•的转换方法并向读者提供完整的51C程序•二基本原理•实现公历与农历的转换一般采用查表法按日查表是速度最快的方法但51 单片机寻址能力有限不可能采用•按日查表的方法除按日查外我们可以通过按月查表和按年查表的方法再通过适当的计算来确定公历日所对应的•农历日期本文采用的是按年查表法最大限度地减少表格所占的程序空间•对于农历月来说大月为30 天小月为29 天这是固定不变的这样我们就可用1 个BIT 位来表示大小月信•息农历一年如有闰月为13 个月否则是12 个月所以一年需要用13 个BIT 闰月在农历年中所在的月份并不固定•大部分闰月分布在农历2 8 月但也有少量年份在9 月以后所以要表示闰月的信息至少要4BIT 在这里我们用4BIT•的值来表示闰月的月份值为0 表示本年没有闰月有了以上信息还不足以判断公历日对应的农历日因为还需要一•个参照日我们选用农历正月初一所对应的公历日期作参照日公历日最大为31 日需要5BIT 来表示而春节所在的•月份不是1 月就是2 月用1BIT 就够了考虑到表达方便我们用2BIT 来表示春节月2BIT 的值直接表示月份这•样一年的农历信息只用3 个字节就全部包括了•计算公历日对应的农历日期的方法先计算出公历日离当年元旦的天数然后查表取得当年的春节日期计算出春•节离元旦的天数二者相减即可算出公历日离春节的天数以后只要根据大小月和闰月信息减一月天数调整一月农•历月份即可推算出公历日所对应的农历日期如公历日不到春节日期农历年要比公历年小一年农历大小月取前一•年的信息农历月从12 月向前推算•公历日是非常有规律的所以公历日所对应的星期天可以通过计算直接得到理论上公元0 年1 月1 日为星期日•只要求得公历日离公元0 年1 月1 日的日子数除7 后的余数就是星期天为了简化计算采用月校正法根据公历的•年月日可直接计算出星期天其算法是日期年份所过闰年数月校正数之和除7 的余数就是星期天但如果是在•闰年又不到3 月份上述之和要减一天再除7 其1 12 月的校正数据为6 2 2 5 0 3 5 1 4 6 2 4 在•本程序中采用1 个字节表示年份闰年数也只计算1900 年以后的闰年数所以实际校正数据也和上述数据不同••••公历年对应的农历数据,每年三字节,•格式第一字节BIT7-4 位表示闰月月份,值为0 为无闰月,BIT3-0 对应农历第1-4 月的大小•第二字节BIT7-0 对应农历第5-12 月大小,第三字节BIT7 表示农历第13 个月大小•月份对应的位为1 表示本农历月大(30 天),为0 表示小(29 天)•第三字节BIT6-5 表示春节的公历月份,BIT4-0 表示春节的公历日期•************************************************************************************ *************/•code uchar year_code[597]={• 0x04,0xAe,0x53, //1901• 0x0A,0x57,0x48, //1902• 0x55,0x26,0xBd, //1903• 0x0d,0x26,0x50, //1904• 0x0d,0x95,0x44, //1905• 0x46,0xAA,0xB9, //1906• 0x05,0x6A,0x4d, //1907• 0x09,0xAd,0x42, //1908• 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• 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• 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• 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 • 0x0C,0x96,0x45, //2000 • 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• 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• 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};••bit c_moon;•data uchar year_moon,month_moon,day_moon;•/*子函数,用于读取数据表中农历月的大月或小月,如果该月为大返回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);}• }•}••/*********************************************************************************** **•函数功能:输入阳历数据,输出阴历数据(只允许1901-2099年)•调用函数示例:Conversion(c,year,month,day)•如:计算2004年10月16日Conversion(0,0x4,0x0A,0x10);•c,year,month,day均为16进制数据,c为世纪标志位,c_sun=0为21世纪,c_sun=1为19世纪•调用函数后,原有数据不变,读c_moon,year_moon,month_moon,day_moon得出阴历16进制数据。
CC++程序设计——万年历(完整代码+实验报告)

2、主要函数流程图: (1)类的构造函数:用于给类的对象赋值。提示用户输入数据,并具有较强的错误输 入数据检查功能。(参见图 3-1) (2)闰年判断函数:判断哪些年份为闰年。 (图 3-2)
正文 第 2 页(共 18 页)
开 始
开 始
year%4==0
否
输入待查询的 年份
是
否
year%100==0
* ","***** ","***** ","***** ","***** ","***** "," * ","***** ","***** "," * ","***** ","***** ","
"***** ","
=====================公元"<<year<<"年日历====================="<<endl; =====================公元"<<year<<"年日历====================="<<endl;
/*实现 3 维数组图案的输出*/ for(int g=0;g<5;g++) { cout<<" fout<<" for(int i=0;i<4;i++) for(int h=0;h<7;h++) { cout<<ss[g][num[i]][h]; fout<<ss[g][num[i]][h]; } cout<<endl; fout<<endl; } }
C语言课程设计万年历 完整版

目录一引言 (2)二系统功能和数据说明 (3)一)功能简介 (3)二)程序中的数据说明 (3)三程序总体设计及流程图 (4)一)应用到的c语言 (4)二)程序的总框架 (5)四功能模块设计及调试 (5)一)算法说明 (5)1.总天数的算法 (5)2.计算输入日期是星期几 (6)3.对输入信息的汇总 (8)4..界面的控制 (10)二)调试结果 (11)五程序清单 (12)六结束语 (17)一引言通过大一上学期对C语言的学习,了解到了很多C语言的相关知识。
学习的过程有很多困惑但是当自己能够独立的看懂,能过独立的完成一个简单的程序时,心中就会收获无限的喜悦和成就感。
我可以里哟哦那个它看懂一些简单的程序,编写一些简单的计算程序,更多的是学会了一种思想——编程,它让我在去思考很多日常生活中的事物是怎么样通过一个个小小的函数实现功能的,激发我对探究的兴趣。
C语言是近年在国内外得到迅速推广应用的一种语言。
C语言功能丰富,表达能力强,使用灵活方便,应用面广,目标程序效率高,可移植性好,既具有高级语言的优点,又具有低级语言的许多特点。
因此,C语言特别适合于编写各种软件。
在这次的课程设计中我将把日常生活中最经常接触的——日期的查询利用C语言的程序编成一个简单的日历。
通过这个小小的日历可以实现很多功能。
在程序中你能看到很多熟悉的C语言关键字,同时也加入了很多自己课外了解到的一些关键字。
在不断的调试中最终才获得最为完整的程序。
接下来就是我的C 语言课程设计的具体内容来了二系统功能和数据说明(一)功能简介在我们的日常生活中能接触到很多不同类型的日历,在日历上我们通常希望它能简介明了的给我们最想要的日期信息。
在我的万年历当中,就是将日历,月历做的简单明了,很方便我们的使用。
下面是它要实现的一些基本功能:用C语言编写万年历1、输入年份,判断是否为闰年2、输入年月日,判断改日为星期几3、输入年份,打出12个月历,输入月份,打出该月的日历4、要求用多个函数实现[名称]万年历[修改]1、对输入的日期进行容错处理2、增加和修改为英文的月份和星期显示3、采用指针形式的weeks和month数组(二)程序中的数据说明①int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};这是定义的关于每个月天数的数组,根据大小月以及二月分的特殊情况将每个月的天数最为数组中的元素存入数组当中。
51单片机c语言电子万年历完整程序

该程序为51单片机c语言电子万年历#include"reg52.h"//#include<stdio.h>#define uchar unsigned char#define uint unsigned intsbit lcden=P3^4;sbit lcdrs=P3^5;sbit DATA=P0^7;sbit RST=P0^5;sbit SCLK=P0^6;sbit menu=P3^0; //菜单sbit add=P3^1; //加一sbit dec=P3^7; //减一sbit led0=P1^0;sbit led1=P1^1;sbit led2=P1^2;sbit led3=P1^3;sbit ds=P3^2;//sbit beep=P3^3;uint temp;float f_temp;uint warn_l1=270;uint warn_l2=250;uint warn_h1=300;uint warn_h2=320;uint get_temp();void delayms(uint x);void write_com(uchar com);void write_data(uchar date);void init();void dis_temp(uint t);void Write1302(uchar dat);void WriteSet1302(uchar Cmd,uchar dat);uchar Read1302(void);uchar ReadSet1302(uchar Cmd);void Init_DS1302(void);void DisplaySecond(uchar x);void DisplayMinute(uchar x);void DisplayHour(uchar x);void DisplayDay(uchar x);void DisplayMonth(uchar x);void DisplayYear(uchar x);void DisplayWeek(uchar x);void dis_temp(uint t);void read_date(void);void turn_val(char newval,uchar flag,uchar newaddr,uchar s1num);void key_scan(void);char code table[]="0123456789" ;uchar code table2[]= "TUEWESTHUFRISATSUNMON"; uchar second,minute,hour,day,month,year,week,count=0; uchar ReadValue,num,time;void delayms(uint x){uint i,j;for(i=x;i>0;i--)for(j=110;j>0;j--);}////////////////////////////////////////////////////////////void write_com(uchar com){lcdrs=0;P2=com;delayms(5);lcden=1;delayms(5);lcden=0;}void write_data(uchar date){lcdrs=1;P2=date;delayms(5);lcden=1;delayms(5);lcden=0;}void init(){lcden=0;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);}/////////////////////////////////////////////////////////////////void Write1302(uchar dat){uchar i;SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备 delayms(2); //稍微等待,使硬件做好准备for(i=0;i<8;i++) //连续写8个二进制位数据DATA=dat&0x01; //取出dat的第0位数据写入1302delayms(2); //稍微等待,使硬件做好准备SCLK=1; //上升沿写入数据delayms(2); //稍微等待,使硬件做好准备SCLK=0; //重新拉低SCLK,形成脉冲dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位 }}void WriteSet1302(uchar Cmd,uchar dat){RST=0; //禁止数据传递SCLK=0; //确保写数居前SCLK被拉低RST=1; //启动数据传输delayms(2); //稍微等待,使硬件做好准备Write1302(Cmd); //写入命令字Write1302(dat); //写数据SCLK=1; //将时钟电平置于已知状态RST=0; //禁止数据传递}uchar Read1302(void){uchar i,dat;delayms(2); //稍微等待,使硬件做好准备for(i=0;i<8;i++) //连续读8个二进制位数据dat>>=1; //将dat的各数据位右移1位,因为先读出的是字节的最低位if(DATA==1) //如果读出的数据是1dat|=0x80; //将1取出,写在dat的最高位SCLK=1; //将SCLK置于高电平,为下降沿读出delayms(2); //稍微等待SCLK=0; //拉低SCLK,形成脉冲下降沿delayms(2); //稍微等待}return dat; //将读出的数据返回}uchar ReadSet1302(uchar Cmd){uchar dat;RST=0; //拉低RSTSCLK=0; //确保写数居前SCLK被拉低RST=1; //启动数据传输Write1302(Cmd); //写入命令字dat=Read1302(); //读出数据SCLK=1; //将时钟电平置于已知状态RST=0; //禁止数据传递return dat; //将读出的数据返回}void Init_DS1302(void){WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令WriteSet1302(0x80,((0/10)<<4|(0%10))); //根据写秒寄存器命令字,写入秒的初始值WriteSet1302(0x82,((59/10)<<4|(59%10))); //根据写分寄存器命令字,写入分的初始值WriteSet1302(0x84,((23/10)<<4|(23%10))); //根据写小时寄存器命令字,写入小时的初始值WriteSet1302(0x86,((28/10)<<4|(28%10))); //根据写日寄存器命令字,写入日的初始值 WriteSet1302(0x88,((2/10)<<4|(2%10))); //根据写月寄存器命令字,写入月的初始值WriteSet1302(0x8c,((14/10)<<4|(14%10))); //nian//WriteSet1302(0x8a,((4/10)<<4|(4%10)));}/////////////////////////////////////////////////////////////////void DisplaySecond(uchar x){uchar i,j;i=x/10;j=x%10;write_com(0x80+0x46);write_data(i+0x30);write_com(0x80+0x47);write_data(j+0x30);write_com(0x80+0x48);write_data(' ');dis_temp(get_temp());}void DisSecond(uchar x){uchar i,j;ReadValue = ReadSet1302(0x81);second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);i=x/10;j=x%10;write_com(0x80+0x46);write_data(i+0x30);write_com(0x80+0x47);write_data(j+0x30);}void DisplayMinute(uchar x) {uchar i,j;i=x/10;j=x%10;write_com(0x80+0x43);write_data(i+0x30);write_com(0x80+0x44);write_data(j+0x30);write_com(0x80+0x45);write_data(':');}void DisplayHour(uchar x){uchar i,j;i=x/10;j=x%10;write_com(0x80+0x40);write_data(i+0x30);write_com(0x80+0x41);write_data(j+0x30);write_com(0x80+0x42);write_data(':');}void DisplayDay(uchar x) {uchar i,j;i=x/10;j=x%10;write_com(0x89);write_data(i+0x30);write_com(0x8a);write_data(j+0x30); }void DisplayMonth(uchar x) {uchar i,j;i=x/10;j=x%10;write_com(0x86);write_data(i+0x30); write_com(0x87);write_data(j+0x30);write_com(0x88);write_data('/');}void DisplayYear(uchar x) {uchar i,j;i=x/10;j=x%10;write_com(0x81);write_data(2+0x30);write_com(0x82);write_data(0+0x30);write_com(0x83);write_data(i+0x30);write_com(0x84);write_data(j+0x30);write_com(0x85);write_data('/');}void DisplayWeek(uchar x){ uchar i;x=x*3;// write_com(0x8c);write_data(table2[x]);// write_com(0x8d);write_data(table2[x+1]);// write_com(0x8e);write_data(table2[x+2]);write_com(0x8c);for(i=0;i<3;i++){write_data(table2[x]);x++;}}void read_date(void){ReadValue = ReadSet1302(0x81);second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = ReadSet1302(0x83);minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = ReadSet1302(0x85);hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = ReadSet1302(0x87);day=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = ReadSet1302(0x89);month=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = ReadSet1302(0x8d);year=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue=ReadSet1302(0x8b); //读星期week=ReadValue&0x07;DisplayYear(year);DisplayMonth(month);DisplayDay(day);DisplayWeek(week);DisplayHour(hour);DisplayMinute(minute);DisplaySecond(second);dis_temp(get_temp()); ///温度显示key_scan(); ///按键检测}void turn_val(char newval,uchar flag,uchar newaddr,uchar s1num){newval=ReadSet1302(newaddr); //读取当前时间newval=((newval&0x70)>>4)*10+(newval&0x0f); //将bcd码转换成十进制 if(flag) //判断是加一还是减一{newval++;switch(s1num){ case 1: if(newval>99) newval=0;DisplayYear(newval);break;case 2: if(newval>12) newval=1;DisplayMonth(newval);break;case 3: if(newval>31) newval=1;DisplayDay(newval);break;case 4: if(newval>6) newval=0;DisplayWeek(newval);break;case 5: if(newval>23) newval=0;DisplayHour(newval);break;case 6: if(newval>59) newval=0;DisplayMinute(newval);break;case 7: if(newval>59) newval=0;DisplaySecond(newval);break;default:break;}}else{newval--;switch(s1num){ case 1: if(newval==0) newval=99;DisplayYear(newval);break;case 2: if(newval==0) newval=12;DisplayMonth(newval);break;case 3: if(newval==0) newval=31;DisplayDay(newval);break;case 4: if(newval<0) newval=6;DisplayWeek(newval);break;case 5: if(newval<0) newval=23;DisplayHour(newval);break;case 6: if(newval<0) newval=59;DisplayMinute(newval);break;case 7: if(newval<0) newval=59;DisplaySecond(newval);break;default:break;}}WriteSet1302((newaddr-1),((newval/10)<<4)|(newval%10)); //将新数据写入寄存器}//////////////////////////////////////void dsreset(void){uint i;ds=0;i=103;while(i>0)i=4;while(i>0)i--;}bit tempreadbit(void){uint i;bit dat;ds=0;i++;ds=1;i++;i++;dat=ds;i=8;while(i>0)i--;return(dat);}uchar tempread(void){uchar i,j,dat;dat=0;for(i=1;i<=8;i++){j=tempreadbit();dat=(j<<7)|(dat>>1); }return(dat);}void tempwritebyte(uchar dat) {bit testb;for(j=1;j<=8;j++){testb=dat&0x01;dat=dat>>1;if(testb){ds=0;i++;i++;ds=1;i=8;while(i>0)i--;}else{ds=0;i=8;while(i>0)i--;ds=1;i++;i++;}}}void tempchange(void) {dsreset();delayms(1);tempwritebyte(0xcc);tempwritebyte(0x44);key_scan(); //////按键函数}uint get_temp(){uchar a,b;tempchange(); //////温度函数dsreset();delayms(1);tempwritebyte(0xcc);tempwritebyte(0xbe);a=tempread();b=tempread();temp=b;temp<<=8;temp=temp|a;f_temp=temp*0.0625;temp=f_temp*10+0.5;f_temp=f_temp+0.05;return temp;}//////void dis_temp(uint t){uchar n1,n2,n3;n1=t/100;n2=t%100/10;n3=t%100%10;DisSecond(second); ///秒显示 write_com(0x80+0x49);write_data(table[n1]);//delayms(5);write_com(0x80+0x4a);write_data(table[n2]);//delayms(5);write_com(0x80+0x4b);write_data('.');// delayms(5);write_com(0x80+0x4c);write_data(table[n3]);//delayms(5);write_com(0x80+0x4d);write_data('^');//delayms(5);write_com(0x80+0x4e);write_data('C');//delayms(5);DisSecond(second); ////秒显示}/*********************液晶显示*****************/ void warn(uint s,uchar led){uchar i;i=s;// beep=0;P1=~(led);while(i--){dis_temp(get_temp());}// beep=1;P1=0xff;i=s;while(i--){dis_temp(get_temp());}}void deal(uint t){uchar i;if((t>warn_l2)&&(t<=warn_l1)){warn(40,0x01);}else if(t<=warn_l2){warn(10,0x03);}else if((t<warn_h2)&&(t>=warn_h1)) {warn(40,0x04);}else if(t>=warn_h2){warn(10,0x0c);}else{i=40;while(i--){dis_temp(get_temp());DisSecond(second);}}}///////////////////////////////////////void main(){init();Init_DS1302();while(1){tempchange();read_date();deal(temp);key_scan();}}////******************************************* void key_scan(void){// uchar miao,s1num=0;uchar s1num=0;if(menu==0){delayms(5);if(menu==0){while(!menu);s1num++;while(1){if(menu==0){delayms(5);if(menu==0){while(!menu);s1num++;}}// miao=ReadSet1302(0x81);// second=miao;// WriteSet1302(0x80,miao|0x80);write_com(0x0f);//光标闪射if(s1num==1){ //year=ReadSet1302(0x8d);write_com(0x80+4); //年光标if(add==0){delayms(3);if(add==0){ while(!add);turn_val(year,1,0x8d,1);}}if(dec==0){delayms(3);if(dec==0){ while(!dec);turn_val(year,0,0x8d,1);}}}if(s1num==2){//month=ReadSet1302(0x89);write_com(0x80+7); //月光标if(add==0){delayms(3);if(add==0){ while(!add);turn_val(month,1,0x89,2);}}if(dec==0){delayms(3);if(dec==0){ while(!dec);turn_val(month,0,0x89,2);}}}if(s1num==3){ //day=ReadSet1302(0x87);write_com(0x80+10);//日光标{delayms(3);if(add==0){ while(!add);turn_val(day,1,0x87,3);}}if(dec==0){delayms(3);if(dec==0){ while(!dec);turn_val(day,0,0x87,3); //写入日寄存器 }}}if(s1num==4){ //week=ReadSet1302(0x8b);write_com(0x80+14); //星期光标if(add==0){delayms(3);if(add==0){ while(!add);turn_val(week,1,0x8b,4);}}if(dec==0){delayms(3);{ while(!dec);turn_val(week,0,0x8b,4);}}}if(s1num==5){// hour=ReadSet1302(0x85)write_com(0x80+0x40+1); //时光标if(add==0){delayms(3);if(add==0){ while(!add);turn_val(hour,1,0x85,5);}}if(dec==0){delayms(3);if(dec==0){ while(!dec);turn_val(hour,0,0x85,5);}}}if(s1num==6)//调时间分{ // minute=ReadSet1302(0x83);write_com(0x80+0x40+4);if(add==0){delayms(5);if(add==0){ while(!add);turn_val(minute,1,0x83,6); //写入分寄存器}}if(dec==0){delayms(3);if(dec==0){ while(!dec);turn_val(minute,0,0x83,6); //写入分寄存器}}}if(s1num==7)//调时间秒{// second=ReadSet1302(0x81);write_com(0x80+0x40+7);//秒光标if(add==0){delayms(3);if(add==0){ while(!add);if(second==0x60)second=0x00;turn_val(second,1,0x81,7);}}if(dec==0){delayms(3);if(dec==0){ while(!dec);turn_val(second,0,0x81,7);}}}if(s1num==8){// miao=ReadSet1302(0x81);// second=miao;// WriteSet1302(0x80,second&0x7f);s1num=0;//s1num清零//write_com(0x0c);//光标不闪烁//break;}}}}}。
电子万年历源程序#

电子万年历源程序IO口程序#include <reg52.h>//*****数码管引脚*****sbit L1 = P2^0。
sbit L2 = P2^1。
sbit L3 = P2^2。
sbit LEDC= P2^3。
#define LED_DA TA P0//按键接口定义#define K_Port P2sbit K_D = P3^3。
//外部中断1 //*****PCF8563接口定义****sbit PCF8563CLK=P1^0。
sbit PCF8563SDA=P1^1。
// 24c02接口定义sbit E2PCLK=P1^5。
sbit E2PSDA=P1^6。
//蜂鸣器接口定义sbit BEEP = P1^2主程序#include <main.h>void Delay_1ms(unsigned int time>{unsigned char temp。
while(time-->for(temp=127。
temp>0。
temp-->_nop_(>。
}//系统初始化void Sys_Init(>{TMOD=0x01。
TH0=(65535-20000>/256。
//给定时器初值。
TL0=(65535-20000>%256。
TR0=1。
//启动定时器T0ET0=1。
//允许T0中断EA=1。
LEDC=0。
//138正常工作Beep_Flag=1。
//闹铃开}//刷新数码管显示void Fresh_Display(>{static unsigned char Num。
unsigned char temp。
static unsigned int Flash_Time。
Num++。
if(Num>=8>Num=0。
LED_DATA=0x00。
//P0口全部为零if(Num==0>{L3=1。
L2=1。
L1=1。
课程设计说明万年历程序设计

《高级语言程序设计》课程设计说明书设计题目:万年历程序设计班级:学号:姓名:完成日期:一:课程设计目的《高级语言程序设计》课程设计是电子信息、光信息专业和物理学专业集中实践性环节之一,是学习完《高级语言程序设计》课程后进行的一次全面的综合练习,其目的在于加深对程序设计大体知识的明白得,把握利用C语言进行模块化软件设计的大体方式,提高通过编写程序解决实际问题的能力,为尔后从事设计工作和后续各类编程课程的学习打好基础。
二:需求分析题目:要求:输入年份和月份,自动输出该月的日历,清楚的显示每一天是礼拜几,输入年份,月份和具体日期能确信某天是礼拜几。
万年历是采纳数字电路实现对.时,分,秒.数字显示的计时装置,普遍用于个人家庭,车站, 码头办公室等公开场合,成为人们常生活中不可少的必需品,由于数字集成电路的进展和石英晶体振荡器的普遍应用,使得数字钟的精度,远远超过老式钟表, 钟表的数字化给人们生产生活带来了极大的方便,而且大大地扩展了钟表原先的报时功能。
诸如按时自动报警、按时自动打铃、时刻程序自动操纵、按时广播、自动起闭路灯、按时开关烘箱、通断动力设备、乃至各类按时电气的自动启用等,可是所有这些,都是以钟表数字化为基础的。
因此,研究万年历及扩大其应用,有着超级现实的意义。
它能够对年、月、日、周日、时、分、秒进行计时,关于数字电子万年历采纳直观的数字显示,能够同时显示年、月、日、周日、时、分、秒等信息,还具有时刻校准等功能。
综上所述此万年历具有读取方便、显示直观、功能多样、电路简练、本钱低廉等诸多优势,符合电子仪器仪表的进展趋势,具有广漠的市场前景。
三:概要设计1-判定是不是为闰年计算所输入的年份是不是可被4整除,假设不能被整除,为平年。
假设可被4整除,计算此年份可否被100整除,不能被100整除那么为闰年。
既能被4整除,也能被100整除的年份,假设也能被400整除,那么为闰年,不然为平年。
闰年366天,平年365天2-要紧设计思路四:详细设计源程序:#include <stdio.h> #include <stdlib.h>void DayOfWeek(){int rtnDay;int y,m,d;char ch;while (1){printf("请输入年月日(xxxx,xx,xx): ");scanf("%d,%d,%d", &y, &m, &d);fflush(stdin);rtnDay =(3*y-(7*(y+(m+9)/12))/4+(23*m)/9+d+17-((y+(m<3?-1:0))/100+1)*3/4) % 7; printf("%04d年%02d月%02d日是礼拜%d\n", y, m, d, rtnDay?rtnDay:7); printf("继续查询(y/n)");ch = getchar();if(ch != 'y' && ch != 'Y')break;}}void GetMonth(int D, int md, int n){int N ,m,d,y,c,Wd;int i,maxday,i1;if(md>=13||md<=0)printf("HAVE WRONG!");else{for(i1=0;;md++,i1++){if(md==0){md=12;D-=1;}elseif(md==13){md=1;D+=1;}m=md;printf("\n============%d,%2d============\n",D,md);if(0<m&&m<=12){switch(m){case 1:maxday=31;break;case 2:if(D%4==0&&D%100!=0||D%400==0) maxday=29;elsemaxday=28;break;case 3:maxday=31;break;case 4:maxday=30;break;case 5:maxday=31;break;case 6:maxday=30;break;case 7:maxday=31;break;case 8:maxday=31;break;case 9:maxday=30;break;case 10:maxday=31;break;case 11:maxday=30;break;case 12:maxday=31;break;default:printf("HAVE WRONG");}if(0<m&&m<=2){N=D-1;m=m+10;}else{N=D;m=m-2;}c=N/100;y=N%100;Wd=((1+(13*m-1)/5+y+y/4+c/4-2*c)%7+7)%7; printf(" SUN MOU TUE WED TUR FRI SAT\n"); for(i=0;i<Wd;i++)printf("%4c",' ');for(d=1;d<=maxday;d++){printf("%4d",d);Wd=(Wd+1)%7;if(Wd==0)printf("\n");}}elseprintf("HAVE WRONG!");if(i1==n)break;}}}void MonthOfYear(){char ch;int y, m;while (1){printf("请输入年月(xxxx,xx): "); scanf("%d,%d", &y, &m);fflush(stdin);GetMonth(y, m, 0);printf("\n继续查询(y/n)");ch = getchar();if(ch != 'y' && ch != 'Y')break;}}void GetYear(){char ch;int y;while (1){printf("请输入年: ");scanf("%d", &y);fflush(stdin);GetMonth(y, 1, 11);printf("\n继续查询(y/n)");ch = getchar();if(ch != 'y' && ch != 'Y')break;}}int main(){char ch;while(1){system("cls");printf("1.查询礼拜\n");printf("2.查询月份\n");printf("3.显示一年\n");printf("4.退出程序\n");ch = getchar();fflush(stdin);switch(ch){case '1':DayOfWeek();break;case '2':MonthOfYear();break;case '3':GetYear();break;case '4':printf("是不是退出(y/n)");ch = getchar();fflush(stdin);if(ch == 'y' || ch == 'Y')exit(0);break;}}}五:运行成效及分析1 登录界面输入3,通过输入年份可显示一年每一个月份的日历;输入2,通过输入年份和月份(中间以空格分开)可显示该月的日历;假设输入1,通过输入年份月份和日期(中间以逗号分开)可显示该日的礼拜;输入4,那么退出查询系统2查询礼拜输入1后回车,然后输入具体的年月日可查出该天为礼拜几3查询月历输入2回车,然后输入年月可显示该月月历4显示一年输入3后回车,输入一个有效年份可显示该年的十二个月的月历。
C++程序设计(万年历——说明书)

C++程序设计说明书题目:万年历班级学号:学生姓名:目录一.应用程序的名称二.应用程序的主题、设计目的三.应用程序简介1.程序的基本结构及内容2。
程序的运行环境四.主要运行界面的介绍五.程序亮点六.课程设计中存在的问题及解决方法一.课程设计名称万年历二.应用程序要求、目的主题:万年历目的:实现对年月的查询三.应用程序简介(1)基本结构:整个程序有cls_screen(清屏)、judgement(判断是否为闰年)、show_week(记录周几)、print_year(查询某年)、print_year_month(查询某年某月)等自定义函数,程序中涉及到switch语句、for语句、if语句等和多次函数调用语句,开头定义了day_of_month[]数组,主要目的是将12个月每个月有多少天依次排出,在后面又用if语句判断二月的天数是28还是29。
在主函数中运用while 语言与switch语句的嵌套,是程序拥有了循环的功能.用fflush(stdin);语句清除输入缓存,使程序在使用过程中不会太过眼花缭乱。
万年历的编程,需要两个方面的讨论和研究,一是要在用户输入年份的时候,判断该年是否为闰年,而对于闰年的判断,能被4整除但不能被100整除,或者能被400整除的年份为闰年,否则为平年。
所以会改变day_of_month[]数组中的二月份的数值。
二是在用户输入年月份的时候,判断该年该月的第一天是周几,从来好排列。
而对于判断周几,需要运用公式:w=(y+[y/4]+[c/4]—2c+[26(m+1)/10]+d-1)%7并用if语句使用判断。
通过这两个方面的讨论和实现,才能合理的编程出万年历的基本程序代码.(2)源程序代码:#include〈stdio.h>#include 〈string。
h〉#include 〈time.h>#include <math。
h〉#include 〈windows。
万年历初始源程序

12864、DS1302制作的电子万年历代码如下:/********************************************************************名称:电子万年历功能:自动计时100年,节日、时间提醒作者:甘春生实验板:KX-1N/******************************************************************** #include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit RS=P2^0;sbit RW=P2^1;sbit EN=P2^2;sbit FUN=P1^0;sbit OK=P1^1;sbit INC=P1^2;sbit DEC=P1^3;sbit RST=P2^5;sbit IO=P2^6;sbit SCLK=P2^7;uchar hour=10;uchar min=18;uchar sec=30;uchar year=10;uchar mon=1;uchar date=20;uchar day=3;uchar count=0;uchar flag=0;uchar num=0;uchar i=6;void delay(uint i){uint j;for(;i>0;i--)for(j=0;j<125;j++);}void Write_Ds1302_Byte(uchar temp){uchar i;for(i=0;i<8;i++)SCLK=0;IO=temp&0x01;//只传最后一位temp>>=1;SCL=1;}}void Write_Ds1302(uchar address,uchar dat) {RST=0;SCLK=0;RST=1;Write_Ds1302_Byte(address);Write_Ds1302_Byte(dat);SCLK=1;RST=0;}uchar Read_Ds1302(uchar address){uchar i,temp=0x00;RST=0;SCLK=0;RST=1;Write_Ds1302_Byte(address);for(i=0;i<8;i++){temp>>=1;SCLK=0;if(IO)temp=temp|0x80;SCLK=1;}RST=0;IO=0;return temp;}void Check_Busy(void){RW=1;//RW=1为读RS=0;//RS=0为指令EN=1;while(P2&0X80);}void Write_com(uchar com)Check_Busy();RW=0;RS=0;P2=com;EN=1;delay(1);EN=0;}void Write_dat(uchar dat){Check_Busy();RW=0;RS=1;P2=dat;EN=1;delay(1);EN=0;}void Lcd_Pos(uchar Xpos,uchar Ypos){uchar tmp;Xpos&=0x0f;Ypos&=0x03;tmp=Xpos;if(Ypos==0)tmp|=0x80;if(Ypos==1)tmp|=0x90;if(Ypos==2)tmp|=0x88;if(Ypos==3)tmp|=0x98;Write_com(tmp);}void Write_LCD_String(uchar x,uchar y,uchar *s) {Lcd_Pos(x,y);Lcd_Pos(x,y);while (*s!='\0'){Write_dat(*s);s++;delay(1);}void LCD_Rst(void){Write_com(0x30);Check_Busy();Write_com(0x01);Write_com(0x06);Write_com(0x0c);delay(5);}void Write_day(uchar Sel){switch (Sel){case 1:Write_LCD_String(6,1,"一");break;case 2:Write_LCD_String(6,1,"二");break;case 3:Lcd_Pos(6,1);Write_dat(0xc8);Write_dat(0xfd);break;case 4:Write_LCD_String(6,1,"四");break;case 5:Write_LCD_String(6,1,"五");break;case 6:Write_LCD_String(6,1,"六");break;case 7:Write_LCD_String(6,1,"日");break;default :break;}}void Updat_Time(void){Lcd_Pos(3,0);Write_dat(0x30+(year/10));Write_dat(0x30+(year%10)); Lcd_Pos(0,1);Write_dat(0x30+(mon/10));Write_dat(0x30+(mon%10)); Lcd_Pos(2,1);Write_dat(0x30+(date/10));Write_dat(0x30+(date%10)); Lcd_Pos(0,2);Write_dat(0x30+(hour/10));Write_dat(0x30+(hour%10)); Lcd_Pos(2,2);Write_dat(0x30+(min/10));Write_dat(0x30+(min%10)); Lcd_Pos(4,2);Write_dat(0x30+(sec/10));Write_dat(0x30+(sec%10)); Write_day(day);}void Write_Time(void){Write_Ds1302(0x8e,0x00);Write_Ds1302(0x8c,(year/10)*16+year%10);Write_Ds1302(0x88,(mon/10)*16+mon%10);Write_Ds1302(0x86,(date/10)*16+date%10);Write_Ds1302(0x84,(hour/10)*16+hour%10);Write_Ds1302(0x82,(min/10)*16+min%10);Write_Ds1302(0x80,(sec/10)*16+sec%10);Write_Ds1302(0x8a,(day/10)*16+day%10);Write_Ds1302(0x8e,0x80);}void Read_Time(void){year=(Read_Ds1302(0x8d)>>4)*10+Read_Ds1302(0x8d)%16; mon=(Read_Ds1302(0x89)>>4)*10+Read_Ds1302(0x89)%16; date=(Read_Ds1302(0x87)>>4)*10+Read_Ds1302(0x87)%16; hour=(Read_Ds1302(0x85)>>4)*10+Read_Ds1302(0x85)%16; min=(Read_Ds1302(0x83)>>4)*10+Read_Ds1302(0x83)%16; sec=(Read_Ds1302(0x81)>>4)*10+Read_Ds1302(0x81)%16; day=(Read_Ds1302(0x8b)>>4)*10+Read_Ds1302(0x8b)%16; Updat_Time();}void Set_Time(void){if(FUN==0){delay(10);if(FUN==0){while(!FUN);flag=1;num++;if(num==8)num=1;}}if(flag){if(num==1){Lcd_Pos(0,2);Write_com(0x0d);if(INC==0){delay(10);if(INC==0){while(!INC);hour++;if(hour==24)hour=0;}}if(DEC==0){delay(10);if(DEC==0){while(!DEC);hour--;if(hour==-1)hour=23;Updat_Time();}}}if(num==2){Lcd_Pos(2,2);Write_com(0x0d);if(INC==0){delay(10);if(INC==0){while(!INC);min++;if(min==60)min=0;Updat_Time();}}if(DEC==0){delay(10);if(DEC==0){while(!DEC);min--;if(min==-1)min=59;}}}if(num==3){Lcd_Pos(4,2);Write_com(0x0d);if(INC==0){delay(10);if(INC==0){while(!INC);sec++;if(sec==60)sec=0;Updat_Time();}}if(DEC==0){delay(10);if(DEC==0){while(!DEC);sec--;if(sec==-1)sec=59;Updat_Time();}}}if(num==4){Lcd_Pos(3,0);Write_com(0x0d);if(INC==0){delay(10);if(INC==0){while(!INC);year++;year=0;Updat_Time();}}if(DEC==0){delay(10);if(DEC==0){while(!DEC);year--;if(year==-1)sec=99;Updat_Time();}}}if(num==5){Lcd_Pos(0,1);Write_com(0x0d); if(INC==0){delay(10);if(INC==0){while(!INC);mon++;if(mon==13)mon=1;Updat_Time();}}if(DEC==0){delay(10);if(DEC==0){while(!DEC);mon--;if(mon==0)mon=12;Updat_Time();}}}if(num==6){Lcd_Pos(2,1);Write_com(0x0d); if(INC==0){delay(10);if(INC==0){while(!INC);date++;if(date==32)date=1;Updat_Time();}}if(DEC==0){delay(10);if(DEC==0){while(!DEC);date--;if(date==0)date=31;Updat_Time();}}}if(num==7){Lcd_Pos(6,1);Write_com(0x0d); if(INC==0){delay(10);if(INC==0){while(!INC);day++;if(day==8)day=1;Updat_Time();}}if(DEC==0){delay(10);if(DEC==0){while(!DEC);day--;if(day==0)day=7;Updat_Time();}}}}if(OK==0){delay(10);if(OK==0){while(!OK);flag=0;num=0;Write_com(0x0c);Write_Time();}}}void Festival(void){if (mon == 1 && date== 1 ) { Write_LCD_String(0,3,"Happy New Year!!"); } elseif (mon == 1 && date== 28 ) { Write_LCD_String(0,3," 世界麻风日"); } elseif (mon == 2 && date== 2 ) { Write_LCD_String(0,3," 世界湿地日"); } elseif (mon == 2 && date== 13 ) { Write_LCD_String(0,3," 明天情人节了"); } elseif (mon == 2 && date== 14 ) { Write_LCD_String(0,3," 今天是情人节"); } elseif (mon == 3 && date== 1 ) { Write_LCD_String(0,3," 国际海豹日"); }elseif (mon == 3 && date== 3 ) { Write_LCD_String(0,3," 全国爱耳日"); } elseif (mon == 3 && date== 8 ) { Write_LCD_String(0,3," 3.8妇女节"); } elseif (mon == 3 && date== 12 ) { Write_LCD_String(0,3," 植树节"); } elseif (mon == 3 && date== 14 ) { Write_LCD_String(0,3," 国际警察日"); } elseif (mon == 3 && date== 15 ) { Write_LCD_String(0,3," 消费者权益日"); } elseif (mon == 3 && date== 17 ) { Write_LCD_String(0,3," 国际航海日"); } elseif (mon == 3 && date== 21 ) { Write_LCD_String(0,3," 世界森林日"); } elseif (mon == 3 && date== 22 ) { Write_LCD_String(0,3," 世界水日"); } elseif (mon == 3 && date== 23 ) { Write_LCD_String(0,3," 世界气象日"); } elseif (mon == 3 && date== 24 ) { Write_LCD_String(0,3,"世界防治结核病日"); } elseif (mon == 4 && date== 1 ) { Write_LCD_String(0,3,"愚人节小心上当"); } elseif (mon == 4 && date== 7 ) { Write_LCD_String(0,3," 世界卫生日"); } elseif (mon == 4 && date== 8 ) { Write_LCD_String(0,3," 复活节"); } elseif (mon == 4 && date== 13 ) { Write_LCD_String(0,3," 黑色星期五"); } elseif (mon == 5 && date== 1 ) { Write_LCD_String(0,3," 劳动节放假"); } elseif (mon == 5 && date== 4 ) { Write_LCD_String(0,3," 青年节"); } elseif (mon == 5 && date== 8 ) { Write_LCD_String(0,3," 世界红十字日"); } elseif (mon == 5 && date== 12 ) { Write_LCD_String(0,3," 国际护士节"); } elseif (mon == 5 && date== 5 ) { Write_LCD_String(0,3,"近日注意母亲节"); } // &nb, , , , , sp;elseif (mon == 5 && date== 15 ) { Write_LCD_String(0,3," 国际家庭日"); } elseif (mon == 5 && date== 31 ) { Write_LCD_String(0,3," 世界无烟日"); } elseelseif (mon == 6 && date== 5 ) { Write_LCD_String(0,3," 世界环境日"); } elseif (mon == 6 && date== 26 ) { Write_LCD_String(0,3," 国际禁毒日"); } elseif (mon == 6 && date== 6 ) { Write_LCD_String(0,3," 全国爱眼日"); } elseif (mon == 6 && date== 13 ) { Write_LCD_String(0,3,"近日注意父亲节"); } elseif (mon == 6 && date== 15 ) { Write_LCD_String(0,3,"近日注意父亲节"); } elseif (mon == 7 && date== 1 ) { Write_LCD_String(0,3,"香港回归记念日"); } elseif (mon == 7 && date== 7 ) { Write_LCD_String(0,3,"抗日战争记念日"); } elseif (mon == 7 && date== 11 ) { Write_LCD_String(0,3," 世界人口日"); } elseif (mon == 8 && date== 1 ) { Write_LCD_String(0,3," 八一建军节"); } elseif (mon == 8 && date== 8 ) { Write_LCD_String(0,3," 中国男子节"); } elseif (mon == 8 && date== 15 ) { Write_LCD_String(0,3,"抗战胜利记念日"); } elseif (mon == 9 && date== 10 ) { Write_LCD_String(0,3," 中国教师节"); } elseif (mon == 9 && date== 18 ) { Write_LCD_String(0,3,"九·一八事变记念"); } elseif (mon == 9 && date== 20 ) { Write_LCD_String(0,3," 国际爱牙日"); } elseif (mon == 9 && date== 27 ) { Write_LCD_String(0,3," 世界旅游日"); } elseif (mon == 10 && date== 1 ) { Write_LCD_String(0,3," 中国国庆节"); } elseif (mon == 10 && date== 4 ) { Write_LCD_String(0,3," 世界动物日"); } elseif (mon == 10 && date== 24 ){ Write_LCD_String(0,3," 联合国日"); } elseif (mon == 10 && date== 12 ){ Write_LCD_String(0,3,"明天国际教师节"); } elseif (mon == 10 && date== 13 ){ Write_LCD_String(0,3," 国际教师节"); } elseif (mon == 11 && date== 10 ){ Write_LCD_String(0,3," 世界青年节"); } elseelseif (mon == 12 && date== 1 ) { Write_LCD_String(0,3," 世界艾滋病日"); } elseif (mon == 12 && date== 23 ){ Write_LCD_String(0,3," 明晚平安夜"); }elseif (mon == 12 && date== 24 ){ Write_LCD_String(0,3," 今晚平安夜"); }elseif (mon == 12 && date== 25 ){ Write_LCD_String(0,3," 圣诞快乐"); }elseif (mon == 12 && date== 31 ){ Write_LCD_String(0,3," 明日新年"); }else{if(hour >= 4 && hour< 6 ) { Write_LCD_String(0,3,"★★__▲▲__凌晨"); } if(hour >= 6 && hour< 8 ) { Write_LCD_String(0,3,"☆○__▲△__早晨"); } if(hour >= 8 && hour< 12 ) { Write_LCD_String(0,3,"__●__▲▲__上午"); } if(hour == 12) { Write_LCD_String(0,3,"____▲●▲__中午"); }if(hour >= 13 && hour< 18 ){ Write_LCD_String(0,3,"__▲▲__●__下午"); } if(hour >= 18 && hour< 22 ){ Write_LCD_String(0,3,"△▲__●☆__晚上"); } if(hour >= 22 && hour<= 23 ){ Write_LCD_String(0,3,"△▲__★☆__夜里"); } if(hour >= 0 && hour< 4 ) { Write_LCD_String(0,3,"__★▲▲★__深夜"); } }}void System_Init(void){LCD_Rst();Write_LCD_String(0,1,"系统初始化");Lcd_Pos(5,1);while(i--){Write_dat(0x3e);delay(300);}Write_com(0x01);Write_LCD_String(0,1,"您好!欢迎使用!");delay(1500);Write_com(0x01);Write_LCD_String(2,0,"2010年");Write_LCD_String(0,1,"01月18日星期一");Write_LCD_String(0,2,"10时17分30秒");}void main(void){System_Init();Write_Time(); while(1){Set_Time();if(!flag){Read_Time();Festival();}}}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一个计算万年历的简单程序
通常我们只知道生活当天的前后几天是星期几,即便是翻日历,也只能知道有限日期的星期数。
那么有没有一种方法可以让我们知道任何一天是星期几呢?有,下面我将向大家介绍一种方法,用以编写万年历的程序。
首先我们必须约定一些法则,我们用Y、M、D分别表示年、月、日,用数字0-6分别表示星期日-星期六,这样我们就可以开始推导我们的公式了。
我们知道2002年9月1号为星期日,如果我们要想知道2002年9月10号为星期几,可以这样算:(0+(10-1))%7=(0+9)%7=2,即星期二。
同样可算得2002年9月20号为:(0+(20-1))%7=(0+19)%7=5,即星期五。
但是这样算需要把日期减1,不太方便,为了解决这个问题,我们可以假设每个月有一个0号,由于2002年9月1号为星期日,那么2002年9月0号为星期六,这样算9月10号,只需代入10既(6+10)%7=2。
事实上,9月0号也就是8月31号,每个月0号的星期数实际上就是每个月1号的前一天的星期数。
我把这个星期数称之为每个月的代码。
有了这个代码,要算这个月任一天的星期数都好办了。
以上讨论的是一年中每个月的代码,事实上对于每年也有一个代码,这个代码就是每年1月0号(即1月1号的前一天)的星期数,也就是一月份的代码。
如果我们能够找到每年的代码之间的关系,那么要计算万年历就易如反掌了。
(一)推算年的代码公式
我们都知道,平年一年有365天,即52周多1天。
闰年为366天即52周多2天。
我们先只考虑平年的情况。
假设第N年的代码为W,则第N+1年的代码为(W+1)%7,而第N+K年的代码则为(W+K)%7。
这是因为从第N年到第N+K年共经过了K年,每过一年也就是过了52周余1天,经过K年也就是过了52*K周余K天,将多余的天数K加上第N年的代码W再对7取模,所得也就是第N+K年的代码了。
下面我们把闰年也考虑进来。
判断闰年的规则是,能被4整除,并能被100和400同时整除的年份就是闰年。
所以从第N年到第N+K年间共有K/4 -K/100+K/400个闰年,而每个闰年有52周余2天,要比平年多余了1天,即共多余了K/4-K/100+K/400天。
我们应该把这些天也加进去,所以第N+K年的代码应为(W+K+K/4-K/100+K/400)%7。
这样子是不是就考虑完全了呢?并非如此,我们还有两点没考虑到。
第一点是第N年是不是闰年。
如果第N年是闰年的话,它本身就是52周余2天,而我们在上面却是把它当作平年来计算的,少算了1天,应加上。
所以在第N年为闰年的时候上式应为
(W+(K+1)+K/4-K/100+K/400)%7。
第二点是第N+K年是不是闰年。
如果第N+K年是闰年,虽然它有52周余2天,但只有在算第N+(K+1)年的时候,才需要多加它那一天,而在算第N+K年的时候不需要多加这1天,因此我们必须将上式改为
(W+(K+1)+(K-1)/4-(K-1)/100+(K-1)/400)%7(注意千万不能改为
(W+(K+1)+(K/4-K/100+K/400-1))%7=(W+K+K/4-K/100+K/400)%7)。
由此我们可以得出当第N年为闰年时,第N+K年的代码计算式为:
A=(W+(K+1)+(K-1)/4-(K-1)/100+(K-1)/400)%7
为了方便计算,我们可以取N为0,也就是假设公元元年的代码为W。
因为公元元年也是闰年,符合上式,那么当我们输入的年份为Y时,此时就有K=Y,也就是说第Y年的代码为
A=(W+(Y+1)+(Y-1)/4-(Y-1)/100+(Y-1)/400)%7
接下来的问题就是W究竟是一个什么数了,下面我们就来解决这个问题。
我们已经知道2002年1月1号为星期二,它的前一天为星期一,那也就是说2002年的代码就是1,由此我们可得
(W+(2002+1)+(2002-1)/4-(2002-1)/100+(2002-1)/400)%7=1
即
(W+2488)%7=1
(W+3)%7=1
这样我们就可求得W=5。
我们的公式就变成了如下形式
A=(5+(Y+1)+(Y-1)/4-(Y-1)/100+(Y-1)/400)%7
有了这个公式,我们就可以算公元后任意一年的代码了,但还不能算公元前的,我们还需要再改进一下,得出公式(1):
(1)A year= Y>0 ? (5+(Y+1)+(Y-1)/4-(Y-1)/100+(Y-1)/400)%7
: (5 + Y + Y/4 - Y/100 + Y/400) % 7
这样就OK了。
不过这又导致了另一个问题:Y<0时,算得的A有可能小于0。
这个问题我们暂且留下,待会再解决。
(二)推算月的代码公式
年的问题解决了,月怎么办呢?请看下表:
表中的A为当年的代码。
由这个表我们可以看出,月与月之间也有一定的关系。
由此我们可以推出下面的公式(2):
(2)A month=M>2 ? (A year+2*(M+1)+3*(M+1)/5)%7
: (A year+2*(M+2)+3*(M+2)/5)%7
但是上表所反映的仅为平年的情况,若Y为闰年,则在M大于2时,每个月的代码还需再加1。
这可用一个IF语句解决:
(3)if (((Y%4==0 && Y%100!==0) || (Y%400==0)) && M > 2)
A month = (A month+1)%7;
现在我们回到公式(1)中的问题。
如果Y<0时,使得A year<0,那么A year最小也只能到-6。
大家可以看到,当我们将A year代入公式(2)时,问题就自然解决了。
(三)计算日期
有了上面的公式,当我们输入日期后,就很容易算出当天为星期几了,而且可以计算变量允许范围内的任意一天的星期数。
(4)A = (A month+D)%7
(四)写程序
下面给出该万年历的程序,约莫估计,它可从公元前数十亿年算到公元后数十亿年(即从负十位数到正十位数),而且无一错漏。
(程序中并没有对输入的月份和日期进行出错处理)
#include <stdio.h>
char *week[ ] = {"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"};
void main()
{
int Y;
int M;
int D;
int A;
printf("\nEnter year:");
scanf("%d",&Y);
printf("\nEnter month:");
scanf("%d",&M);
printf("\nEnter date:");
scanf("%d",&D);
//下面的四条语句用来计算输入日期的星期数,是程序的核心部分,缺一不可
A = Y > 0 ? (5 + (Y + 1) + (Y - 1)/4 - (Y - 1)/100 + (Y - 1)/400) % 7 : (5 + Y + Y/4 -
Y/100 + Y/400) % 7;
A = M > 2 ? (A + 2*(M + 1) + 3*(M + 1)/5) % 7 : (A + 2*(M + 2) + 3*(M + 2)/5) % 7;
if (((Y%4 == 0 && Y%100 != 0) || Y%400 == 0) && M>2)
{
A = (A + 1) % 7;
}
A = (A + D) % 7;
printf("\nI's a %s.\n\n",week[A]); }。