//主程序
#include
#include "LCD1602.h"
#include "DS1302.h"
void Delay1ms(unsigned int count)
{
unsigned int i,j;
for(i=0;i for(j=0;j<120;j++); } main() { SYSTEMTIME CurrentTime; LCD_Initial(); Initial_DS1302(); GotoXY(0,0); Print("Date: "); GotoXY(0,1); Print("Time: "); while(1) { DS1302_GetTime(&CurrentTime); DateToStr(&CurrentTime); TimeToStr(&CurrentTime); GotoXY(6,0); Print(CurrentTime.DateString); GotoXY(6,1); Print(CurrentTime.TimeString); Delay1ms(300); } } //19602程序 #ifndef LCD_CHAR_1602_2005_4_9 #define LCD_CHAR_1602_2005_4_9 #include //Port Definitions********************************************************** sbit LcdRs = P2^0; sbit LcdRw = P2^1; sbit LcdEn = P2^2; sfr DBPort = 0x80; //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口 //内部等待函数************************************************************************** unsigned char LCD_Wait(void) { LcdRs=0; LcdRw=1; _nop_(); LcdEn=1; _nop_(); //while(DBPort&0x80);//在用Proteus仿真时,注意用屏蔽此语句,在调用GotoXY()时,会进入死循环, //可能在写该控制字时,该模块没有返回写入完备命令,即DBPort&0x80==0x80 //实际硬件时打开此语句 LcdEn=0; return DBPort; } //向LCD写入命令或数据************************************************************ #define LCD_COMMAND 0 // Command #define LCD_DATA 1 // Data #define LCD_CLEAR_SCREEN 0x01 // 清屏 #define LCD_HOMING 0x02 // 光标返回原点 void LCD_Write(bit style, unsigned char input) { LcdEn=0; LcdRs=style; //数据\命令 LcdRw=0; _nop_(); DBPort=input; _nop_();//注意顺序 LcdEn=1; _nop_();//注意顺序 LcdEn=0; _nop_();//E下降沿有效 LCD_Wait(); } //设置显示模式************************************************************ #define LCD_SHOW 0x04 //显示开 #define LCD_HIDE 0x00 //显示关 #define LCD_CURSOR 0x02 //显示光标 #define LCD_NO_CURSOR 0x00 //无光标 #define LCD_FLASH 0x01 //光标闪动 #define LCD_NO_FLASH 0x00 //光标不闪动 void LCD_SetDisplay(unsigned char DisplayMode) { LCD_Write(LCD_COMMAND, 0x08|DisplayMode); } //设置输入模式************************************************************ #define LCD_AC_UP 0x02 #define LCD_AC_DOWN 0x00 // default #define LCD_MOVE 0x01 // 画面可平移 #define LCD_NO_MOVE 0x00 //default void LCD_SetInput(unsigned char InputMode) { LCD_Write(LCD_COMMAND, 0x04|InputMode); } //移动光标或屏幕************************************************************ /* #define LCD_CURSOR 0x02 #define LCD_SCREEN 0x08 #define LCD_LEFT 0x00 #define LCD_RIGHT 0x04 void LCD_Move(unsigned char object, unsigned char direction) { if(object==LCD_CURSOR) LCD_Write(LCD_COMMAND,0x10|direction); if(object==LCD_SCREEN) LCD_Write(LCD_COMMAND,0x18|direction); } */ //初始化LCD************************************************************ void LCD_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递增, 画面不动 } //************************************************************************ void GotoXY(unsigned char x, unsigned char y) { if(y==0) LCD_Write(LCD_COMMAND,0x80|x); if(y==1) LCD_Write(LCD_COMMAND,0x80|(x-0x40)); } void Print(unsigned char *str) { while(*str!='\0') { LCD_Write(LCD_DATA,*str); str++; } } /* void LCD_LoadChar(unsigned char user[8], unsigned char place) { unsigned char i; LCD_Write(LCD_COMMAND,0x40|(place*8)); for(i=0; i<8; i++) LCD_Write(LCD_DATA,user[i]); } */ //************************************************************************ #endif //1302程序 #ifndef _REAL_TIMER_DS1302_2003_7_21_ #define _REAL_TIMER_DS1302_2003_7_21_ sbit DS1302_CLK = P1^6; //实时时钟时钟线引脚 sbit DS1302_IO = P1^7; //实时时钟数据线引脚 sbit DS1302_RST = P1^5; //实时时钟复位线引脚 sbit ACC0 = ACC^0; sbit ACC7 = ACC^7; typedef struct __SYSTEMTIME__ { unsigned char Second; unsigned char Minute; unsigned char Hour; unsigned char Week; unsigned char Day; unsigned char Month; unsigned char Year; unsigned char DateString[9]; unsigned char TimeString[9]; }SYSTEMTIME; //定义的时间类型 #define AM(X) X #define PM(X) (X+12) // 转成24小时制 #define DS1302_SECOND 0x80 #define DS1302_MINUTE 0x82 #define DS1302_HOUR 0x84 #define DS1302_WEEK 0x8A #define DS1302_DAY 0x86 #define DS1302_MONTH 0x88 #define DS1302_YEAR 0x8C #define DS1302_RAM(X) (0xC0+(X)*2) //用于计算 DS1302_RAM 地址的宏 RAM命令控制字地址:0xC0-0xFD void DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数) { unsigned char i; ACC = d; for(i=8; i>0; i--) { DS1302_IO = ACC0; //相当于汇编中的 RRC DS1302_CLK = 1; DS1302_CLK = 0; ACC = ACC >> 1; } } unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数) { unsigned char i; for(i=8; i>0; i--) { ACC = ACC >>1; //相当于汇编中的 RRC 将前一个下降沿读出的数据右移一位从而读出该次读出的数放入ACC7 ACC7 = DS1302_IO; DS1302_CLK = 1; DS1302_CLK = 0; //SCLK下降沿读出DS1302的数 } return(ACC); } void Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302地址, ucData: 要写的数据 { DS1302_RST = 0; DS1302_CLK = 0; DS1302_RST = 1; DS1302InputByte(ucAddr); // 地址,命令 DS1302InputByte(ucDa); // 写1Byte数据 DS1302_CLK = 1; DS1302_RST = 0; } unsigned char Read1302(unsigned char ucAddr) //读取DS1302某地址的数据 { unsigned char ucData; DS1302_RST = 0; DS1302_CLK = 0; DS1302_RST = 1; DS1302InputByte(ucAddr|0x01); // 地址,命令 ucData = DS1302OutputByte(); // 读1Byte数据 DS1302_CLK = 1; DS1302_RST = 0; return(ucData); } void DS1302_SetProtect(bit flag) //是否写保护 { if(flag) Write1302(0x8E,0x80); //0x8E 控制字节地址,bit7=WP WP=1 禁止数据写入DS1302 else Write1302(0x8E,0x00); //WP=0 允许写入DS1302 } void DS1302_SetTime(unsigned char Address, unsigned char Value) // 设置时间函数 { DS1302_SetProtect(0); Write1302(Address, ((Value/10)<<4 | (Value%10))); } void DS1302_GetTime(SYSTEMTIME *Time) { unsigned char ReadValue; 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); } void DateToStr(SYSTEMTIME *Time) { Time->DateString[0] = Time->Year/10 + '0'; Time->DateString[1] = Time->Year%10 + '0'; Time->DateString[2] = '-'; Time->DateString[3] = Time->Month/10 + '0'; Time->DateString[4] = Time->Month%10 + '0'; Time->DateString[5] = '-'; Time->DateString[6] = Time->Day/10 + '0'; Time->DateString[7] = Time->Day%10 + '0'; Time->DateString[8] = '\0'; } void TimeToStr(SYSTEMTIME *Time) { Time->TimeString[0] = Time->Hour/10 + '0'; Time->TimeString[1] = Time->Hour%10 + '0'; Time->TimeString[2] = ':'; Time->TimeString[3] = Time->Minute/10 + '0'; Time->TimeString[4] = Time->Minute%10 + '0'; Time->TimeString[5] = ':'; Time->TimeString[6] = Time->Second/10 + '0'; Time->TimeString[7] = Time->Second%10 + '0'; Time->TimeString[8] = '\0'; } void Initial_DS1302(void) { unsigned char Second=Read1302(DS1302_SECOND); if(Second&0x80) //BIT7=CH CH=0振荡器允许工作,CH=1,振荡器停止 DS1302_SetTime(DS1302_SECOND,0); } #endif 用LED稍微改下就OK,希望对你有帮助。
用时钟芯片了最好是用LCD显示吧,贴个图给你。一定要LEd的话自己改下吧,有问题可以 +我