单片机课程设计报告电子万年历_第1页
单片机课程设计报告电子万年历_第2页
单片机课程设计报告电子万年历_第3页
单片机课程设计报告电子万年历_第4页
单片机课程设计报告电子万年历_第5页
已阅读5页,还剩39页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

PAGE单片机课程设计报告电子万年历姓名:刘承森学号:201125040240专业班级:机电一体化指导老师:宋海军所在学院:工程技术学院

目录摘要 I1绪论 1目的与意义 11.2方案选择与DIY电子万年历的研究情况 1 1 3 41.2.4DIY万年历的研究情况 42主要硬件描述 52.189C52模块 52.2显示模块LCM12864 5 5 52.3芯片DS1302简介 62.4芯片DS18B20简介 63硬件设计与实现 8单片机最小系统的设计 8时钟电路的设计 9温度采集模块的设计 9人机交互模块设计 104系统软件设计与实现 11 114.2LCM16824子程序的实现 154.3DS1302子程序的实现 164.4DS18B20子程序的实现 174.5键盘子程序的实现 194.6主程序的实现 205测试结果分析与结果 225.1测试结果分析 225.2测试总结 22结束语 23致谢 24参考文献 25附录一作品实物图 26附录二原理图 27附录三部分程序 281绪论设计目的与意义随着电子技术的高速发展,对电子方面人才的要求越来越高,不仅要求其具备相关的专业理论知识,还要求其具有较强的设计、制作等实践动手能力.此次学校举行的电子设计无疑是对从事电子相关专业的人的一次很好的锻炼和考验,是培养信息人才的一次良好的机会,为其提供了一个理论知识与实践相结合的平台。通过本次课程设计,引导学生结合所学的电路理论和程序设计的知识,思考设计方案,以小组合作方式,分工完成各个部分,从而掌握相关的硬件结合软件显示电路的设计和调试技术,一方面提高了学生的实践动手和协作能力,另一方面培养了学生综合运用所学理论知识进行工程设计的能力。1.2方案选择与DIY电子万年历的研究情况方案一:不使用芯片,采用单片机的定时计数器这种方法原理是利用单片机芯片的定时器来产生固定的时间,模拟时钟的时,分,秒。如:利用AT80C52芯片,定时器用工作方式1,每50ms产生一个中断,循环20次,即1s周期。每一个周期加1,那么1min为60个周期,1h就是60*60=3600个周期,一天就是3600*24=86400个周期。此方法优点是可以省去一些外围的芯片,但这种方法只能适用于一些要求不是十分精确,不做长期保留的场合。方案二:并行接口时钟芯片DS12887特点:采用单片机应用系统并行总线(三总线)扩展的接口电路,采用这种接口电路具有操作速度快,编程方便的优点。但是对于80C52单片机来说,低位地址线要通过锁存器输出,还要地址译码器,而且并行口芯片的体积相对较大,DS12887管脚图如图1所示。图1DS12887管脚图方案三:串行接口时钟芯片DS1302芯片主特性:(1)实时时钟具有能计算2100年之前的秒分时日日期星期月年的能力,还有闰年调整的能力�(2)318位暂存数据存储RAM�(3)串行I/O口方式使得管脚数量最少�(4)宽范围工作电压�(5)工作电流2.0V时,小于300nA�(5)读/写时钟或RAM数据时有两种传送方式单字节传送和多字节传送字符组方式�(6)8脚DIP封装或可选的8脚SOIC封装根据表面装配�(7)简单3线接口�(8)与TTL兼容Vcc=5V�(9)可选工业级温度范围-40+85优点:串行接口的日历时钟芯片,使用简单,接口容易,与微型计算机连线较少等特点,在单片机系统尤其是手持式信息设备中己得到了广泛的应用。所以,最终选择串行时钟芯片DS1302,DS1302的管脚图如图2所示。图2DS1302管脚图方案一:矩阵式键盘矩阵式键盘电路图如图3所示。图3矩阵式键盘行列式键盘的原理就是每一行线与每一列线的交叉地方不相通,而是接上一个按键,通过按键来接通。特点:以省出不少的I/O口资源,程序编写相对复杂点,适用于键数比较多的情况。方案二:独立式键盘独立式键盘电路图如图4所示。图4独立式键盘独立式键盘是指各个按键相互独立地连接到各自的单片机的I/O口,I/O口只需要做输入口就能读到所有的按键。特点:电路简单,程序容易写,适用于按键数较少的情况。所以我们选择独立式键盘。方案一:LED数码管显示数码管显示比较常用的是采用CD4511和74LS138实现数码转换,数码显示分动态显示和静态显示,静态显示具有锁存功能,可以使数据显示得很清楚,但浪费了一些资源。目前单片机数码管普通采用动态显示。编程简单,但只能显示数字,不能显示中文。方案二:LCD1602能够显示英文和数字。1602液晶模块内部的字符发生存储器(CGROM)已经存储了160个不同的点阵字符图形,这些字符有:阿拉伯数字、英文字母的大小写、常用的符号。方案三:LCD12864作为一种输出方式,液晶显示最大的特点就是能够实现友好的人机界面,它己经广泛应用于现代工业控制和智能化仪器仪表等领域,它己经成为单片机就用开发领域典型模块之一。能够方便的显示文字和数字。所以最终选择LCD12864。1.2.4DIY万年历的研究情况目前电子爱好者,所设计的万年历大部分都采用LCD1602或数码管显示,只能显示阳历,不能带显示阴历,而且没有阴历相对应的的天干地支,和生肖年,没有达到多功能的效果。我们采用LCD12864显示,通过算法实现,能正确显示阴历,具有友好的界面,为了追求时间的准确,我们采用芯片DS1302,通过单片机控制,读出时间显示在LCD上。我们除了用芯片DS18B20,通过程序控制,把温度也显示出来外还通过算法控制,把阴历相对应的天干地支,和生肖年也显示出来,达到多功能效果。2主要硬件描述2.189C52模块Mcs-51单片机管脚图图如图5所示。图5单片机管脚图(1)一个8位的微处理器(CPU)(2)片内数据存储器RAM(128B/256B)(3)片内程序存储器ROM/EPROM(4kB/8kB)(4)4个8位并行I/O拉口P0-P3,每个口既可以作输入,也可以作输出(5)2个16位定时器/计数器(6)5个中断源的中断控制系统(7)1个全双工的串行I/O接口(8)片内时钟振荡器2.2显示模块LCM12864我们采用FG12864J显示模块,如图6所示,它是一种图形点阵液晶显示器。它主要采用动态驱动原理由行驱动—控制器和列驱动器两部分组成了128(列)×64(行)的全点阵液晶显示。(1)工作电压为+5V±10%,可自带驱动LCD所需的负电压(2)全屏幕点阵,点阵数为128(列)×64(行),可显示8(/行)×4(行)个(16×16点阵)汉字,也可完成图形,字符的显示(3)与CPU接口采用5条位控制总线和8位并行数据总线输入输出,适配M6800系列时序(4)内部有显示数据锁存器(5)简单的操作指令显示开关设置,显示起始行设置,地址指针设置和数据读/写等指令图6FG12864J显示模块2.3芯片DS1302简介DS1302是DALLAS公司推出的涓流充电时钟芯片内含有一个实时时钟/日历和31字节静态RAM通过简单的串行接口与单片机进行通信实时时钟/日历电路提供秒分时日日期月年的信息每月的天数和闰年的天数可自动调整时钟操作可通过AM/PM指示决定采用24或12小时格式。DS1302与单片机之间能简单地采用同步串行的方式进行通信仅需用到三个口线1RES复位2I/O数据线3SCLK串行时钟时钟/RAM的读/写数据以一个字节或多达31个字节的字符组方式通信DS1302工作时功耗很低保持数据和时钟信息时功率小于1mW。DS1302的管脚描述如表1所示。表1DS1302管脚X1X2晶振管脚GND地RST复位I/O数据输入/输出引脚SCLK串行时钟Vcc1Vcc2电源供电管脚2.4芯片DS18B20简介DS18B20温度传感器当仁不让。超小的体积,超低的硬件开消,抗干扰能力强,精度高,附加功能强。对电子爱好者来说,DS18B20是我们开发温度相关的首选小产品。DS18B20引脚功能如表2所示。表2DS18B20引脚功能GND地DQ单数据总线VDD电源电压NC空引脚3硬件设计与实现该万年历以89S52作为控制核心,外接DS18B20温度传感器,DS1302时钟芯片,显示采用LCM12864,调表采用矩阵式键盘,整体硬件电路的框图如图7所示。图7硬件电路框图3.1单片机最小系统的设计AT89S52单片机为40引脚双列直插芯片,有四个I/O口P0,P1,P2,P3,MCS-51单片机共有4个8位的I/O口(P0、P1、P2、P3),每一条I/O线都能独立地作输出或输入。单片机的最小系统如图8所示,18引脚和19引脚接时钟电路,XTAL1接外部晶振和微调电容的一端,在片内它是振荡器倒相放大器的输入,XTAL2接外部晶振和微调电容的另一端,在片内它是振荡器倒相放大器的输出。第9引脚为复位输入端,接上电容,电阻及开关后够上电复位电路,20引脚为接地端,40引脚为电源端。图8单片机最小系统3.2时钟电路的设计本系统采用有DS1302串行时钟芯片作为主时钟电路,该电路使用单独的的晶振和单独的电源供电,减小主控的负担。电路图如图9所示。图9时钟电路温度采集模块的设计采用数字式温度传感器DS18B20,它是数字式温度传感器,具有测量精度高,电路连接简单特点,此类传感器仅需要一条数据线进行数据传输,使用P0.7与DS18B20的I/O口连接加一个上拉电阻,Vcc接电源,Vss接地。电路图如图10所示。图10温度采集电路3.4人机交互模块设计该系统输入模块采用独立式式键盘输入,显示模块采用LCM12864,很好的实现了人机交互,液晶与主控制器的接口如图11所示。图11液晶接口电路4系统软件设计与实现4.1主要算法流程图描述以80C52为核心,处理外转电路传进来的信号,实现时钟数据的读取,保存,显示其及键盘操作。流程图如图12所示。图12主程序流程图阳历和时分秒都是通过DS1302读出来的,经过主控的转换和处理最终显示在LCM12864上,该程序流程图如图13所示。图13计算阳历和时分秒流程图阴历是通过一种算法转换过来,首先得到阳历值,然后根据这种算法把阳历转换成阴历,最终显示在LCM12864模块上,该程序流程图如图14所示。图14计算阴历程序流程图时间调整是通过四个独立按键来调整时间值,时间调整流程图如图15所示。图15时间调整程序流程图星期的计算方法如下:星期=(日期年份+所过闰年数+月校正数)%7,如果是在闰年又不到3月份上述之和要减一天再除7,其1到12月的校正数据为[622503514624],该程序中采用1个字节表示年份闰年数也只计算1900年以后的闰年数。该程序的流程图如图16所示。图16计算星期算法4.2LCM16824子程序的实现LCM12864的读写时序如图17所示。图17LCM12864读写时序主要函数模块:函数:voidlcd_init(void)显示初始化程序函数:VoidGUI_init()该函数用于初始化显示界面,把一些固定不需要刷新的文字固定下来函数:voidlw(ucharx,uchary,uchardd)用来写数据的子程序函数:voiddisplay(ucharxx,ucharyy,ucharn,ucharfb,ucharhz[])用于显示汉字,每个汉字为16*16的点阵函数:voidshownum(ucharxx,ucharyy,ucharn,ucharfb,ucharnum[])用于显示数字,每个数字为8*16的点阵4.3DS1302子程序的实现DS1302的读写时序如图18所示。图18DS1302读写时序定义结构体数组SYSTEMTIME的时间类型,结构体数组如下:typedefstruct__SYSTEMTIME__{ unsignedcharSecond; unsignedcharMinute; unsignedcharHour; unsignedcharWeek; unsignedcharDay; unsignedcharMonth; unsignedcharYear;}SYSTEMTIME主要函数模块:函数:voidInitial_DS1302(void)描述:时钟芯片初始化函数:voidWrite1302(unsignedcharucAddr,unsignedcharucDa)描述:把某个数据写进某个地址函数:unsignedcharRead1302(unsignedcharucAddr)描述:从芯片内某地址读取数据函数:voidDS1302_GetTime(SYSTEMTIME*Time)描述:获取时钟芯片的时钟数据到自定义的结构型数组函数:voidDS1302InputByte(unsignedchard)描述:往时钟写入一字节函数:unsignedcharDS1302OutputByte(void)描述:从时间内读取一个字节4.4DS18B20子程序的实现DS18B20的读写时序如图19所示。图19DS18B20读写时序简易的程序流程图如图20所示。图20DS18B20读写程序流程图主要函数描述:函数:voidInit_DS18B20(void)描述:单总线传输初始化函数.函数:voidWriteOneChar(uchardat)描述:往芯片内部地址写入一个字节,有写数据和写指令之分.函数:voidReadTemp(void)描述:读取芯片的温度.函数:voiddelay_18B20(unsignedinti)描述:延时函数4.5键盘子程序的实现键盘示意图如图21所示。图21按键示意图主要函数模块:函数名:voidkey_count()功能描述:设置状态转换函数,根据变量count的不同值,对应不同的设置状态按下设置键,自动切换设置位函数名:voidkey_out()功能描述:跳出设置模式函数名:ucharkey_up(inttemp,intmax,intmin)功能描述:按键加函数,在最大值与最小值之间变化函数名:ucharkey_down(inttemp,intmax,intmin)功能描述:按键减函数,在最大值与最小值之间变化函数名:voidset_year();voidset_month();voidset_day();voidset_hour();voidset_minute();功能描述:分别是用来设置年月日时分秒函数名:voidkey_al01() 功能描述:设置定时报警功能4.6主程序的实现主要函数模块:函数名:Init_GUI()功能描述:进行界面初始化,例如固定的年、星期、农历函数名:voidShow_NL() 功能描述:根据算法,得出阴历,包括天干地支月日函数名:voidShow_YL()功能描述:根据算法,从时钟芯片读出阳历数据,显示出来函数名:LCD_ShowWNL()功能描述:根据算法,显示电子万年历,其中时钟的”秒”位为每次循环刷新一次,”分”为在普通模式时每分钟刷新一次,在设置模式时每次循环刷新一次,”时”为在普通模式时每小时刷新一次,在设置模式时每次循环刷新一次,公历农历的年、月、日、星期、温度,设置模式每次循环刷新一次函数名:voidLCD_showalarm()功能描述:显示定时报警的时间函数名:voidmian()功能描述:.显示万年历,循环读取时间,并通过程序进行键盘检测5测试结果分析与结果5.1测试结果分析(1)在测试中遇到LEDLCD16824不显示分析:首先使用试测仪对电路进行测试,观察是否存在漏焊,虚焊,或者元件损坏。再接着研究程序的时序图是否正确。最后发现程序时序方面出了点小错。修改后就把问题解决了(2)测试中遇到调时间调到2079年后跳到2000年分析:认真研究时钟芯片的Datasheet发现,对年的读取,读出后是BCD码转换成十制显示时算法不正确(3)按键调整时,不是按单位递增和递减分析:在键盘程序中,按键一次,向芯片写入一个新的数字,在写入数字后必须有一定延时才再写入另一个数字(4)烧写程序进单片机里面时,有时会在显示屏上显示烂码.分析:用电压表检查.最后检测出USB下载线的端口电压不够换条新线就可以把问题解决5.2测试总结经过多次的反复测试与分析,掌握了硬件的设计与分析的能力,学会看英文版的Datasheet,同时在软件的编程方面得到更到的提高,对编程能力得到加强。对所学的知识得到很大的提高与巩固。最终实现功能:(1)能显示阳历年、月、日、星期、小时、分、秒(2)显示模块采用LCD液晶显示,要求能用按键调整时间。(3)能显示阴历月、日,在显示阴历时间时能标明是否为闰年。(4)具有定时报警功能,能够进行整点和半点语音报时。(5)能够准确在LCD上显示室。(6)在显示农历时通过算法能够把天干地去也显示出来。结束语通过对基于单片机的万年历的研究和设计,完成了一种能够显示阳历、阴历、星期、时间、实时温度、天干地支的多功能万年历,该万年历还可以定时报警和进行进行整点和半点报时。本系统设计从开始到完成包括文档的编写总共花了一个月左右的时间,设计的难点在于星期和天干地支的计算方法,还有单片机和各个芯片之间的通信协议,液晶的读写时序,按键的防抖。本系统基本完成了设计指标的所有要求,所有的程序分块编写,通过main函数来调用,增加了程序的易修改性和易读性,方便他人的使用和改进。但是由于时间的局限性以及本人能力的有限性,本系统还有许多需要改进和完善的地方。其中主要的问题就是功耗和电源供电的问题,该处采用5V供电,最好采用3V供电。整个电路的功耗太大,没让单片机工作在空闲模式,这都是作品不实用,不能够大批量生产,这都有待改进,希望以后有机会对该系统做进一步的完善。致谢在本次设计中,我想首先感谢孙老师、宋老师,从设计的开始到完成,给了我很多指导性的意见,不断帮助我完善系统设计。从大一开始,赵老师作为我的导师,一直很注重我们动手能力的培养。她丰富的教学及实际操作经验、严谨的治学态度,以及和蔼的态度,使得我投入了大量时间在创新基地的实验室中,做了许多实验。而这,对我的帮助和影响是非常巨大的。正是因为有了这些锻炼的机会,我才能非常顺利地完成我的毕业设计。最后非常感谢郑州铁路职业技术学院信息工程系的老师和同学,是他们让我学会了如何学习,更学会了如何做人,这将是我终身受益的宝贵财富参考文献[1]周兴华编著.手把手教你学单片机C程序设计.北京:北京航空航天大学出版社,2007[2]侯玉宝编著.基于Proteus的51系列单片机设计与仿真.北京:电子工业出版社,2008[3]张义和编著.例说51单片机(C语言).北京:人民邮电出版社.2008[4]李朝青编著.单片机原理及接口技术.北京:北京航空航天大学出版社,2005[5]周慈航编著.单片机应用程序设计基础.北京:北京航空航天大学出版社,1991[6]马忠梅编著.单片机的C语言应用程序设计.北京:北京航空航天大学出版社,2003[7]李广弟编著.单片机基础.北京:北京航空航天大学出版社,1994[8]曾巧媛编著.单片机原理及应用.北京:电子工业出版社,1997[9]邱丽芳编著.单片机原理与应用.人民邮电出版社,2007[10]何立民编著.MCS-51系列单片机应用系统设计.北京航空航天大学出版社,2003附录二原理图附录三部分程序主程序#include<reg51.h>#include<DS1302.c> //更改管脚#include<DS18B20.c>#include<zimo.c>#include<lcd12864.c>#include<key.c>#include<beep.c>#include<lunar.c>#defineucharunsignedchar#defineuintunsignedintSYSTEMTIMEsys;ucharc_sun,year_sun,month_sun,day_sun;ucharyear_moon,month_moon,day_moon,week;ucharalarm=0,al_hour=0,al_min=0;Init_GUI(){ lcd_init(); Init_DS18B20(); Initial_DS1302(); delay(10); jiemian(); //显示初始化界面,例如固定的年、星期、农历……放在1里 } voidShow_NL(){ DS1302_GetTime(&sys); year_sun=Read1302(DS1302_YEAR); month_sun=Read1302(DS1302_MONTH); day_sun=Read1302(DS1302_DAY); Conversion(0,year_sun,month_sun,day_sun); /* day_moon=((day_moon&0x70)>>4)*10+(day_moon&0x0F); month_moon=((month_moon&0x70)>>4)*10+(month_moon&0x0F); year_moon=((year_moon&0xF0)>>4)*10+(year_moon&0x0F); */ if(month_moon==1)display(8,4,12,0,ch1616); //显示“正” elsedisplay(8,4,month_moon-1,0,ch1616); //显示当前农历的月 if(day_moon<11)display(12,4,13,0,ch1616); //显示“初” if(day_moon<20&&day_moon>10)display(12,4,9,0,ch1616); //显示“十” if(day_moon<30&&day_moon>19)display(12,4,14,0,ch1616); //显示“廿” if(day_moon>29)display(12,4,2,0,ch1616); //显示“三” display(14,4,(day_moon-1)%10,0,ch1616); //显示农历个位 display(14,2,year_moon%12,0,shengxiao); //显示生肖 display(9,2,year_moon%10,0,tiangan); //显示天干 display(11,2,year_moon%12,0,dizhi); //显示地支 Conver_week(0,year_sun,month_sun,day_sun); //星期 if(week==0)display(5,4,17,0,ch1616); //显示星期日 elsedisplay(5,4,week-1,0,ch1616); //显示星期1~6} voidShow_YL() //显示阳历{ DS1302_GetTime(&sys); shownum(6,6,sys.Second/10,0,num); //显示秒 shownum(7,6,sys.Second%10,0,num); shownum(3,6,sys.Minute/10,0,num); //显示分 shownum(4,6,sys.Minute%10,0,num); shownum(0,6,sys.Hour/10,0,num); //显示时 shownum(1,6,sys.Hour%10,0,num); shownum(4,2,sys.Day/10,0,num); //显示日 shownum(5,2,sys.Day%10,0,num); shownum(0,2,sys.Month/10,0,num); //显示月 shownum(1,2,sys.Month%10,0,num); shownum(3,0,sys.Year/10,0,num); //显示年 shownum(4,0,sys.Year%10,0,num); if((!(sys.Year%4)&&(sys.Year%100))||!(sys.Year%400))display(8,0,24,0,ch1616); //显示平闰年 else display(8,0,23,0,ch1616); //平闰年计算 if(sys.Minute==30&&sys.Second==0)Beep_Half(); //报时 if(sys.Minute==0&&sys.Second==0)Beep_Hour(); }voidLCD_ShowWNL(){ DS1302_GetTime(&sys); shownum(6,6,sys.Second/10,0,num); shownum(7,6,sys.Second%10,0,num); //秒每次循环钟刷新一次 if(!sys.Second) //分在普通模式时每分钟刷新一次,在设置模式时每次循环刷新一次 { shownum(3,6,sys.Minute/10,0,num); shownum(4,6,sys.Minute%10,0,num); } if(!sys.Second&&!sys.Minute) //时在普通模式时每小时刷新一次,在设置模式时每次循环刷新一次 { shownum(0,6,sys.Hour/10,0,num); shownum(1,6,sys.Hour%10,0,num); } if(!sys.Second&&!sys.Minute&&!sys.Hour) //公历农历的年、月、日、星期、温度,设置模式每次循环刷新一次 { Show_YL(); //显示农历 Show_NL(); //显示新历 diswendu(); //显示温度 } if(sys.Minute==30&&sys.Second==0)Beep_Half(); //报时 if(sys.Minute==0&&sys.Second==0)Beep_Hour(); } voidLCD_showalarm(){ display(8,6,21-alarm,0,ch1616); shownum(11,6,al_hour/10,0,num); //显示闹铃时 shownum(12,6,al_hour%10,0,num); //显示闹铃时 shownum(14,6,al_min/10,0,num); //显示闹铃分 shownum(15,6,al_min%10,0,num); //显示闹铃分}voidmain(){ Init_GUI(); diswendu(); Show_YL(); Show_NL(); LCD_showalarm();while(1) { LCD_ShowWNL(); if(sys.Second%9==0)diswendu(); key_count(); if(count)key_set(); //判断set键按下,进入设置界面 if(alarm&&(al_hour==sys.Hour)&&(al_min==sys.Minute)&&!sys.Second) //定时报警功能 { Beep_Half(); DS1302_GetTime(&sys);shownum(7,6,sys.Second%10,0,num); Beep_Hour(); DS1302_GetTime(&sys);shownum(7,6,sys.Second%10,0,num); Beep_Half(); DS1302_GetTime(&sys);shownum(7,6,sys.Second%10,0,num); Beep_Hour(); DS1302_GetTime(&sys);shownum(7,6,sys.Second%10,0,num); Beep_Half(); DS1302_GetTime(&sys);shownum(7,6,sys.Second%10,0,num); Beep_Hour(); DS1302_GetTime(&sys);shownum(7,6,sys.Second%10,0,num); } }}DS1302程序#defineuintunsignedint#defineucharunsignedchar#include<intrins.h>sbitDS1302_CLK=P1^2;//实时时钟时钟线引脚sbitDS1302_IO=P1^1;//实时时钟数据线引脚sbitDS1302_RST=P1^0;//实时时钟复位线引脚sbitACC0=ACC^0;sbitACC7=ACC^7;typedefstruct__SYSTEMTIME__{ unsignedcharSecond; unsignedcharMinute; unsignedcharHour; unsignedcharWeek; unsignedcharDay; unsignedcharMonth; unsignedcharYear;}SYSTEMTIME; //定义的时间类型SYSTEMTIMEsys;#defineAM(X) X#definePM(X) (X+12) //转成24小时制#defineDS1302_SECOND 0x80//时钟芯片的寄存器位置,存放时间#defineDS1302_MINUTE 0x82#defineDS1302_HOUR 0x84#defineDS1302_WEEK 0x8A#defineDS1302_DAY 0x86#defineDS1302_MONTH 0x88#defineDS1302_YEAR 0x8CvoidDS1302InputByte(unsignedchard) //实时时钟写入一字节(内部函数){unsignedchari;ACC=d;for(i=8;i>0;i--){DS1302_IO=ACC0; //相当于汇编中的RRCDS1302_CLK=1;DS1302_CLK=0;ACC=ACC>>1;}}unsignedcharDS1302OutputByte(void) //实时时钟读取一字节(内部函数){unsignedchari;for(i=8;i>0;i--){ACC=ACC>>1; //相当于汇编中的RRCACC7=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&0xf0)>>4)*10+(ReadValue&0x0F); } voidInitial_DS1302(void)//时钟芯片初始化{ unsignedcharSecond=Read1302(DS1302_SECOND); if(Second&0x80) //判断时钟芯片是否关闭 { Write1302(0x8e,0x00); //写入允许 _nop_();_nop_();_nop_(); Write1302(0x8c,0x09); //写入年 _nop_();_nop_();_nop_(); Write1302(0x88,0x05); //写入月 Write1302(0x86,0x05); //写入日 Write1302(0x8a,0x02); //星期 Write1302(0x84,0x23); //时 Write1302(0x82,0x59); //写入分 Write1302(0x80,0x30); //写入秒 Write1302(0x90,0xae); //开启充电 _nop_();_nop_();_nop_(); Write1302(0x8e,0x80); //禁止写入 }}LCD12864程序#include<REG51.H> #defineucharunsignedchar #defineuintunsignedintsbitCS1=P1^4; sbitCS2=P1^5;sbitRS=P0^5; sbitRW=P0^6; sbitEN=P0^7; sbitRST=P1^6; #defineDataPortP3voiddelay(unsignedlongv){ while(v!=0)v--; } voidlcd_busy(void){ RS=0;RW=1;DataPort=0xff; while(1) { EN=1; if(DataPort<0x80)break; EN=0; } EN=0; }voidwcode(ucharc,ucharcsl,ucharcsr){ CS1=csl; CS2=csr; lcd_busy(); RS=0; RW=0; DataPort=c; EN=1; EN=0; } voidwdata(ucharc,ucharcsl,ucharcsr){ CS1=csl; CS2=csr; lcd_busy(); RS=1; RW=0; DataPort=c; EN=1;

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论