文档库 最新最全的文档下载
当前位置:文档库 › 万年历

万年历

万年历
万年历

程序设计综合实践报告

(C语言)

项目名称:桌面万年历

班级:信息与计算2010级1班

姓名:郭玉豪

学号:201001051506

山东科技大学信息科学与工程学院

2012年12月

目录

1. 项目概述 (3)

1.1 需求陈述 (3)

1.2 开发技术、环境与工具 (3)

2. 软件需求 (4)

2.1 功能性需求 (4)

3. 软件架构设计 (4)

4. 软件详细设计与实现 (5)

4.1 主要模块的流程图 (5)

4.2 核心代码 (5)

5 总结与体会 (21)

5.1遇到的问题与解决途径 (21)

5.2 心得体会 (22)

1. 项目概述

1.1 需求陈述

本项目是桌面时钟与万年历的实现,时钟可以实现年月日、时分秒、天干地支及生肖的输出,并且还能显示阴历的日期。右击时钟会选中日历会出现日历的输出。日历上显示今天阳历的年月日、阴历的年月日、干支年,生肖及图片,并且右边还有年和月的加减,点击今日按钮时间就立刻转的电脑本地的日期。日历本身显现阳历与阴历,和国家法定节假日。在日历的右上角有个取消按钮。为了增加日历的外观,增加了换肤按钮,使得本万年历更加人性化。

1.2 开发技术、环境与工具

1.2.1(DrawClockText)

此函数给出了表盘的的年月日与时分秒、干支年和生效年的输出调用。

1.2.2(DrawCalendar)

此函数是日历表的输出函数,它实现了日历表的输出阳历时间和阴历时间,生肖与干支年的输出。1.2.3(用到的API函数)

API函数参考:

GetLocalTime: 获得当前时间(公历:年、月、日、周);

MoveToEx: 移动划线的起点;

LineTo: 绘制到某一点;

SetTextColor: 设置要绘制的文字颜色;

TextOut: 绘制文字;

GetLocalTime:获得当前系统的本地时间;

结构体类型参考:

SYSTEMTIME: 描述时间类型,包括年月日、时分秒、周;

系统调用:

根据已给样本的提示,绘制了日历的矩形背景,并且也根据公历日期来计算出农历日期,并且标注了一些重要节日,像“春节、元宵节、国庆节、端午节、中秋节”等一些重要的节日,并且将节假日的字体颜色设置为红色,然后又写了获取当前系统本机时间的函数,成功的获得了当前本机的时间,这在日历中就可以观察到。

1.2.4

本程序是在基于c语言下实现的,用到的工具就是microsoft visual studio 2008。

2. 软件需求

2.1 功能性需求

2.1.1

void SunToLunar(const stDateTime* pSunDay,stDateTime* pLunarDay)

此调用函数实现了将一个公立日期转为一个阴历日期,目前此函数还有一些错误。

2.1.2

int GetDayOfWeek(const stDateTime* pSunDay)

此函数将一个阳历日期输进去,判断这一天为星期几,然后返回一个整型数据。

2.1.3

void DrawCalendar (HDC hDC)

此函数是是日历表的输出,标出了当天时间,并且在每天下都对应着当天的阴历时间。

2.1.4

void CalendarButtonEvent(UINT nID)

此函数实现了日历的年份和月份按钮的增加或者减少。

2.1.5

void DrawClockText(HDC hDC)

此函数实现了表盘的输出,年月日时分秒,生效年,干支年,星期几。

3. 软件架构设计

设计该万年历建了一个项目CalendarApp,该项目下有个头文件,源文件,资源文件,源文件中包括主程序main.c以及被调用的程序,资源文件中包括设置的万年历的外观,按钮设置……。该软件调用外部图片,图片在image中。

在日期设置上:

(1)根据公历日期获得农历日期,调用判断是不是闰年的函数,把一年中的农历所有月份的天数分为四

类(28,29,30,31)。

(2)用FOR循环输出各月份的日历,并把周末的字体设为红色。其余为黑色。

(3)在钟表上获得当前本地的系统时间。

(5)显示出星期、天干地支及农历日期。

详细设计过程:

