51单片机和DS1302时钟芯片和LCD1602液晶显示的数字时钟.docx
PRoTEUS仿真图:KEILC程序:include<REGX52.H>include"LCD1602.h"include"DS1302.h"voidDelaylms(unsignedintcount)(unsignedinti,j;for(i=0;i<count;i+)for(j=0;j<120;j+);)main()(SYSTEMTIMECurrentTime;1.CDJnitiaIO;lnitial_DS1302();GotoXY(0,0);Print("tianmadianzi");GotoXY(OzI);Print("Time:");while(l)(DS1302_GetTime(&CurrentTime);TimeToStr(StCurrentTime);GotoXY(64);Print(CurrentTimeJimeString);Delaylms(400);)#ifndefLCD_CHAR_1602_2005_4_9ftdefineLCD_CHAR_1602_2005_4_9#include<intrins.h>/PortDefinitionS*sbitLcdRs=P20;sbitLcdRw=P21;sbitLcdEn=P22;sfrDBPort=0×80;Po=OX80,Pl=OX90,P2=0xA0,P3=0xB0.数据端口内部等待函数*unsignedcharLCD_Wait(void)1.cdRs=O;1.cdRw=I;_nop_();1.cdEn=I;_nop_();while(DBPort&0x80);在用PrOteUS仿真时,注意用屏蔽此语句,在调用GOtOXY()时,会进入死循环,可能在写该控制字时,该模块没有返回写入完备命令,即DBPort&0x80=0x80实际硬件时翻开此语句1.cdEn=O;returnDBPort;LCD/*ftdefine LCD_COMMANDftdefine LCD_DATA#define LCD_CLEAR_SCREEN#define LCD HOMING1OxOl0/ Command/ Data /清屏 0x02/光标返回原点voidLCD_Write(bitstyle,unsignedcharinput)1.cdEn=O;1.cdRs=StyIe;1.cdRw=O;_nop_();DBPOrt=input;JIOP_();注意顺序1.cdEn=I;_nop_();注意顺序1.cdEn=O;_nop_();1.CD_Wait();)设置显示模式*#define LCD_SHOW#define LCD_HIDEftdefine LCD,CURSOR#define LCD_NO_CURSOR#define LCD_FLASHftdefine LCD NO FLASH0x04显示开OxOO显示关0x02 显示光标0x00 无光标0x01 光标闪动0x00 光标不闪动voidLCD_SetDisplay(unsignedcharDispIayMode)1.CD_Write(LCD.COMMAND,0x081DispIayMode);)设置输入模式*#define LCD_AC_UP#define LCD_AC_DOWN#define LCD_MOVEftdefine LCD NO MOVE0x02OxOOOxOlOxOO/ default画面可平移/defaultvoidLCD_Setlnput(unsignedcharInputMode)1.CD_Write(LCD.COMMAND,0x041InputMode);移动光标或屏幕*#defineLCD_CURSOR0x02#defineLCD_SCREEN0x08ftdefineLCD_LEFT0x00#defineLCD_RIGHT0x04voidLCD_Move(unsignedcharobject,unsignedchardirection)(if(object=LCD_CURSOR)1.CD_Write(LCD_COMMAND,OxlOIdirection);if(object=LCD_SCREEN)1.CD_Write(LCD_COMMAND,Oxl81direction);)*/初始化LCD*voidLCDJnitiaIO(1.cdEn=O;1.CD_Write(LCD_C。MMAND,0x38);位数据端口,2行显示,5*7点阵1.CD_Write(LCD.COMMAND,0x38);1.CD_SetDisplay(LCD_SHOWLCD_NO_CURSOR);开启显示,无光标1.CD_Write(LCD_COMMANDzLCD_CLEAR_SCREEN);清屏1.CD_Setlnput(LCD_AC_UPLCD_NO_MOVE);Ae递增,画面不动)y*Mt*voidGotoXY(unsignedcharx,unsignedchary)(if(y=O)1.CD_Write(LCD.COMMAND,0x801x);if(y=i)1.CD_Write(LCD_COMMAND,0x80|(x-0x40);)voidPrint(unsignedchar*str)(while(*str!=,0,)(1.CD_Write(LCD.DATA,*str);str+;)*voidLCD_LoadChar(unsignedcharuser8,unsignedcharplace)unsignedchari;LCD_Write(LCD_COMMAND,0x40|(place*8);for(i=0;i<8;i+)1.CD_Write(LCD_DATA,useri);)*/*«*«*#endif#ifndef_REAL_TIMER_DS1302_2003_7_21_#defineREALTIMERDS13022003721sbitDS1302_CLK=P16;sbitDS1302_IO=P17;sbitDS1302_RST=P15;sbitACCO=ACC0;sbitACC7=ACC7;typedefstruct_SYSTEMTIME_实时时钟时钟线引脚实时时钟数据线引脚实时时钟复位线引脚unsignedcharSecond;unsignedcharMinute;unsignedcharHour;unsignedcharWeek;unsignedcharDay;unsignedcharMonth;unsignedcharYear;unsignedcharDateString9;unsignedcharTimeString9;SYSTEMTIME;定义的时间类型ftdefineAM(X)XftdefinePM(X)(×+12)#defineDS1302_SECOND0x80#defineDS1302_MINUTE0x82#defineDS1302_HOUR0x84ftdefineDS1302_WEEK0x8A#defineDS1302_DAY0x86#defineDS1302_MONTH0x88#defineDS1302_YEAR0x8CftdefineDS1302-RAM(X)(0×C0+(X)*2)voidDS1302lnputByte(unsignedchard)(unsignedchari;ACC=d;for(i=8;i>0;i-)/转成24小时制用于计算DS1302_RAM地址的宏实时时钟写入一字节(内部函数)DS1302JO=ACCO;DS1302CLK=1:相当于汇编中的RRCDS1302_CLK=O;ACC=ACC»1;)unsignedcharDS1302OutputByte(void)实时时钟读取一字节(内部函数)(unsignedchari;for(i=8;i>0;i-)(ACC=ACC»1;相当于汇编中的RRCACC7=DS1302JO;DS13O2_CLK=1;DS13O2_CLK=0;)return(ACC);)voidWritel302(unsignedcharucAddrzunsignedcharucDa)ucAddr:DS13O2地址,ucData:要写的数据(DS13O2_RST=0;DS13O2_CLK=0;DS13O2_RST=1;DS13O2lnputByte(ucAddr);/土也址,命令DS13O2lnputByte(ucDa);/写IByte数据DS13O2_CLK=1;DS13O2_RST=0;)unsignedcharReadl302(unsignedcharucAddr)读取DS13O2某地址的数据(unsignedcharucData;DS13O2_RST=0;DS13O2_CLK=0;DS13O2_RST=1;DS13O2lnputByte(ucAddrOxOl);/地址,命令ucData=DS1302OutputByte();/读IByte数据DS13O2_CLK=1;DS13O2_RST=O;return(ucData);)voidDS1302_SetProtect(bitflag)