单片机课设 电子万年历.docx

上传人:b****6 文档编号:6359387 上传时间:2023-01-05 格式:DOCX 页数:25 大小:140.26KB
下载 相关 举报
单片机课设 电子万年历.docx_第1页
第1页 / 共25页
单片机课设 电子万年历.docx_第2页
第2页 / 共25页
单片机课设 电子万年历.docx_第3页
第3页 / 共25页
单片机课设 电子万年历.docx_第4页
第4页 / 共25页
单片机课设 电子万年历.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

单片机课设 电子万年历.docx

《单片机课设 电子万年历.docx》由会员分享,可在线阅读,更多相关《单片机课设 电子万年历.docx(25页珍藏版)》请在冰豆网上搜索。

单片机课设 电子万年历.docx

单片机课设电子万年历

 

《单片机原理及应用》

课程设计

题目:

万年历设计

姓名:

学号:

系别:

专业:

年级:

2008

起讫日期:

2010.11.22~2010.12.3

指导教师:

职称:

 

目录

 

1.设计概述…………………………………………………………1

2.硬件电路图………………………………………………………3

3.软件设计…………………………………………………………5

3.1流程图…………………………………………………………5

3.2程序……………………………………………………………7

4.结论

4.1测试结果………………………………………………………12

4.2遇到问题………………………………………………………12

5.3如何解决………………………………………………………12

5.参考文献…………………………………………………………13

附录:

电路图………………………………………………………………15

组员分工……………………………………………………………14

1、设计概述

单片机就是微控制器,是面向应用对象设计、突出控制功能的芯片。

单片机接上晶振、复位电路和相应的接口电路,装载软件后就可以构成单片机应用系统。

将它嵌入到形形色色的应用系统中,就构成了众多产品、设备的智能化核心。

本设计就是应用单片机强大的控制功能制作而成的电子万年历,该电子万年历包括三大功能:

实时显示年、月、日、时、分、秒、周期。

本设计采用的是AT89S52单片机,该单片机采用的MCU51内核,因此具有很好的兼容性,内部带有8KB的ROM,能够存储大量的程序。

计时芯片采用DALLAS公司的涓细充电时钟芯片DS1302,该芯片通过简单的串行通信与单片机进行通信,时钟/日历电路能够实时提供年、月、日、时分、秒信息。

显示器件采用通用型1602液晶,可显示32个字符,如果使用数码管来做显示器件需消耗大量的系统资源,因此采用低功耗的1602液晶,该液晶显示方便,功能强大,完全能满足数字万年历的显示要求。

综上各方案所述,对此次作品的方案选定:

采用AT89S52作为主控制系统;DS1302提供时钟;LCD液晶显示屏作为显示。

通过此次设计能够更加牢固的掌握单片机的应用技术,增强动手能力、硬件设计能力以及软件设计能力。

2、硬件电路图

1.时钟芯片

 

2.LCD1602液晶显示屏

3.单片机芯片C52

3、软件设计

3.1流程图

 

 

主程序流程图

 

 

3.2程序

#include

#include

//#include"LCD1602.h"

//#include"DS1302.h"

#defineuintunsignedint

#defineucharunsignedchar

sbitDS1302_CLK=P1^7;//实时时钟时钟线引脚

sbitDS1302_IO=P1^6;//实时时钟数据线引脚

sbitDS1302_RST=P1^5;//实时时钟复位线引脚

sbitACC0=ACC^0;

sbitACC7=ACC^7;

charhide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year;//秒,分,时到日,月,年位闪的计数

sbitSet=P2^0;//模式切换键

sbitUp=P2^1;//加法按钮

sbitDown=P2^2;//减法按钮

sbitout=P2^3;//立刻跳出调整模式按钮

chardone,count,temp,flag,up_flag,down_flag;

ucharTempBuffer[5],week_value[2];

voidshow_time();//液晶显示程序

/***********1602液晶显示部分子程序****************/

//PortDefinitions**********************************************************

sbitLcdRs=P2^5;

sbitLcdRw=P2^6;

sbitLcdEn=P2^7;

sfrDBPort=0x80;//P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口

//内部等待函数

//**************************************************************************

unsignedcharLCD_Wait(void)

{LcdRs=0;LcdRw=1;_nop_();LcdEn=1;_nop_();LcdEn=0;returnDBPort;}

//向LCD写入命令或数据

//************************************************************

#defineLCD_COMMAND0//Command

#defineLCD_DATA1//Data

#defineLCD_CLEAR_SCREEN0x01//清屏

#defineLCD_HOMING0x02//光标返回原点

voidLCD_Write(bitstyle,unsignedcharinput)

{LcdEn=0;LcdRs=style;LcdRw=0;_nop_();DBPort=input;_nop_();//注意顺序

LcdEn=1;_nop_();//注意顺序

LcdEn=0;_nop_();LCD_Wait();

}

//设置显示模式************************************************************