1、首先绘制日历的矩形背景,用CreateSolidBrush(函数做出矩形的背景颜色,在日历的上端和下端分别输出阳历的年月份,及阴历的天干地支年等。

2、判断农历的每月有多少天,调用判断是否为闰年的函数,若为闰年,则定义二月为29天,通过一switch 函数输出十二个月的天数。

3、调用公历转为农历的函数并用for循环获得每日的农历日期,并调用CreateSolidBrush(函数标出当天的日期,并设置了五个法定节假日提醒。

4、对日历上的几个按钮进行设置,使得当年月份发生改变时,日历表可以正常显示。

5、获得本地系统时间,在表盘上的正确位置输出当天的年月日(调用CreateFont函数按角度输出)及当地时间和星期。

6、用指针数组存放十二个月的英文和星期的英文缩写。

4. 软件详细设计与实现

4.1 主要模块的流程图

流程图为阳历和阴历的转换过程示意图。

4.2 核心代码

#include"public.h"

/*

********************************************************* API函数参考:

GetLocalTime: 获得当前时间(公历:年、月、日、周)

MoveToEx: 移动划线的起点

LineTo: 绘制到某一点

SetTextColor: 设置要绘制的文字颜色

TextOut: 绘制文字

GetLocalTime:获得当前系统的本地时间

结构体类型参考:

SYSTEMTIME: 描述时间类型,包括年月日、时分秒、周

*********************************************************

*/

HINSTANCE g_hInst;//保存操作系统传递进来的"应用程序实例句柄"

typedef struct _stDateTime

{

int nYear;

int nMonth;

int nDay;

}stDateTime;

//定义表格,存储年-2099年的农历信息:每年的大小月、闰月信息、春节所在的公历日期

unsigned int LunarCalendarTable[199] =

{

0x04AE53,0x0A5748,0x5526BD,0x0D2650,0x0D9544,0x46AAB9,0x056A4D,0x09AD42,0x24AEB6,0x04AE4A,/*1901-1910* /

0x6A4DBE,0x0A4D52,0x0D2546,0x5D52BA,0x0B544E,0x0D6A43,0x296D37,0x095B4B,0x749BC1,0x049754,/*1911-1920* /

0x0A4B48,0x5B25BC,0x06A550,0x06D445,0x4ADAB8,0x02B64D,0x095742,0x2497B7,0x04974A,0x664B3E,/*1921-1930* /

0x0D4A51,0x0EA546,0x56D4BA,0x05AD4E,0x02B644,0x393738,0x092E4B,0x7C96BF,0x0C9553,0x0D4A48,/*1931-1940* /

0x6DA53B,0x0B554F,0x056A45,0x4AADB9,0x025D4D,0x092D42,0x2C95B6,0x0A954A,0x7B4ABD,0x06CA51,/*1941-1950* /

0x0B5546,0x555ABB,0x04DA4E,0x0A5B43,0x352BB8,0x052B4C,0x8A953F,0x0E9552,0x06AA48,0x6AD53C,/*1951-1960* /

0x0AB54F,0x04B645,0x4A5739,0x0A574D,0x052642,0x3E9335,0x0D9549,0x75AABE,0x056A51,0x096D46,/*1961-1970* /

0x54AEBB,0x04AD4F,0x0A4D43,0x4D26B7,0x0D254B,0x8D52BF,0x0B5452,0x0B6A47,0x696D3C,0x095B50,/*1971-1980* /

0x049B45,0x4A4BB9,0x0A4B4D,0xAB25C2,0x06A554,0x06D449,0x6ADA3D,0x0AB651,0x093746,0x5497BB,/*1981-1990* /

0x04974F,0x064B44,0x36A537,0x0EA54A,0x86B2BF,0x05AC53,0x0AB647,0x5936BC,0x092E50,0x0C9645,/*1991-2000* /

0x4D4AB8,0x0D4A4C,0x0DA541,0x25AAB6,0x056A49,0x7AADBD,0x025D52,0x092D47,0x5C95BA,0x0A954E,/*2001-2010* /

0x0B4A43,0x4B5537,0x0AD54A,0x955ABF,0x04BA53,0x0A5B48,0x652BBC,0x052B50,0x0A9345,0x474AB9,/*2011-2020* /

0x06AA4C,0x0AD541,0x24DAB6,0x04B64A,0x69573D,0x0A4E51,0x0D2646,0x5E933A,0x0D534D,0x05AA43,/*2021-2030* /

0x36B537,0x096D4B,0xB4AEBF,0x04AD53,0x0A4D48,0x6D25BC,0x0D254F,0x0D5244,0x5DAA38,0x0B5A4C,/*2031-2040* /

0x056D41,0x24ADB6,0x049B4A,0x7A4BBE,0x0A4B51,0x0AA546,0x5B52BA,0x06D24E,0x0ADA42,0x355B37,/*2041-2050* /

0x09374B,0x8497C1,0x049753,0x064B48,0x66A53C,0x0EA54F,0x06B244,0x4AB638,0x0AAE4C,0x092E42,/*2051-2060* /

0x3C9735,0x0C9649,0x7D4ABD,0x0D4A51,0x0DA545,0x55AABA,0x056A4E,0x0A6D43,0x452EB7,0x052D4B,/*2061-2070* /

0x8A95BF,0x0A9553,0x0B4A47,0x6B553B,0x0AD54F,0x055A45,0x4A5D38,0x0A5B4C,0x052B42,0x3A93B6,/*2071-2080* /

0x069349,0x7729BD,0x06AA51,0x0AD546,0x54DABA,0x04B64E,0x0A5743,0x452738,0x0D264A,0x8E933E,/*2081-2090* /

0x0D5252,0x0DAA47,0x66B53B,0x056D4F,0x04AE45,0x4A4EB9,0x0A4D4C,0x0D1541,0x2D92B5

/*2091-2099*/

};

char* TianGanDizhi[60]=

{

"甲子", "乙丑","丙寅","丁卯","戊辰","已巳","庚午","辛未","壬申","癸酉",

"甲戌","乙亥","丙子","丁丑","戊寅","已卯","庚辰","辛巳","壬午","癸未",

"甲申","乙酉","丙戌","丁亥","戊子","已丑","庚寅","辛卯","壬辰","癸巳",

"甲午","乙未","丙申","丁酉","戊戌","已亥","庚子","辛丑","壬寅","癸卯",

"甲辰","乙巳","丙午","丁未","戊申","已酉","庚戌","辛亥","壬子","癸丑",

"甲寅","乙卯","丙辰","丁巳","戊午","已未","庚申","辛酉","壬戌","癸亥"

};

char *ShengXiao[]={"鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","犬","猪"};

char *DayTable[] =

{

"*","初一","初二","初三","初四","初五",

"初六","初七","初八","初九","初十",

"十一","十二","十三","十四","十五",

"十六","十七","十八","十九","二十",

"廿一","廿二","廿三","廿四","廿五",

"廿六","廿七","廿八","廿九","三十"

};

char *WeekTable[] ={"星期天","星期一","星期二","星期三","星期四","星期五","星期六"};

char *MonthTable[] = {"*","正","二","三","四","五","六","七","八","九","十","十一","腊"};

int Days[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};

//定义表格,存储每月日离元旦的天数(不考虑瑞年)

unsigned int MonthAdd[12] = {0,31,59,90,120,151,181,212,243,273,304,334};

//定义用户要显示的年、月、日

unsigned int nCurrentYear=0;

unsigned int nCurrentMonth=0;

unsigned int nCurrentDay=0;

int count = 1; //控制背景图片、

HBITMAP hBkmap;//得到图片

//判断某年是否为公历瑞年

int IsLeapYear(WORD iYear)

{

//错误已更正

if(((iYear%4 == 0)&&(iYear%100 != 0))||(iYear%400 == 0))

return 1;

else

return 0;

}

//公历日期转农历日期的函数

void SunToLunar(const stDateTime* pSunDay,stDateTime* pLunarDay)

{

int i=0;

int SunDiff=0;

int SpringDiff=0;

int nSpringYear=pSunDay->nYear;

int nSpringMonth=1;

int nSpringDay=0;

//计算当前公历日离当年元旦的天数

SunDiff = MonthAdd[pSunDay->nMonth-1] + pSunDay->nDay - 1;

if(IsLeapYear(pSunDay->nYear) && (pSunDay->nMonth > 2) )//若是闰年且大于月,天数再加SunDiff++;

//计算春节所在公历日离元旦的天数:通过查表,计算当年的春节所在的公历日期,

if(((LunarCalendarTable[pSunDay->nYear - 1901] & 0x60)>>5)==1)//若春节在公历月

SpringDiff= (LunarCalendarTable[pSunDay->nYear-1901]&0x1F)-1;

else//若春节在公历月

SpringDiff= (LunarCalendarTable[pSunDay->nYear-1901]&0x1F)-1+31;

//SunDiff和SpringDiff的差就是当前公历日离春节的天数

if(SunDiff>SpringDiff)//公历日在春节后

{

int x = SunDiff - SpringDiff;

int bLunar = (LunarCalendarTable[nSpringYear - 1901] & 0xF00000)>>20;//闰月月份

i=0;

nSpringMonth=1;

for(;;)

{

int a = (LunarCalendarTable[pSunDay->nYear-1901] & (0x80000>>i))>>(19-i);//计算大小月

if(a==0)

a=29;

else

a=30;

if(x

break;

x =x - a;

i++;

nSpringMonth++;

}

nSpringDay =x+1;

//如果有闰月

if(nSpringMonth>bLunar && bLunar>0)

nSpringMonth--;

}

else if(SunDiff

{

int x = SpringDiff-SunDiff;

int nShift=0;

int Shift=0;

int bLunar = (LunarCalendarTable[nSpringYear - 1901-1] & 0xF00000)>>20;//闰月月份

i=0;

nSpringYear--;//需要上一年的农历信息

nSpringMonth=12;//从最后一个月开始计算

if (bLunar == 0)//如果没有闰月

{

nShift = 0x100;

Shift=8;

}

else

{

nShift = 0x80;

Shift=7;

}

for(;;)

{

int a = (LunarCalendarTable[nSpringYear-1901] & (nShift<>(Shift+i);//计算大小月

if(a==0)

a=29;

else

a=30;

if(x<=a)

{

x = a-x;

break;

}

x =x - a;

i++;

nSpringMonth--;

}

nSpringDay =x+1;

if(nSpringMonth0)

nSpringMonth++;

}

else {

nSpringMonth= 1;

nSpringDay = 1;

}

pLunarDay->nYear = nSpringYear;

pLunarDay->nMonth= nSpringMonth;

pLunarDay->nDay = nSpringDay;

}

//根据公历日期获得星期

int GetDayOfWeek(const stDateTime* pSunDay)

{

//根据泰勒公式

//nWeek = [nYear1÷] - 2*nYear1 + nYear2 + [nYear2÷] + [26(nMonth+1)÷] + nDay - 1 int nWeek=0;

int nYear1=pSunDay->nYear/100;//年的前两位数字

int nYear2=pSunDay->nYear%100;//年的后两位数字

int nDay=pSunDay->nDay; //公立日

int nMonth=pSunDay->nMonth;//公立月数,所求的月份如果是月或月,

//则应视为上一年的月或月,

//也就是公式中nMonth的取值范围是从到而不是从到

if(nMonth==1 || nMonth==2)

{

nMonth=12+nMonth;

nYear1=(pSunDay->nYear-1)/100;//年的前两位数字

nYear2=(pSunDay->nYear-1)%100;//年的后两位数字

}

nWeek = nYear1/4 - 2*nYear1 + nYear2 + nYear2/4 + (26*(nMonth+1))/10 + nDay - 1;

if(nWeek >= 0)

nWeek = nWeek%7;//

else

{

nWeek = nWeek%7;

nWeek += 7;

}

return nWeek;

}

//根据公立年得到农历干支年

char* GetGanZhi(int nYear)

{

return TianGanDizhi[nYear%60-4];

}

//根据公立年得到农历生肖

char* GetShengXiao(int nYear)

{

int judge = (nYear%60-3-1)%12;

return (judge >= 0) ? ShengXiao[judge]:ShengXiao[judge+12];

}

int GetShengXiaoID(int nYear)

{

int judge = (nYear%60-3-1)%12;

return (judge >= 0) ? judge:judge+12;

}

//Windows程序入口函数

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd ) {

g_hInst = hInstance;

ShowClockDlg();

}

//日历绘制函数,学员自己实现该函数

void DrawCalendar(HDC hDC,int nWidth,int nHeight)

{

SYSTEMTIME datetime;

int week, i, j = 67, k = 0, days, init;

int a, b, c;//记录阴历年、月、日

char tttt[100];

HDC hdcMem;

HBITMAP hbmp;

BITMAP bmp;

HBRUSH hbrush;

HPEN hpen;

RECT rc;

stDateTime sundate,lunardate,sundate_today;

GetLocalTime(&datetime);//获取当前时间

sundate_today.nDay=datetime.wDay;

sundate_today.nMonth=datetime.wMonth;

sundate_today.nYear=datetime.wYear;

SunToLunar(&sundate_today.nYear,&lunardate);//阳历转阴历

i=lunardate.nYear;//(阴)年

j=lunardate.nMonth;//(阴)月

k=lunardate.nDay;//(阴)日

//--------------------绘制窗体背景,加载背景图片-----------------------------// (count > 12) ? (count = 1): count;

hdcMem = CreateCompatibleDC(hDC);

wsprintf(tttt,"../image/skin/%d.bmp",count);

hdcMem=CreateCompatibleDC(hDC);

hbmp = (HBITMAP)LoadImage(g_hInst,

tttt ,IMAGE_BITMAP,600,500,LR_LOADFROMFILE);

GetObject(hbmp, sizeof(BITMAP), &bmp);

SelectObject(hdcMem,hbmp);

BitBlt(hDC, 0, 0, bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);

DeleteObject(hbmp);

//-----------------------输出阳历当日日期---------------------------------------// hpen=GetStockObject(DEFAULT_GUI_FONT);

SelectObject(hDC,hpen);

SetTextColor(hDC,RGB(250,0,0));

wsprintf(tttt,"今天是%d-%d-%d",datetime.wYear,datetime.wMonth,datetime.wDay);

TextOut(hDC,100,30,tttt,strlen(tttt));

//----------------------输出阴历当日日期----------------------------------------// wsprintf(tttt,"农历%s月%s日",MonthTable[j], DayTable[k]);

TextOut(hDC,300,30,tttt,strlen(tttt));

//----------------------输出天干地支及生肖----------------------------------------// wsprintf(tttt,"%s%s年",GetGanZhi(i),GetShengXiao(i));

TextOut(hDC,15,30,tttt,strlen(tttt));

TextOut(hDC,550,282,"年",2);

TextOut(hDC,550,310,"月",2);

if(nCurrentYear == 0)//如果还没设定当前时间

{

nCurrentDay=datetime.wDay;

nCurrentMonth=datetime.wMonth;

nCurrentYear=datetime.wYear;

}

sundate.nDay=nCurrentDay;

sundate.nMonth=nCurrentMonth;

sundate.nYear=nCurrentYear;

week = GetDayOfWeek(&sundate);

SunToLunar(&sundate,&lunardate);//阳历转阴历

i=lunardate.nYear;//(阴)年

j=lunardate.nMonth;//(阴)月

k=lunardate.nDay;//(阴)日

//设置日历表变化年

hpen=(HPEN)CreateFont(15,10,0,0,9,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_CHARACTER_PRECIS,CLIP_DEFAULT_ PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,"黑体");

SelectObject(hDC,hpen);

SetTextColor(hDC,RGB(250,0,0));//颜色设置

wsprintf(tttt,"%d",sundate.nYear);

TextOut(hDC,500,280,tttt,strlen(tttt));

hpen=GetStockObject(DEFAULT_GUI_FONT);

SelectObject(hDC,hpen);

//设置日历表变化月

hpen=(HPEN)CreateFont(15,10,0,0,9,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_CHARACTER_PRECIS,CLIP_DEFAULT_ PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,"黑体");

SelectObject(hDC,hpen);

SetTextColor(hDC,RGB(250,0,0));//颜色设置

wsprintf(tttt,"%d",sundate.nMonth);

(strlen(tttt)==1) ? TextOut(hDC,525,305,tttt,strlen(tttt)):TextOut(hDC,525,305,tttt,strlen(tttt));

//--------------------输出日历表--------------------------------------------//

hpen=(HPEN)CreateFont(15,8,0,0,9,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_CHARACTER_PRECIS,CLIP_DEFAULT_P RECIS,DEFAULT_QUALITY,DEFAULT_PITCH,"黑体");

SelectObject(hDC,hpen);

SetTextColor(hDC,RGB(120,120,0));//设置日历字体颜色

sundate.nDay=1;

week = GetDayOfWeek(&sundate);

days = Days[nCurrentMonth];//当月有多少天

init = 58;

i = (week-1)*67+init;

j = 105;

(week == 0) ? (j = j-50):j;//如果第一天为星期天

for(k = 1;k<=days;k++)//核心算法

{

SetTextColor(hDC,RGB(255,0,0));//设置星期天颜色

sundate.nDay=k;

sundate.nMonth =nCurrentMonth;

sundate.nYear=nCurrentYear;

SunToLunar(&sundate,&lunardate);//阳历转阴历

a=lunardate.nYear;//(阴)年

b=lunardate.nMonth;//(阴)月

c=lunardate.nDay;//(阴)日

i = i+67;

if((week+k-1)%7==0)//每过一星期换行

{

j = j+50;

i = init;

}

if(k==datetime.wDay && nCurrentYear==datetime.wYear

&& nCurrentMonth==datetime.wMonth)//背景色标注当前日期 {

SetRect (&rc,i-28,j-10, i+38, j+40);

hbrush=CreateSolidBrush(RGB(250,0,0));

FillRect(hDC,&rc,hbrush);

}

SetTextColor(hDC,RGB(250,0,0));//节日颜色

if(sundate.nMonth==1&&sundate.nDay==1)//法定节假日

{

TextOut(hDC,i-10,j,"元旦",4);

}

else if(sundate.nMonth==10&&sundate.nDay==1)

{

TextOut(hDC,i-18,j,"国庆节",6);

}

else

{

if((week+k-1)%7==0 || (week+k-1)%7==6)

SetTextColor(hDC,RGB( 255, 0, 0));//公立日期颜色(周六周天颜色特殊) else

SetTextColor(hDC,RGB( 0, 64, 0));

wsprintf(tttt, "%d", k);//显示公历

TextOut(hDC,i, j,tttt,strlen(tttt));

}

//显示农历

SetTextColor(hDC,RGB(250,0,0));//节日颜色

if(b==1&&c==1)

{

TextOut(hDC,i-10,j+20,"春节",4);//农历节日显示

}

else if(b==1&&c==15)

{

TextOut(hDC,i-18,j+20,"元宵节",6);//农历节日显示

}

else if(b==5&&c==5)

{

TextOut(hDC,i-18,j+20,"端午节",6);//农历节日显示

}

else if(b==8&&c==15)

{

TextOut(hDC,i-18,j+20,"中秋节",6);//农历节日显示

}

else if(c == 1)//每月一号显示当前月,否则显示日期

{

SetTextColor(hDC,RGB(200,0,50));//阴历日期颜色(月份)

wsprintf(tttt, "%s月", MonthTable[b]);//输出阴历时间(月份)

TextOut(hDC,i-10, j+20,tttt,strlen(tttt));

}

else

{

SetTextColor(hDC,RGB(0,128,255));//阴历日期颜色

wsprintf(tttt, "%s", DayTable[c]);

TextOut(hDC,i-10, j+20,tttt,strlen(tttt));

}

hdcMem= CreateCompatibleDC(hDC);//通过光栅运算消除底色

switch((nCurrentYear-4)%12)

{

case 0:

hBkmap = (HBITMAP)LoadImage(g_hInst,

"../Image/shengxiao/1.bmp",IMAGE_BITMAP,50,50,LR_LOADFROMFILE);

break;

case 1:

hBkmap = (HBITMAP)LoadImage(g_hInst,

"../Image/shengxiao/2.bmp",IMAGE_BITMAP,50,50,LR_LOADFROMFILE);

break;

case 2:

hBkmap = (HBITMAP)LoadImage(g_hInst,

"../Image/shengxiao/3.bmp",IMAGE_BITMAP,50,50,LR_LOADFROMFILE);

break;

case 3:

hBkmap = (HBITMAP)LoadImage(g_hInst,

"../Image/shengxiao/4.bmp",IMAGE_BITMAP,50,50,LR_LOADFROMFILE);

break;

case 4:

hBkmap = (HBITMAP)LoadImage(g_hInst,

"../Image/shengxiao/5.bmp",IMAGE_BITMAP,50,50,LR_LOADFROMFILE);

break;

case 5:

hBkmap = (HBITMAP)LoadImage(g_hInst,

"../Image/shengxiao/6.bmp",IMAGE_BITMAP,50,50,LR_LOADFROMFILE);

break;

case 6:

hBkmap = (HBITMAP)LoadImage(g_hInst,

"../Image/shengxiao/7.bmp",IMAGE_BITMAP,50,50,LR_LOADFROMFILE);

break;

case 7:

hBkmap = (HBITMAP)LoadImage(g_hInst,

"../Image/shengxiao/8.bmp",IMAGE_BITMAP,50,50,LR_LOADFROMFILE);

break;

case 8:

hBkmap = (HBITMAP)LoadImage(g_hInst,

"../Image/shengxiao/9.bmp",IMAGE_BITMAP,50,50,LR_LOADFROMFILE);

break;

case 9:

hBkmap = (HBITMAP)LoadImage(g_hInst,

"../Image/shengxiao/10.bmp",IMAGE_BITMAP,50,50,LR_LOADFROMFILE);

break;

case 10:

hBkmap = (HBITMAP)LoadImage(g_hInst,

"../Image/shengxiao/11.bmp",IMAGE_BITMAP,50,50,LR_LOADFROMFILE);

break;

case 11:

hBkmap = (HBITMAP)LoadImage(g_hInst,

"../Image/shengxiao/12.bmp",IMAGE_BITMAP,50,50,LR_LOADFROMFILE);

break;

}

SelectObject(hdcMem,hBkmap);

BitBlt(hDC,500,350,100,100,hdcMem,-10,-10,SRCCOPY);

}

hpen = CreatePen(PS_SOLID, 2, RGB(100,100,100));//设置画笔

SelectObject(hDC, hpen);//为设备环境配置画笔

//画框架

for(i = 95; i < 400; i += 50)//画横线

{

MoveToEx (hDC, 30, i, NULL);

LineTo (hDC, 498, i);

}

for(i = 30; i < 500;i += 67)//画竖线

{

MoveToEx (hDC, i, 95, NULL);

LineTo (hDC, i, 395);

}

//输出文字

j = 70;

hpen=(HPEN)CreateFont(12,5,0,0,4,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_CHARACTER_PRECIS,CLIP_DEFAULT_P RECIS,DEFAULT_QUALITY,DEFAULT_PITCH,"黑体");

hpen=GetStockObject(DEFAULT_GUI_FONT);

SelectObject(hDC,hpen);

SetTextColor(hDC,RGB(255,255,0));

TextOut(hDC,35,76,"星期日",6);

TextOut(hDC,35+j,76,"星期一",6);

TextOut(hDC,35+2*j,76,"星期二",6);

TextOut(hDC,35+3*j,76,"星期三",6);

TextOut(hDC,35+4*j,76,"星期四",6);

TextOut(hDC,35+5*j,76,"星期五",6);

TextOut(hDC,35+6*j,76,"星期六",6);

}

//事件函数:点击日历界面上各个按钮后被调用,学员自己实现该函数

//注意:该函数调用完后,系统自动调用DrawCalendar函数

// 因此,可以理解为,该函数和DrawCalendar函数是联动的

void CalendarButtonEvent(UINT nID)

{

if(nID==IDC_BTN_YEARUP)//点击了"年↑"按钮

nCurrentYear++;

}

else if(nID==IDC_BTN_YEARDOWN)//点击了"年↓"按钮

{

nCurrentYear--;

}

if(nID==IDC_BTN_MONTHUP)//点击了"月↑"按钮

{

if(nCurrentMonth==12)

{

nCurrentYear++;

nCurrentMonth=1;

}

else

{

nCurrentMonth++;

}

}

else if(nID==IDC_BTN_MONTHDOWN)//点击了"月↓"按钮{

if(nCurrentMonth==1)

{

nCurrentYear--;

nCurrentMonth=12;

}

else

{

nCurrentMonth--;

}

}

else if(nID==IDC_BTN_SKIN)

{

//绘制窗体背景,加载背景图片

count++;

}

if(nID==IDC_BTN_TODAY)//今天的按钮

{

SYSTEMTIME DateTime;

GetLocalTime(&DateTime);

nCurrentMonth=DateTime.wMonth;

nCurrentYear=DateTime.wYear;

nCurrentDay=DateTime.wDay;

}

//...

}

//--------------------输出表盘信息--------------------------------------------// void DrawWeek(HDC hDC,int week)//输出表盘的星期

{

HFONT newFont;

int x=35,y=36;

newFont=CreateFont(10,9,0,0,0,0,0,0,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH | FF_DONTCARE,NULL);

SelectObject(hDC,newFont);

switch(week)

{

case 0:

TextOut(hDC,x,y,TEXT("星期日"),6);

break;

case 1:

TextOut(hDC,x,y,TEXT("星期一"),6);

break;

case 2:

TextOut(hDC,x,y,TEXT("星期二"),6);

break;

case 3:

TextOut(hDC,x,y,TEXT("星期三"),6);

break;

case 4:

TextOut(hDC,x,y,TEXT("星期四"),6);

break;

case 5:

TextOut(hDC,x,y,TEXT("星期五"),6);

break;

default:

TextOut(hDC,x,y,TEXT("星期六"),6);

break;

}

}

void DrawGanZhi(HDC hDC,int year)//输出表盘的天干地支

{

char *ch;

TCHAR szBuffer[12];

ch=GetGanZhi(year);

wsprintf(szBuffer,"%s",ch);

SetTextColor(hDC,RGB(2,128,0));//文字颜色

TextOut(hDC,34,72,szBuffer,4);//输出年份

C++万年历实验报告

《高级语言程序设计》课程设计报告万年历程序设计

(1)课程设计名称:C++万年历设计 (2)使用工具软件:Microsoft visual C++ (3)课程设计内容简介 1、以开关语句进行执行功能的选择,这些功能分别是: A、判断闰年; B、判断某天是星期几; C、判断某年的隶属生肖; D、输出某年的日历; E、输出某月的日期; F、退出系统; 2、建立类wnl,定义类的成员函数; void isleapyear(); //判断闰年,用于输出判断结果,以流的形式bool isleap(int year); //判断闰年,返回判断结果,用于计算天数int getdays(int year,int month,int day); //获取据第一天天数 void weekdays(int year,int month,int day);//获取星期几 void printyear(int year); //输出年的日历 void printyearmonth(int year,int month); //输出某年某月的日历 void animal(int year); //判断某年的生肖 int getyear(){return Year;} //返回私有成员的值 int getmonth(){return Month;} int getday(){return Day;} 3、定义私有成员:i nt Year,Month,Day; 4、定义类的对象:_wnl; 5、为类的成员函数填写代码,满足功能实现; 6、运行环境:控制台应用程序的源程序; (4)得意之处: 1、可以满足多功能实现,可以循环执行功能; 2、可以选择每行输出的月份数; 3、有欢迎界面; 4、客户输入错误会有提示; 5、使用了C语言的流的形式,判断闰年,提高执行速度; 6、使用I/O流控制头文件iomanip.h控制月份日历的输出,更加整齐;(5)创意的技术实现

Excel中关于日期的计算公式的运用

Excel中关于日期的计算公式的运用 方法1:在A1单元格输入前面的日期,比如“2004-10-10”,在A2单元格输入后面的日期,如“2005-6-7”。接着单击A3单元格,输入公式 “=DATEDIF(A1,A2,"d")”。然后按下回车键,那么立刻就会得到两者的天数差“240”。 提示: 公式中的A1和A2分别代表前后两个日期,顺序是不可以颠倒的。此外,DATEDIF函数是Excel中一个隐藏函数,在函数向导中看不到它,但这并不影响我们的使用。 方法2:任意选择一个单元格,输入公式“="2004-10-10"-"2005-6-7"”,然后按下回车键,我们可以立即计算出结果。 计算工作时间——工龄—— 假如日期数据在D2单元格。 =DATEDIF(D2,TODAY(),"y")+1 注意: 工龄两头算,所以加“1”。 如果精确到“天”—— =DATEDIF(D2,TODAY(),"y")&"年"&DATEDIF(D2,TODAY(),"ym")&"月 "&DATEDIF(D2,TODAY(),"md")&"日" 二、计算2003-7-617:05到2006-7-713:50分之间相差了多少天、多少个小时多少分钟 假定原数据分别在A1和B1单元格,将计算结果分别放在C 1、"D1和E1单元格。

C1单元格公式如下: =ROUND(B1-A1,0) D1单元格公式如下: =(B1-A1)*24 E1单元格公式如下: =(B1-A1)*24*60 注意: A1和B1单元格格式要设为日期,C 1、"D1和E1单元格格式要设为常规. 三、计算生日,假设b2为生日 =datedif(B2,today(),"y") DATEDIF函数,除Excel2000中在帮助文档有描述外,其他版本的Excel在帮助文档中都没有说明,并且在所有版本的函数向导中也都找不到此函数。但该函数在电子表格中确实存在,并且用来计算两个日期之间的天数、月数或年数很方便。微软称,提供此函数是为了与Lotus1-2-3兼容。 该函数的用法为“DATEDIF(Start_date,End_date,Unit)”,其中Start_date为一个日期,它代表时间段内的第一个日期或起始日期。End_date为一个日期,它代表时间段内的最后一个日期或结束日期。Unit为所需信息的返回类型。 “Y”为时间段中的整年数,“M”为时间段中的整月数,“D”时间段中的天数。“MD”为Start_date与End_date日期中天数的差,可忽略日期中的月和年。“YM”为Start_date与End_date日期中月数的差,可忽略日期中的日和年。“YD”为Start_date与End_date日期中天数的差,可忽略日期中的年。比如,B2单元格中存放的是出生日期(输入____年__月__日时,用斜线或短横线隔开),在C2单元格中输入“=datedif(B2,today(),"y")”(C2单元格的格式为常规),按回车键

嵌入式系统课程设计题目

嵌入式系统课程设计题目 2016.5 共同要求:在LCD上显示设计题目、设计者名字(主设计者在前) 常用外设引脚: LED:LED0(上边)~LED3(下边)分别接PF5~PF9引脚,低电平点亮 按钮:K0(上边)~K3(下边)分别接PA0、PC13、PA8、PD3引脚,另一端均接地,按下为低电平。 蜂鸣器:蜂鸣器BEEP接PB10引脚,为有源蜂鸣器,PB10输出低电平发声 1、频率计设计 所谓频率计,就是每秒的计数值。使用2个通用定时器,一个计时,另一个对外部信号计数,在LCD 上显示出计数值和频率值。 2、用DAC设计低频信号发生器——硬键盘 使用DAC的模拟输出功能,模拟输出正弦波、方波、三角波信号。 用实验板上的4个按钮(K0~K3)控制输出:K3用于循环选择输出的信号类型,K0、K1、K2用于设置输出的频率,K2用于循环选择输出频率的某个位(个十百千万),K0按钮用于对选中的位加1,K1用于对选中的位减1。 在LCD上显示出频率值和输出信号的波形(曲线)。 3、用DAC设计低频信号发生器——软键盘 使用DAC的模拟输出功能,模拟输出正弦波、方波、三角波信号。 在LCD上设计4个触摸屏按钮(K0~K3)控制输出:K3用于循环选择输出的信号类型,K0、K1、K2用于设置输出的频率,K2用于循环选择输出频率的某个位(个十百千万),K0按钮用于对选中的位加1,K1用于对选中的位减1。 在LCD上显示出频率值和输出信号的波形(曲线)。 4、直流电机控制器设计——硬键盘 直流电机控制原理:理论上转速与电压成正比,用PWM控制则与占空比成正比;旋转方向与绕组电流的方向有关,改变绕组接电源的极性,便可改变电机的转向。 使用通用定时器的比较输出引脚,接直流电机的绕组,改变比较寄存器的值,即改变了占空比,便可调速(可以使用ARM实验箱上的直流电机(有驱动),只需把时钟信号和地线接到直流电机上即可)。 用4个按钮分别控制启动、停止、加速、减速;在LCD上显示出电机的转速等级。 5、直流电机控制器设计——软键盘

电子万年历实验1

电子万年历实验 实验要求: 在LCD (12864或者1602)上显示: 年月日 星期 时间 可以 自由修改显示的 年月日 星期 时间 实验需求: 硬件需求: 1.需要按键做初始化等需求 2.需要LED 作为显示输出。 2需要一款硬件作为实时时钟 器件选型 DS1302 实时时钟芯片,三线接口,带涓流充电。 DS1307 实时时钟芯片,I2C 接口。 DS1337 实时时钟芯片,I2C 接口,带两个日历闹钟。 PCF8563 实时时钟芯片,I2C 接口,带中断输出。 PCF8583 实时时钟芯片,I2C 接口,带中断输出,内置的32.768KHz 振荡器,256个字节RAM ,但性价比较差。

选型结论: LCD:12864 键盘:4*4矩阵键盘 实时时钟芯片:DS1302 结构框图 DS1302 DS1302 是DALLAS 公司推出的涓流充电时钟芯片内含有一个实时时钟/日历和31 字节静态RAM 可通过简单的串行接口与单片机进行通信 可提供: --秒分时日日期月年的信息 --每月的天数和闰年的天数可自动调整 --可通过AM/PM 指示决定采用24 或12 小时格式

--保持数据和时钟信息时功率小于1mW

DS1302引脚 X1 X2 32.768KHz 晶振管脚 GND 地 CE 复位脚 I/O 数据输入/输出引脚 SCLK 串行时钟 Vcc1,Vcc2 电源供电管脚 各引脚的功能为: Vcc1:主电源;Vcc2:备份电源。当Vcc2>Vcc1+0.2V时,由Vcc2向DS1302供电,当Vcc2< Vcc1时,由Vcc1向DS1302供电。SCLK:串行时钟,输入,控制数据的输入与输出; I/O:三线接口时的双向数据线; CE:输入信号,在读、写数据期间,必须为高。该引脚有两个功能:第一,CE开始控制字访问移位寄存器的控制逻辑;其次, CE提供结束单字节或多字节数据传输的方法。

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

一个计算万年历的简单程序 通常我们只知道生活当天的前后几天是星期几,即便是翻日历,也只能知道有限日期的星期数。那么有没有一种方法可以让我们知道任何一天是星期几呢?有,下面我将向大家介绍一种方法,用以编写万年历的程序。 首先我们必须约定一些法则,我们用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

基于单片机的GPS时间校准设计

[请输入学校名称] [请输入专业] 基于单片机的GPS时间校准设计 姓名: [请输入姓名] 学号: [请输入学号] 指导教师:[请输入指导教师] 2017年4月21日

摘要: (3) Abstract (4) 第一章概述 (5) 1.1实时时钟研究的背景及意义 (5) 1.2论文主要研究内容 (5) 1.2.1 系统设计实现的目标 (5) 1.2.2 系统的总体设计 (5) 第二章硬件电路设计 (7) 2.1单片机控制部分 (7) 2.2 DS1302时钟芯片部分 (10) 2.3LCD1602液晶显示部分 (12) 2.5.2 1602引脚功能说明 (12) 2.5.3 1602LCD的指令说明及时序 (13) 2.5.4 1602LCD的RAM地址映射及标准字库表 (14) 2.5.5 1602LCD的一般初始化(复位)过程 (16) 2.4.6 1602LCD的电路连接 (16) 2.4 GPS模块VK2828U7G5LF部分 (16) 第三章软件部分设计 (21) 3.1 按键程序流程图 (23) 结束语 (32) 致谢词 (33) 参考文献 (34) 附录 (35) 硬件原理图与PCB图 (35) 源程序: (36)

摘要: 本文介绍了基于STC89C52单片机的多功能电子万年历的硬件结构和软硬件设计方法。本设计由数据显示模块、GPS模块、时间处理模块和按键输入模块四个模块组成。系统以STC89C52单片机为控制器,以DS1302时钟日历芯片DS1302记录日历和时间,它可以对年、月、日、时、分、秒进行计时,还具有闰年补偿等多种功能。GPS模块采用了VK2828U7G5LF,万年历采用直观的数字显示,数据显示采用1602液晶显示模块,可以在LCD1602上同时显示年、月、日、周日、时、分、秒,和GPS模块的工作模式。此万年历具有读取方便、显示直观、功能多样、电路简洁、成本低廉等诸多优点,具有广阔的市场前景。 关键字:单片机,时钟芯片, 温度传感器, 1602液晶显示器

EDA实训万年历

《EDA技术与应用》实训报告指导教师:

实训题目:数字日历 1. 系统设计 1.1 设计要求 1.1.1 设计任务: 设计一个数字日历电路 1.1.2 技术要求: ⑴用Verilog HDL 语言设计一个数字日历。 ⑵数字日历能正确显示年、月、日、时、分和秒。 ⑶通过开关分别控制对年、月、日或时、分、秒校对及自动切换、,并且运用 按钮对年、月、日或时、分、秒校对。 ⑷通过按钮对数码管全部清零。 ⑸拓展功能:添加时钟闹钟功能,并通过LED管显示。 1.2 方案比较: 由于这次实验用到的仪器是EDA实训仪,数码管个数只有八个,因此不能同时显示年、月、日、时、分、秒。但是实训仪的LED管只有12个,因 此在拓展功能时12 小时做一个周期的整点记时显示。在多次的测试和修改 后,得到此最好方案。 1.3 方案论证 1.3.1 总体思路: 通过EDA S程的学习,可知运用Verilog HDL语言设计一个数字日历 括计时器模块(jsq60、j sq24 )、年月日模块(nyr2009)、控制模块 (conr)、校时选择模块(mux_4、显示选择模块(mux_16和闹钟定时模块 (LED1)、闹钟灯模块(nzd);然后将各个模块连接起来画成原理图再下载 到实训仪上,调节开关及按钮来实现数字日历的功能。 1.3.2 设计方案: 总原理图如下:

2 ?各个模块程序的设计 (1)设计一个分频器进行20MHz分频得到实训所需的1Hz的频率 分析:这是个20MHZ寸钟的分频器,将原来EDA实训仪提供的频率为20MHZ 的时钟转换成频率1HZ的时钟,然后输出到有需要的端口,触发模块起作用。 ⑵分别设计一个能显示年月日和时分秒的程序 校准年月日和秒分时的原理图如下: 分析:①当k=0时,开关j1,j2,j3校秒时分然后将信号分别送到jsq24模块的jm(校秒)、jf (校分)、js (校时)。 ②当k=1时,开关j1,j2,j3校年月日然后将信号分别送到nyr2009模块的jr(校日)、jy (校月)、jn (校年)。 计算年月日的模块如下: FIHI Ilk m ■!:! 下町nr TUT TFT) H'j 31 , mzitc' FIH iOS H<匚; rm c 计七匚― H ?- i-im LTJ rn ?■ FIM Cl | r-NLCs' M'l t Fl处i/l FIW反

电子表格日期公式

竭诚为您提供优质文档/双击可除 电子表格日期公式 篇一:excel中几个时间计算公式 假设b2为生日 =datedif(b2,today(),"y") datediF函数,除excel2000中在帮助文档有描述外,其他版本的excel在帮助文档中都没有说明,并且在所有版本的函数向导中也都找不到此函数。但该函数在电子表格中确实存在,并且用来计算两个日期之间的天数、月数或年数很方便。微软称,提供此函数是为了与lotus1-2-3兼容。 该函数的用法为 “datediF(start_date,end_date,unit)”,其中start_date 为一个日期,它代表时间段内的第一个日期或起始日期。end_date为一个日期,它代表时间段内的最后一个日期或结束日期。unit为所需信息的返回类型。 “y”为时间段中的整年数,“m”为时间段中的整月数,“d”时间段中的天数。“md”为start_date与end_date日期中天数的差,可忽略日期中的月和年。“ym”为start_date 与end_date日期中月数的差,可忽略日期中的日和年。“yd”

为start_date与end_date日期中天数的差,可忽略日期中的年。比如,b2单元格中存放的是出生日期(输入年月日时,用斜线或短横线隔开),在c2单元格中输入 “=datedif(b2,today(),"y")”(c2单元格的格式为常规),按回车键后,c2单元格中的数值就是计算后的年龄。此函数在计算时,只有在两日期相差满12个月,才算为一年,假如生日是20xx年2月27日,今天是20xx年2月28日,用此函数计算的年龄则为0岁,这样算出的年龄其实是最公平的。 身份证号提取年龄 =datediF(--text((len(a1)=15)*19”即可获得当时的日期时间; 2、使用公式:用=now()而非=date(),=date()只有日期,然后进行菜单“工具->选项”,选择“重新计算”页,选中“人工重算”,勾不勾选“保存前自动重算”看自己的需要和想法了,如果勾选了,那日期时间那总是最后一次保存的日期时间,不勾选的话,如果你的表格中有公式记得准备存前按F9 篇二:excel函数--时间和日期函数 时间和日期函数 1.date 用途:返回代表特定日期的序列号。

简单万年历设计

信电学院 电子信息工程专业CDIO一级项目项目设计说明书(2013/2014学年第一学期) 项目名称:简单万年历的设计 专业班级:电子信息工程 学生姓名: 学号: 指导教师: 设计周数:一周 设计成绩: 2013 年12 月29 日

目录 1项目设计目的及任务--------------------------------------------------------------2 2 设计方案--------------------------------------------------------------2 3 电路仿真与分析--------------------------------------------------------------9 4项目设计心得-------------------------------------------------------------17 5参考文献-------------------------------------------------------------17

1.项目设计目的及任务 用51单片机或52单片机为主体,设计并制作一台数字万年历。基本要求有时钟显示(时/分/秒);日期、星期显示,可设定月份;上电即可显示当前系统的时间该系统的设计电路是以 AT89C51单片机为核心控制器,其外围电路主要包括时钟模块,液晶模块,和与电脑主机通信模块等。通过 PC 机在 Internet 上同步时间,整个系统使用C语言进行编程,实现其设计的各种功能。输出方式灵活、功耗低、计时准确、性能稳定、维护方便等优点。实用电子时钟是一个时间控制系统,既能作为一般的时间显示器,同时可以根据需要扩展其功能。系统上电自检后,实时实现小时、分钟、秒以及日历的显示等指示信息的显示,通过按键可实现校对时间等功能。 2 设计方案 2.1总方案设计:设计简单万年历一般有三个可行方案,方案一:纯硬件电路系统,各功能采用分离的硬件电路模块实现。用时序逻辑电路实现时钟功能,用555定时器实现闹钟的设定。但这种实现方法可靠性差、控制精度低,灵活性小、线路复杂、安装调试不方便,而且不方便实现对系统的扩展。方案二:用可编程逻辑器件(PLD)实现。这种方案与前一种相比,可靠性增加,同时可以很好的完成时钟的功能。同时这种方案只能选用数码管显示,显示的效果不够理想,无法很好的完成扩展功能的要求。同时,系统的灵活性不够。方案三:采用单片机作为系统的控制核心。随着国内超大规模集成电路的出现,微处理器及其外围芯片有了迅速的发展。集成技术的最新发展之一是将CPU和外围芯片,如程序存储器、数据存储器、并行I/O口、串行I/O口、定时/计数器、中断控制器及其他控制部件集成在一个芯片之中,制成单片计算机。而近年来推出的一些高档单片机还包括有许多特殊功能单元,如A/D、D/A转换器、调制解调器、通信控制器、锁相环、DMA、浮点运算单元、PWM控制输出单元、PWM输出时的死区可编程控制功能等。因此,只要外加一些扩展电路及必要的通道接口就可以构成各种计算机应用系统,如工业流水线控制系统、作为家用电器的主控制器、分布式控制系统的终端节点或作为其主控制节点起中继的作用、数据采集系统、自动测试系统等。我们选用的是方案三。因为单片机的出现,并在各技术领域中得到如此迅猛的发展,与单片机构成计算机应用系统所形成的下述特点有关:

万年历实验报告

篇一:电子万年历实验报告 重庆电力高等专科学校 计算机科学系 实训报告 课程名称 实验名称 班级信息0911 姓名廖林单片机应用技术电子万年历 学号 200903020243 教师任照富 日期 2010-12-28 地点一教七机房一、实训任务: 1、看实训要求,计划出自己实训所要用元件,在网上查找资料。 2、思考仿真原理图,然后画出来(具体i/o口暂时不确定)。 3、在网上找一些程序,然后自己改一些,进行编译。 4、编译无误之后,跟原理图相联系,完成最终的仿真图。 5、进行最后的改写,把程序和仿真原理图确定下来。 6、根据仿真图形,制作出实物图。 7、在实物制作过程中,进行电路检查和最后的调试。 二、实训要求: 要求:能显示阳历的年、月、日、星期、时、分、秒; 能显示阴历的年、月、日; 能进行日期、时间的调整。 扩展:能显示当前温度; 有闹钟功能(至少2个) 选择ds1302时钟芯片,温度传感器采用ds18b20数字温度传感器。 三、实训环境(软件、硬件): 软件:keil protues7.5 硬件:计算机2单片机的应用 四、实训意义:在这快速发展的年代,时间对人们来说是越来越宝贵,在快节奏的生活时,人们往往忘记了时间,一旦遇到重要的事情而忘记了时间,这将会带来很大的损失。因此我们需要一个定时系统来提醒这些忙碌的人,而数字化的钟表给人们带来了极大的方便。由于单片机具有灵活性强、成本低、功耗低、保密性好等特点,所以电子日历时钟一般都以单片机为核心,外加一些外围设备来实现。 电子万年历作为电子类小设计不仅是市场上的宠儿,也是是单片机实验中一个很常用的题目。因为它的有很好的开放性和可发挥性,因此对作者的要求比较高,不仅考察了对单片机的掌握能力更加强调了对单片机扩展的应用。而且在操作的设计上要力求简洁,功能上尽量齐全,显示界面也要出色。所以,电子万年历无论作为竞赛题目还是毕业设计题目都是很有价值。对于这个实验项目,我们还要有一些其他的基本知识掌握和意义:(1)在学习了《数字电子技术》和《单片机原理及接口技术》课程后,为了加 深对理论知识的理解,学习理论知识在实际中的运用,为了培养动手能力和解决实际问题的经验,了解专用时钟芯片ds1302,并会用ds1302芯片开发时钟模块,应用到其他系统中去。熟悉keil和protues软件调试程序和仿真. (2)通过实验提高对单片机的认识; (3)通过实验提高焊接、布局、电路检查能力; (4)通过实验提高软件调试能力; (5)进一步熟悉和掌握单片机的结构及工作原理。

带温度计的万年历

设计课题题目: 带温度计的万年历 一、设计任务与要求 1. 显示准确的北京时间(时、分、秒)及公历日期显示功能(年、月、日); 2. 可通过按键切换年、月、日及时、分、秒的显示状态; 3. 可随时可以调校年、月、日或时、分、秒; 4. 可每次增减一进行时间调节,也可快速增减进行时间调节; 5. 可显示环境温度。 二、系统设计方案 方案一、用主芯片为AT89C51的单片机控制实现,使用单片机内部的定时计数器实现时间的设定,使用按键进行时间的调整和定时,按键有蜂鸣器提示,温度传感器使用DALLAS 公司生产的单总线式数字温度传感器,它具有微型化、低功耗、高性能、抗干扰能力强、易配处理器等优点。显示时间和温度使用数码管显示。 方案二、用主芯片为STC89C52的单片机控制实现,为了满足单片机系统的实时控制的需求,采用实时钟芯片DS1302,使用按键进行时间的调整和定时,温度传感器使用 DS18B20。显示时间和温度使用LCD1602显示。 方案一片内定时器会导致计时节拍的时间误差,当进行年、月、日的日历计时,定时中断误差扥积累就会很大。使用片内定时器进行计时的时候,单片机始终要处于工作状态。才能维持计时时间,一旦停机或进入待机状态,开机后,计时时间就需要重新设定。为了满足单片机系统的实时钟需求,本设计采用的是方案二,系统框图如图2-1所示。 图2-1 三、单元电路分析与设计 1. 原理分析 1.1主控制器 单片机STC89C52 具有低电压供电和体积小等特点,如图3-1所示。

1.2晶振电路 AT89S52引脚XTAL1和XTAL2与晶体振荡器及电容C1、C2按图3-2所示方式连接。晶振、电容C1/C2及片内与非门(作为反馈、放大元件)构成了电容三点式振荡器,振荡信号频率与晶振频率及电容C1、C2的容量有关,但主要由晶振频率决定,范围在0~33MHz 之间,电容C1、C2取值范围在5~30pF 之间。 根据实际情况,本设计晶振选择频率为12MHZ ,电容选择30pF 如图3-2。经计算得单片机工作的机器周期为:12×(1÷12M )=1us 。振荡器的振荡信号从XTAL2端输入到片内的时钟发生器上。时钟发生器是个二分频的触发器,它将振荡器的信号频率fosc 除以2,向CPU 提供两相时的时钟号。 1.3复位电路 时钟电路工作后, 芯片内部开始进行初始复位,如图3-3 。 1.4 LCD 显示电路 显示器是单片机常用的功能单元之一,显示器的工作是由单片机通过显示接口驱动的。本设计采用的是LCD1602显示电路图如图3-4所示。

万年历_开题报告

xxxxx 毕业论文(设计) 开题报告 题目基于年历设计 学院电气工程学院 年级 xxx级 专业电子信息工程 姓名宋飞 学号 2011588693 指导教师欧阳飞 教务处制表 2012年12月10日

一、选题依据 课题来源、选题依据和背景情况;课题研究目的、学术价值或实际应用价值时间对人们来说总是那么宝贵,工作的忙碌和繁杂容易使人忘记当前的时间。然而遇到重大事情的时候,一旦忘记时间,就会给自己和他人带来很大的麻烦。平时我们要求上班准时,约会或召开会议必然要提及时间:火车要准点到达,航班要准点起飞;工业生产中,很多环节都需要用时间来确定工序替换时刻。所以说能随时准确的知道时间并利用时间,是我们生活和工作中必不可少的。 想知道时间,手表当然是一个很好的选择,但是,在忙碌当中,我们还需要个“助理”及时的给我们提醒时间。所以,计时器最好能够拥有个定时系统,随时提醒容易忘记时间的人。最早能够定时、报时的时钟属于机械式钟农,但这种时钟受到机械结构、动力和体积的限制,在功能、性能以及造价上都没办法与电子时钟相比。 电子万年历是采用电子电路实现对时、分、秒进行数字显示的计时装置,广泛应用于个人家庭、车站、码头办公室等公共场所,成为人们日常生活中不可少的必须品。由于数字集成电路的发展和石英晶体振荡器的广泛应用,使得数字钟的精度,远远超过老式钟表,钟表的数字化给人们生产生活带来了极大的方便,而且大大地扩展了钟表原先的报时功能。诸如定时报警、按时自动打铃、定时广播、自动启闭灯箱、通断动力设备、甚至各种定时电气的自动启动等,所有这些,都是以钟表数字化为基础的。因此,研究数字钟及扩大其应用,有着非常现实的意义。单片机开发技术已成为电子信息、电气、通信、自动化、机电一体化等专业技术人员必须掌握的技术。在国内:单片机的学习呈上升趋势,但很多人学习是无头绪,不知道从何入手,行业发展迅速,国内生产技术不断提升。国内企业为了获得更大的投资收益,在生产规模和产品质量上不断提升,开发单片机呈必然趋势。我国生产的电子万年历有很多,总体上来说是研究多功能电子万年历为主,使万年历除了具有原来的时间、日期等基本功能外,还具有闹钟,报警等功能,商家生产的电子万年历更从质量、价格、实用上考虑不断改变电子万年历的设计,使其更有市场。在科技发达的今天,智能化必将是以后的发展趋势,所以开发活和学习单片机是社会发展的必然需求。

万年历课程设计实验报告

百度文库- 让每个人平等地提升自我 黄淮学院 JAVA 课程设计报告 题目:《万年历》课程设计 学院:信息工程学院 专业:计算机科学与技术 班级:计科1101班 指导老师: 二0一三年六月

目录 前言 (2) 1需求分析 (2) 1.1需求分析 (2) 1.2功能设计 (3) 2.概要设计 (3) 2.1程序设计思路 (3) 3.流程图 (5) 4.程序的主要类,和说明: (6) C (17) F (18) G (18) I (19) M (19) S (19) U (20) 类分层结构 (20) 接口分层结构 (21) 前言 Java的前身是Oak,它一开始只是被应用于消费性电子产品中。后来它的开发者们发现它还可以被用于更大范围的Internet上。1995年,Java语言的名字从Oak编程了Java。1997年J2SE1.1发布。1998年J2SE1.2发布,标志Java2的诞生。十多年来,Java编程语言及平台成功地运用在网络计算及移动等各个领域。Java的体系结构由Java语言、Java class、Java API、

Java虚拟机组成。它具有简单、面向对象、健壮、安全、结构中立、可移植和高效能等众多优点。Java支持多线程编程,Java运行时系统在多线程同步方面具有成熟的解决方案。Java的平台标准有Java ME,Java SE和Java EE。Java发展到今天,它的卓越成就及在业界的地位毋庸置疑。目前在众多的支持Java的开发工具中主要的7有Java Development Kit,NetBeans,Jcreator,JBuilder,JDeveloper和Eclipse等。其中Java Development Kit 简称JDK是大多开发工具的基础。以上的每种开发工具都 有优缺点,对于开发者来说,重要的是要根据自己的开发规模、开发内容和软硬件环境等因素来选择一种合适的开发工具。 1需求分析 1.1需求分析 本程序的要求为:1.使用图形用户界面;2.本程序能够实现日期与星期的查询。 1.2功能设计 本程序要构建的万年历程序,其功能有以下几个方面: (1)实现图形界面,通过简单的单击按钮能实现查询日期操作。 (2)能以月历形式显示日期与星期。 (3)提供月份的下拉形式菜单来选择月份。 2.概要设计 2.1程序设计思路 (1)日期类的设计: 设定日期年的方法 public void changeYear(String year){ cal.set(Calendar.YEAR,Integer.parseInt(year)) ; updateCalendar();//每次修改年后,更新日期

万年历生产工艺实训报告

“电子产品综合设计”课程 基于单片机带温度的液晶万年历 设计报告书 \ 目录 1 绪论....................................................................................错误!未定义书签。 2 设计要求及设计框图 (3) 2.1 设计要求 (3) 2.2 设计框图 (3)

3 知识要点..........................................................................错误!未定义书签。 3.1 LMO16L液晶模块 (3) 3.2 基于Proteus ISIS 7的液晶模块仿真 (4) 3.3 时钟芯片DS1302 (10) 3.3.1 DS1302的控制字节 (4) 3.3.2 数据输入输出(I/O) (11) 3.3.3 DS1302的寄存器 (4) 3.4 DS18B20数字温度传感器 (12) 3.4.1技术性能描述 (12) 3.4.2 DS18B20主要的数据部件 (13) 3.4.4 DS18B20的主要特性...............................................错误!未定义书签。 4 生产技术文件 (5) 4.1设计电路图 (5) 4.2技术说明 (6) 4.3技术说明 (7) 4.4元器件明细表 (8) 4.5PCB板工艺流程图 (9) 4.6工艺流程图 (10) 4.7印制板装配图 (11) 4.8印制板工艺说明 (12) 4.9制造工艺 (13) 4.10焊接工艺说明 (14) 4.11工具明细表 (15) 5作业指导书 (16) 5.1人员分配 (17) 5.2岗位操作指导书 (18) 5.3安全职责规程 (19) 5.4附 (20) 6设计总结 (20) 1、绪论 1.1课题背景 现在电子产品制造业的发展日新月异,产品的电路、功能设计和生产工艺在不断提升。电子产品生产的指导思想是按照发展要有新思路、改革要有新突破、开放要有新局面、工

万年历时钟实验报告

万年历时钟设计报告 专业: 年级: 姓名: 学号: 指导老师:

万年历的设计与仿真 一、实验目的; 电子时间显示器现在在任何地方都有涉及到,例如电子表和商场、车站的时间显示等等,所以它是一种既方便又实用的技术,而我们所做的万年历则是在它的基础上做出来的,通过万年历的制作,我们可以进一步了解计数器的使用,了解各个进制之间的转换,以及他的任意进制计数器的构成方法等,并且进一步了解74LS160以及74ls90的性质,以及门电路的使用等。 二、实验要求: A. 设计一个能显示“年月日”、“星期”、“时分秒“的十进制万年历时钟显示器; B. 要求要满足一天24小时,一小时60分,一分60秒; C. 关于显示星期天时,要用8来代替; D. 年月日显示时,要满足大月31天,小月30天,闰年二月29天,平年二月28天; 三、实验器材: ISIS 仿真软件、一些常用逻辑门(与门、非门,或门等); 本实验要用到得芯片有:74ls160 74ls161 74ls160 74ls160: 74ls160是一块十进制上升沿触发计数器如右下图: 其中MR 是异步清零端,LOAD 是同步置数端 CLK 是时钟脉冲输入端;D0、D1、D2、D3是 置数输入端,Q0、Q1、Q2、Q3是计数输出端, RCO 是进位端; 74ls161与74ls160的功能基本相同,74ls160是十进制的,而74ls161是十六进制的。 异步清零端 进位端 同步置数端

置九端 74ls90: 74ls90是一块二—五—十进制计数器其图如下: 其中 2、3端为置零端,6、7端为置九端, CKB 为五进制脉冲输入端,CKA 二进制脉冲输入端, ,Q0、Q1、Q2、Q3是计数输出端; LED 七段显示器: 其功能是将BCD 码以十进制形式显示出来,其图如下: 四、万年历时钟构架图: 万年历时钟显示器需要有显示“年”、“月”、“日”、“星期”、“时”、“分” “秒”的功能,又根据它们之间的进位和置位关系 可知,它们主要有以下各部分组成,其整个电路的 框架图如下图所示: 五进制脉冲输入端 置零端 二进制脉冲输入端

钟表维修工

深圳市职业技能鉴定(钟表维修工)考试大纲 1.职业概况 1.1 职业名称:钟表维修工 1.2职业定义:使用专业工具和检测仪器,对机械、电子钟表进行检测、维修、保养的人员。 1.3 职业等级:本大纲共设三个等级:初级、中级、高级。 1.4 适用对象与基本文化程度 (1)适用对象:从事或准备从事本职业的人员。 (2)基本文化程度:初中毕业及以上。 1.5培训期限要求:初级不少于200标准学时;中级不少于200学时;高级不少于220学时。 1.6申报条件: ——初级(具备以下条件之一者) (1)本职业连续工作2年以上。 (2)经维修初级工培训达到标准学时数,并取得结业证书。 ——中级(具备以下条件之一者) (1)连续从事本职业工作7年以上。 (2)取得本职业初级工等级证书后,连续从事本职业工作5年以上。 (3)取得维修初级工等级证书满3年,经维修中级工培训达到标准学时数,并取得结业证书。 (4)取得经教育或劳动保障行政部门审核认定的、以中级技能为培养目标的中等以上职业学校本职业(专业)毕业证书。 ——高级(具备以下条件之一者) (1)取得本职业中级工职业资格证书后,连续从事本职业工作7年以上。 (2)取得本职业中级工职业资格证书后, 连续从事本职业工作4年以上,经本职业高级工培训达到标准学时数,并取得结业证书。 (3)取得经教育或劳动保障行政部门审核认定的、以高级技能为培养目标的高等以上职业学校(含高级技工学校)本职业(专业)毕业证书。 1.7 鉴定方式 分为理论知识考试与技能操作考核。理论知识考试采用闭卷笔试方式,技能操作考核采用现场实际操作方式。理论知识考试和技能操作考核均实行百分制,成绩达到60分以上者为合格。 1.8鉴定时间: 理论知识考试时间:各等级均为120分钟。 技能操作考核时间:初级90分钟,中级、高级110分钟。 1.9考评人员与考生配比: 理论知识考试考评人员与考生配比为1:15,每个标准教室不少于2名考评人员;技能操作考核考评员与考生配比为1:10,且不少于3名考评员。 2.基本要求: 2.1职业道德 2.1.1职业道德基本知识 2.1.2职业守则 (1)遵纪守法,敬业爱岗;遵守行业规定,不弄虚作假。 (2)工作认真负责,自觉履行职责。 (3)文明礼貌,热情待客,全心全意为消费者服务。 (4)刻苦学习,勤奋钻研,不断提高自身素质。 (5)谦虚谨慎,团结协作,主动配合。 (6)遵守操作规程,爱护仪器设备。 2.2基础知识 2.2.1机械传动基础 (1)机械传动原理。 (2)各种传动部件。

电子万年历

河北科技师范学院课程设计说明书 题目: 学院(系): 年级专业: 学号: 学生姓名: 指导教师:

摘要 本设计是电子万年历。具备三个功能:能显示:年、月、日、时、分、秒及星期信息,并具有可调整日期和时间功能。 我选用的是单片机8052来实现电子万年历的功能。该电子万年历能够成功实现时钟运行,调整,显示年月日时分秒及星期,温度等信息。 该电子万年历使用12MHZ晶振与单片机8052相连接,通过软件编程的方法实现了以24小时为一个周期,同时显示小时、分钟和秒的要求。利用单片机定时器及计数器产生定时效果通过编程形成数字钟效果,再利用数码管动态扫描显示单片机内部处理的数据。同时通过端口读入当前外部控制状态来改变程序的不同状态,实现不同功能。 电子万年历设计与制作可采用数字电路实现,也可以采用单片机来完成。若用数字电路完成,所设计的电路相当复杂,大概需要十几片数字集成块,其功能也主要依赖于数字电路的各功能模块的组合来实现,焊接的过程比较复杂,成本也非常高。若用单片机来设计制作完成,由于其功能的实现主要通过软件编程来完成,这样一来就降低了硬件电路的复杂性,从而使得其成本降低,更适合我们大学生自主研发。所以在该设计与制作中我选用了单片机8052,它是低功耗、高性能的CMOS型8位单片机。片内带有4KB的Flash存储器,且允许在系统内改写或用编程器编程。另外, 单片机8052的指令系统和引脚与8051完全兼容,片内有128B 的RAM、32条I/O口线、2个16位定时计数器、5个中断源、一个全双工串行口等。 因此,采用单片机8052原理制作的电子万年历,不仅仅在原理上能够成功实现计时等功能,也更经济,更适用,更符合我们实际生活的需要,对我们大学生来说也更加有用。

根据公历日期计算星期的公式

根据公历日期计算星期的公式 蔡勒(Zeller)公式:是一个计算星期的公式,随便给一个日期,就能用这个公式推算出是星期几。 公式如下: W = [C/4] - 2C + y + [y/4] + [13 * (M+1) / 5] + d - 1 公式中的符号含义如下: w:星期;(w对7取模得:0-星期日,1-星期一,2-星期二,3-星期三,4-星期四,5-星期五,6-星期六) c:世纪(前两位数) y:年(后两位数) m:月(m大于等于3,小于等于14,即在蔡勒公式中,某年的1、2月要看作上一年的13、14月来计算,比如2003年1月1日要看作2002年的13月1日来计算) d:日 [ ]代表取整,即只要整数部分。 下面以中华人民共和国成立100周年纪念日那天(2049年10月1日)来计算是星期几,过程如下: w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1 =49+[49/4]+[20/4]-2×20+[26×(10+1)/10]+1-1 =49+[12.25]+5-40+[28.6] =49+12+5-40+28 =54 (除以7余5) 即2049年10月1日(100周年国庆)是星期五。 再比如计算2006年4月4日,过程如下: w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1 =6+[6/4]+[20/4]-2*20+[26*(4+1)/10]+4-1 =-12 (除以7余2,注意对负数的取模运算!) 不过,以上的公式都只适合于1582年(我国明朝万历十年)10月15日之后的情形。罗马教皇格里高利十三世在1582年组织了一批天文学家,根据哥白尼日心说计算出来的数据,对儒略历作了修改。将1582年10月5日到14日之间的10天宣布撤销,继10月4日之后为10月15日。 后来人们将这一新的历法称为“格里高利历”,也就是今天世界上所通用的历法,简称格里历或公历。 若要计算1582年10月4日及之前的日期是星期几,则公式为:

相关文档