基于AT89S51单片机的多功能电子万年历的设计Word下载.docx
《基于AT89S51单片机的多功能电子万年历的设计Word下载.docx》由会员分享,可在线阅读,更多相关《基于AT89S51单片机的多功能电子万年历的设计Word下载.docx(14页珍藏版)》请在冰豆网上搜索。
第六章参考文献
第七章附录
1、源程序代码
1.1主函数源程序代码
1.2LCD显示源程序代码
1.3DS1302源程序代码(徐辰)
设计背景及意义
《单片机原理及应用》是一门技术性、应用性很强的学科,实践教学是它的一个极为重要的环节。
不论是硬件扩展、接口应用还是编程方法、程序调试,都离不开实验教学。
如果不在切实认真的抓好实践技能的锻炼上下功夫,单凭课堂理论课的学习,势必出现理论与实践脱节的局面。
任凭书本上把单片机技术介绍的多么重要、多么使用,我们仍会感到那只是空中楼阁,离自己十分遥远。
本次课程设计的目的就是让我们大家在理论学习的基础上,通过完成基于AT89S51单片机的多功能电子万年历的设计,熟悉单片机仿真软件PROTEUS的使用方法,了解AT89C51单片机的硬件系统,掌握LCD显示器LCD1602的工作原理和软硬件设计方法,为今后开发设计工作打下一定的基础。
液晶显示器简称LCD显示器,它是利用液晶经过处理后能改变光线的传输方向的特性实现显示信息的。
液晶显示器具有体积小、重量轻、功耗极低、显示内容丰富等特点,在单片机应用系统中得到了日益广泛的应用。
液晶显示器按其功能可分为三类:
笔段式液晶显示器、自负点阵式液晶显示器和图形点阵式液晶显示器。
前两种可显示数字、字符和符号等,而图形点阵式液晶显示器还可以显示汉字和任意图形,达到图文并茂的效果。
1、系统设计硬件框图
2、系统实现的基本原理
(1)市场上使用的1602液晶显示器以并行操作方式居多,但也有并、串口同时具有的。
LCD1602每行显示16个字符,一共可以显示两行,第一行显示年、月、日,第二行显示时、分、秒,时间显示在1602液晶上,并且按秒实时更新
(2)DS1302实时时钟通过串口接口与单片机进行通信,实时时钟日历电路提供秒、分、时、日、月、年的信息,内部含有31个细节静态RAM,可提供用户访问。
(3)使用5个按键,随时调节年、月、日、时、分的大小
(4)在主程序中调用其他子程序(包括LCD显示模块及DS1302的控制模块),以实现电子万年历的功能
(5)LCD字符显示的工作原理:
一个字符由6*8或8*8这样的点阵组成,要正确显示,必须要找到和屏上某几个位置对应显示RAM区的8个字节,并且要使每个字节的不同的位为“1”,其他的位为“0”,为“1”的点亮,为“0”的点暗,通过明暗的变化显示某个字符。
(6)
AT89C51是一个低电压,高性能CMOS8位单片机,片内含4kbytes的可反复擦写的Flash只读程序存储器和128bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,内置功能强大的微型计算机的AT89C51提供了高性价比的解决方案。
AT89C51是一个低功耗高性能单片机,40个引脚,32个外部双向输入/输出(I/O)端口,同时内含2个外中断口,2个16位可编程定时计数器,2个全双工串行通信口,AT89C51可以按照常规方法进行编程,也可以在线编程。
其将通用的微处理器和Flash存储器结合在一起,特别是可反复擦写的Flash存储器可有效地降低开发成本。
(7)Proteus(海神)的ISIS是一款Labcenter出品的电路分析实物仿真系统,可仿真各种电路和IC,并支持单片机,元件库齐全,使用方便,是不可多得的专业的单片机软件仿真系统。
该软件的特点:
①具有模拟电路仿真、数字电路仿真、单片机及其外围电路组成的系统的仿真、RS一232动态仿真、1C调试器、SPI调试器、键盘和LCD系统仿真的功能;
有各种虚拟仪器,如示波器、逻辑分析仪、信号发生器等
②支持大量的存储器和外围芯片。
总之该软件是一款集单片机和SPICE分析于一身的仿真软件,功能极其强大,可仿真51、AVR、PIC。
1、选择元器件:
单片机AT89S51,LCD显示屏,DS1302芯片,按键若干,电阻若干,电容器
2、硬件原理图2-1:
2-1硬件连接图
1、设计原理
启动DS1302,初始化芯片,设置初始时间,读出时间,存放在结构体SYSTEMTIME中,然后将时间转化为字符数组,送往LCD显示器。
每隔1S读出时间,重复以上步骤。
这样可以实现时钟的正常显示。
也可以通过按下按钮对时间进行修改校正。
2、软件流程图
主函数流程图
LCD显示流程图
3、系统的仿真调试
(1)安装并打开单片机仿真软件PROTEUS,选择需要的器件并连接电路
(2)在KEIL环境中编译设计中需要的原程序,并生成.HEX文件
(3)双击AT89C51器件,在打开的“EDITCOMPONENT”对话框中,在“PROGRAMFILE“一栏中将.HEX文件进行装载,界面如图3-1:
3-1
(4)点击运行按扭,观察仿真现象,则显示器显示情况如图4-1,且进入计时工作
4-1显示模块
(5)下图5-1中显示的五个按钮,从左至右分别代表分、时、日、月、年的设置,即点击相应的按钮,显示器上的相应位置的数字将会递增显示;
5-1调节模块
(6)点击下图6-1右边的按扭后,再进行第5步的操作,显示器上相应位置的数字将会递减显示。
6-1选择模块
通过本次课程设计-----完成基于AT89S51单片机的多功能电子万年历的设计,可以让我们在学习理论知识的基础上,更进一步的了解单片机,认识单片机,运用单片机。
(一)单片机属于控制类数字芯片,目前气应用领域非常广泛:
1、工业自动化控制
2、智能仪器仪表
3、计算机外部设备和智能接口
4、家用电器
(二)以往的测控仪器的显示部分大都采用LED式液晶显示屏进行参数设置和结果显示,其显示信息量少、形式单一、人机交互性差、操作人员要求高,而本设计中运用的液晶显示器(LCD)具有功耗低、体积小、可编程驱动等其他显示方式无法比拟的优点,不仅可以显示数字、字符还可以显示各种图形、曲线、汉字,并且课实现屏幕上下左右滚动、动画等功能,人机界面更加友好,操作也更加灵活方便,使其成为智能仪器仪表和测试设备的首选显示器件。
(三)显示功能最完整的点阵图形液晶模块的液晶显示可以分为三种
1、线段的显示
2、字符的显示
3、汉字的显示
在设计过程中,我认识到自己对单片机方面的知识了解的太少太少了,对于书本上的很多知识还不能灵活运用,有很多需要掌握的知识等着我们去学习去研究;
从理论到实践的转化就是实际操作的过程,只有动手动脑,主动请教,查询资料,团结合作,不断的发现问题,不断的解决问题,才能有所收获,才能有更多的体会和快乐;
学习是个长久的过程,并不是一下子就能融会贯通的,要有坚持不懈的毅力,要有不怕困难的精神,在前期刚开始做的时候,面对着课本,面对着课程题目,我有点懵,不知道从哪里下手,在老师的指导帮助下,在小组成员的共同努力下,我由基础到深化,由简单到复杂,循序渐进的完成了基于AT89S51单片机的多功能电子万年历有关模块的设计!
[1]林志琦.基于Proteus的单片机可视化软硬件仿真[M].北京:
北京航空航天大学出版社,2006.9
[2]周润景,张丽娜.基于PROTEUS的电路及单片机系统设计与仿真[M].北京:
北京航空航天大学出版社,2006.5
[3]谢维成单片机原理与应用及C51程序设计[M].北京:
清华大学出版社
[4]谭浩强C语言程序设计[M]清华大学出版社
源程序代码
(1)主函数程序
#include<
REG52.H>
#include"
LCD1602.h"
DS1302.h"
sbitY=P1^0;
sbitM=P1^1;
sbitD=P1^2;
sbitH=P1^3;
sbitF=P1^4;
sbitJ=P2^3;
sbitS=P2^4;
unsignedcharqn=20;
chars=1;
voidDelay1ms(unsignedintcount)
{unsignedinti,j;
for(i=0;
i<
count;
i++)
for(j=0;
j<
120;
j++);
}
keyscan()
{charx,y;
EA=0;
if(S==0)s=!
s;
if(Y==0)
{x=Read1302(DS1302_YEAR);
x=((x&
0x70)>
>
4)*10+(x&
0x0F);
if(s==1)x=x+1;
elsex=x-1;
x=(x/10)<
<
4|(x%10);
Write1302(DS1302_YEAR,x);
}
if(M==0)
{x=Read1302(DS1302_MONTH);
if(x>
12)x=0;
Write1302(DS1302_MONTH,x);
if(D==0)
{x=Read1302(DS1302_DAY);
y=Read1302(DS1302_MONTH);
if((y==1||y==3||y==5||y==7||y==8||y==10||y==12)&
x>
31)x=0;
elseif((y==4||y==6||y==9||y==11)&
30)x=0;
elseif(y==2&
29)x=0;
Write1302(DS1302_DAY,x);
if(H==0)
{x=Read1302(DS1302_HOUR);
23)x=0;
Write1302(DS1302_HOUR,x);
if(F==0)
{x=Read1302(DS1302_MINUTE);
59)x=0;
Write1302(DS1302_MINUTE,x);
if(J==0)
{
qn=qn++;
if(qn>
99)qn=20;
main()
{
SYSTEMTIMECurrentTime;
LCD_Initial();
Initial_DS1302();
GotoXY(0,0);
Print("
Date:
"
);
GotoXY(0,1);
Time:
DS1302_SetTime(DS1302_SECOND,00);
DS1302_SetTime(DS1302_MINUTE,00);
DS1302_SetTime(DS1302_HOUR,00);
DS1302_SetTime(DS1302_WEEK,00);
DS1302_SetTime(DS1302_DAY,01);
DS1302_SetTime(DS1302_MONTH,01);
DS1302_SetTime(DS1302_YEAR,01);
while
(1)
{
keyscan();
DS1302_GetTime(&
CurrentTime);
YearToStr(&
CurrentTime,qn);
DateToStr(&
TimeToStr(&
GotoXY(6,0);
Print(CurrentTime.YearString);
Print(CurrentTime.DateString);
GotoXY(7,1);
Print(CurrentTime.TimeString);
Delay1ms(300);
}
(2)LCD显示程序:
#ifndefLCD_CHAR_1602_2005_4_9
#defineLCD_CHAR_1602_2005_4_9
intrins.h>
sbitLcdRs=P2^0;
sbitLcdRw=P2^1;
sbitLcdEn=P2^2;
sfrDBPort=0x80;
//P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口
unsignedcharLCD_Wait(void)
LcdRs=0;
LcdRw=1;
_nop_();
LcdEn=1;
while(DBPort&
0x80);
LcdEn=0;
returnDBPort;
#defineLCD_COMMAND0//Command
#defineLCD_DATA1//Data
#defineLCD_CLEAR_SCREEN0x01//清屏
#defineLCD_HOMING0x02//光标返回原点
voidLCD_Write(bitstyle,unsignedcharinput)
LcdRs=style;
LcdRw=0;
_nop_();
DBPort=input;
//注意顺序
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/
#defineLCD_MOVE0x01
#defineLCD_NO_MOVE0x00
voidLCD_SetInput(unsignedcharInputMode)
LCD_Write(LCD_COMMAND,0x04|InputMode);
#defineLCD_CURSOR0x02
#defineLCD_SCREEN0x08
#defineLCD_LEFT0x00
#defineLCD_RIGHT0x04
voidLCD_Move(unsignedcharobject,unsignedchardirection)
if(object==LCD_CURSOR)
LCD_Write(LCD_COMMAND,0x10|direction);
if(object==LCD_SCREEN)
LCD_Write(LCD_COMMAND,0x18|direction);
voidLCD_Initial()
LCD_Write(LCD_COMMAND,0x38);
//8位数据端口,2行显示,5*7点阵
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++;
voidLCD_LoadChar(unsignedcharuser[8],unsignedcharplace)
unsignedchari;
LCD_Write(LCD_COMMAND,0x40|(place*8));
i<
8;
i++)
LCD_Write(LCD_DATA,user[i]);
#endif