#defineLCD_SHOW0x04//显示开

#defineLCD_HIDE0x00//显示关

#defineLCD_CURSOR0x02//显示光标

#defineLCD_NO_CURSOR0x00//无光标

#defineLCD_FLASH0x01//光标闪动

#defineLCD_NO_FLASH0x00//光标不闪动

voidLCD_SetDisplay(unsignedcharDisplayMode)

{LCD_Write(LCD_COMMAND,0x08|DisplayMode);}

//设置输入模式************************************************************

#defineLCD_AC_UP0x02

#defineLCD_AC_DOWN0x00//default

#defineLCD_MOVE0x01//画面可平移

#defineLCD_NO_MOVE0x00//default

voidLCD_SetInput(unsignedcharInputMode)

{LCD_Write(LCD_COMMAND,0x04|InputMode);}

//初始化LCD************************************************************

voidLCD_Initial()

{LcdEn=0;

LCD_Write(LCD_COMMAND,0x38);//8位数据端口,2行显示,5*7点阵

LCD_Write(LCD_COMMAND,0x38);

LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR);//开启显示,无光标

LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);//清屏

LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE);//AC递增,画面不动

}

//液晶字符输入的位置************************

voidGotoXY(unsignedcharx,unsignedchary)

{if(y==0)LCD_Write(LCD_COMMAND,0x80|x);

if(y==1)LCD_Write(LCD_COMMAND,0x80|(x-0x40));}

//将字符输出到液晶显示

voidPrint(unsignedchar*str)

{while(*str!

='\0')

{LCD_Write(LCD_DATA,*str);str++;}}

/***********DS1302时钟部分子程序******************/

typedefstruct__SYSTEMTIME__

{

unsignedcharSecond;

unsignedcharMinute;

unsignedcharHour;

unsignedcharWeek;

unsignedcharDay;

unsignedcharMonth;

unsignedcharYear;

unsignedcharDateString[11];

unsignedcharTimeString[9];

}SYSTEMTIME;//定义的时间类型

SYSTEMTIMECurrentTime;

#defineAM(X)X

#definePM(X)(X+12)//转成24小时制

#defineDS1302_SECOND0x80//时钟芯片的寄存器位置,存放时间

#defineDS1302_MINUTE0x82

#defineDS1302_HOUR0x84

#defineDS1302_WEEK0x8A

#defineDS1302_DAY0x86

#defineDS1302_MONTH0x88

#defineDS1302_YEAR0x8C

voidDS1302InputByte(unsignedchard)//实时时钟写入一字节(内部函数)

{unsignedchari;ACC=d;for(i=8;i>0;i--)

{DS1302_IO=ACC0;//相当于汇编中的RRC

DS1302_CLK=1;DS1302_CLK=0;ACC=ACC>>1;}}

unsignedcharDS1302OutputByte(void)//实时时钟读取一字节(内部函数)

{unsignedchari;for(i=8;i>0;i--)

{ACC=ACC>>1;//相当于汇编中的RRC

ACC7=DS1302_IO;DS1302_CLK=1;DS1302_CLK=0;}

return(ACC);}

voidWrite1302(unsignedcharucAddr,unsignedcharucDa)//ucAddr:

DS1302地址,ucData:

要写的数据

{DS1302_RST=0;

DS1302_CLK=0;

DS1302_RST=1;

DS1302InputByte(ucAddr);//地址,命令

DS1302InputByte(ucDa);//写1Byte数据

DS1302_CLK=1;

DS1302_RST=0;

}unsignedcharRead1302(unsignedcharucAddr)//读取DS1302某地址的数据

{unsignedcharucData;

DS1302_RST=0;

DS1302_CLK=0;

DS1302_RST=1;

DS1302InputByte(ucAddr|0x01);//地址,命令

ucData=DS1302OutputByte();//读1Byte数据

DS1302_CLK=1;

DS1302_RST=0;

return(ucData);}

voidDS1302_GetTime(SYSTEMTIME*Time)//获取时钟芯片的时钟数据到自定义的结构型数组

{unsignedcharReadValue;

ReadValue=Read1302(DS1302_SECOND);

Time->Second=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

ReadValue=Read1302(DS1302_MINUTE);

Time->Minute=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

ReadValue=Read1302(DS1302_HOUR);

Time->Hour=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

ReadValue=Read1302(DS1302_DAY);

Time->Day=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

ReadValue=Read1302(DS1302_WEEK);

Time->Week=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

ReadValue=Read1302(DS1302_MONTH);

Time->Month=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

ReadValue=Read1302(DS1302_YEAR);

Time->Year=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);}

voidDateToStr(SYSTEMTIME*Time)//将时间年,月,日,星期数据转换成液晶显示字符串,放到数组里DateString[]

{if(hide_year<2)//这里的if,else语句都是判断位闪烁,<2显示数据,>2就不显示,输出字符串为2007/07/22

{Time->DateString[0]='2';

Time->DateString[1]='0';

Time->DateString[2]=Time->Year/10+'0';

Time->DateString[3]=Time->Year%10+'0';}

else{Time->DateString[0]='';Time->DateString[1]='';

Time->DateString[2]='';Time->DateString[3]='';}

Time->DateString[4]='/';

if(hide_month<2)

{Time->DateString[5]=Time->Month/10+'0';

Time->DateString[6]=Time->Month%10+'0';}

else{Time->DateString[5]='';Time->DateString[6]='';}

Time->DateString[7]='/';

if(hide_day<2)

{Time->DateString[8]=Time->Day/10+'0';

Time->DateString[9]=Time->Day%10+'0';}

else{Time->DateString[8]='';Time->DateString[9]='';}

if(hide_week<2){

week_value[0]=Time->Week%10+'0';}//星期的数据另外放到week_value[]数组里,跟年,月,日的分开存放,因为等一下要在最后显示}

else{week_value[0]='';}

week_value[1]='\0';

Time->DateString[10]='\0';//字符串末尾加'\0',判断结束字符

}

voidTimeToStr(SYSTEMTIME*Time)//将时,分,秒数据转换成液晶显示字符放到数组TimeString[];

{if(hide_hour<2)

{Time->TimeString[0]=Time->Hour/10+'0';

Time->TimeString[1]=Time->Hour%10+'0';}

else{Time->TimeString[0]='';Time->TimeString[1]='';}

Time->TimeString[2]=':

';

if(hide_min<2){Time->TimeString[3]=Time->Minute/10+'0';

Time->TimeString[4]=Time->Minute%10+'0';}

else{Time->TimeString[3]='';Time->TimeString[4]='';}

Time->TimeString[5]=':

';

if(hide_sec<2)

{Time->TimeString[6]=Time->Second/10+'0';

Time->TimeString[7]=Time->Second%10+'0';}

else{Time->TimeString[6]='';Time->TimeString[7]='';}

Time->DateString[8]='\0';}

voidInitial_DS1302(void)//时钟芯片初始化

{unsignedcharSecond=Read1302(DS1302_SECOND);

if(Second&0x80)//判断时钟芯片是否关闭

{Write1302(0x8e,0x00);//写入允许

Write1302(0x8c,0x07);//以下写入初始化时间日期:

07/07/25.星期:

3.时间:

23:

59:

55

Write1302(0x88,0x07);Write1302(0x86,0x25);

Write1302(0x8a,0x07);Write1302(0x84,0x23);Write1302(0x82,0x59);

Write1302(0x80,0x55);Write1302(0x8e,0x80);//禁止写入

}}

voidDelay1ms(unsignedintcount)

{unsignedinti,j;for(i=0;i

/*延时子程序*/

voidmdelay(uintdelay)

{uinti;for(;delay>0;delay--){for(i=0;i<62;i++)//1ms延时.

{;}}}

voidoutkey()//跳出调整模式,返回默认显示

{ucharSecond;if(out==0){mdelay(8);count=0;

hide_sec=0,hide_min=0,hide_hour=0,hide_day=0,hide_week=0,hide_month=0,hide_year=0;

Second=Read1302(DS1302_SECOND);

Write1302(0x8e,0x00);//写入允许

Write1302(0x80,Second&0x7f);

Write1302(0x8E,0x80);//禁止写入

done=0;while(out==0);}}

///////////////////////////////////////////////////////////////////////////////

voidUpkey()//升序按键

{Up=1;if(Up==0)

{

mdelay(8);

switch(count)

{case1:

temp=Read1302(DS1302_SECOND);//读取秒数

temp=temp+1;//秒数加1

up_flag=1;//数据调整后更新标志

if((temp&0x7f)>0x59)//超过59秒,清零

temp=0;break;

case2:

temp=Read1302(DS1302_MINUTE);//读取分数

temp=temp+1;//分数加1

up_flag=1;

if(temp>0x59)//超过59分,清零

temp=0;break;

case3:

temp=Read1302(DS1302_HOUR);//读取小时数

temp=temp+1;//小时数加1

up_flag=1;

if(temp>0x23)//超过23小时,清零

temp=0;break;

case4:

temp=Read1302(DS1302_WEEK);//读取星期数

temp=temp+1;//星期数加1

up_flag=1;

if(temp>0x7)

temp=1;

break;

case5:

temp=Read1302(DS1302_DAY);//读取日数

temp=temp+1;//日数加1

up_flag=1;

if(temp>0x31)

temp=1;

break;

case6:

temp=Read1302(DS1302_MONTH);//读取月数

temp=temp+1;//月数加1

up_flag=1;

if(temp>0x12)

temp=1;

break;

case7:

temp=Read1302(DS1302_YEAR);//读取年数

temp=temp+1;//年数加1

up_flag=1;

if(temp>0x85)

temp=0;

break;

default:

b

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 合同协议

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1