#include <reg51.h>
#include "lcd.h"
#include "DS1302.h"
#include <intrins.h>
#define uchar unsigned char
#define unit unsigned int
sbit DS1302_CLK = P1^7 ;
sbit DS1302_IO = P1^6 ;
sbit DS1302_RST = P1^5 ;
sbit ACC0 = ACC^0 ;
sbit ACC7 = ACC^7 ;
char hide_sec,hide_min,hide_hour,hide_day,hide_month,hide_year ; //秒,分,时到日,月,年位闪的计数
sbit Set = P2^0 ; //模式切换键
sbit Up = P2^1 ; //加法按键
sbit Down= P2^2 ; //减法按键
sbit Out = P2^3 ; //立即跳出调整模式按键
char done,count,temp,flag,up_flag,down_flag ;
uchar TempBuffer[5],week_value[2] ;
void show_time() ; //液晶显示程序
/***************1602液晶显示子程序***************************/
sbit LcdRs = P2^5;
sbit LcdRw = P2^6;
sbit LcdEn = P2^7;
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;
}
#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_();
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 //光标不闪动
viod LCD_SetDisplay(unsigned char DisplayMode)
{LCD_Write(LCD_COMMAND,0x08|DisplayMode);}
//***************设置输入模式***************
#define LCD_AC_UP 0x02
#define LCD_AC_DOWN 0x00
#define LCD_MOVE 0x01
#define LCD_NO_MOVE 0x00
viod LCD_SetInput(unsigned char InputMode)
{LCD_Write(LCD_COMMAND,0x04|InputMode);}
//***************LCD初始化******************
viod LCD_Initial()
{ LcdEn = 0 ;
LCD-Write(LCD_COMMAND,0x38);
LCD-Write(LCD_COMMAND,0x38);
LCD-SetDisplat(LCD_SHOW|LCD_NO_CURSOR);
LCD-Write(LCD_COMMAND,LCD_CLEAR_SCREEN);
LCD-SetInput(LCD_AC_UP|LCD_NO_MOVE);
}
//**************液晶字符输入的位置*************
viod 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));
}
//**************将字符输出到液晶显示*************
viod Print(unsigned char *str)
{ while(*str != '\0')
{LCD_Write(LCD_DATA,*str);str++;}
}
/****************DS1302时钟子程序******************/
tapedefstruct_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[11] ;
unsigned char TimeString[9] ;
}
SYSTEMTIME ; //定义的时间类型
SYSTEMTIME CurrentTime ;
#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
viod DS1302InputByte(unsigned char d)
{ unsigned char i;ACC=d;for(i=8;i>0;i--)
{DS1302_IO = ACC0;
DS1302_CLK = 1;DS1302_CLK = 0;ACC = ACC>>1;}
}
unsigned char DS1302OutputByte(viod)
{ unsigned char i;for(i=8;i>0;i--)
{ ACC = ACC>>1;
ACC7 = DS1302_IO;DS1302_CLK = 1;DS1302_CLK = 0;}
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,0x10);
else
Write1302(0x8E,0x00);
}
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) //将时间年,月,日,星期数据转换成液晶显示字符串,放到数组DateString[]里
{
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->DateString[8] = '\0';
}
void Initial_DS1302(void) //时钟芯片初始化
{
unsigned char Second=Read1302(DS1302_SECOND);
if(Second&0x80)
{ Write1302(0x8e,0x00);
Write1302(0x8c,0x07);
Write1302(0x88,0x07);
Write1302(0x86,0x25);
Write1302(0x8a,0x07);
Write1302(0x84,0x23);
Write1302(0x82,0x59);
Write1302(0x80,0x55);
Write1302(0x8e,0x80);
}
}
viod Delay 1ms(unsigned int count)
{ unsigned int i,j;for(i=0;i<count;i++)for(j=0;j<120;j++);}
/******************延时子程序*****************/
void mdelay(uint delay)
{ uint i;for(;delay>0;delay--);{for(i=0;i<62;i++)};}
viod outkey()
{ uchar Second;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);
}
}
viod Upkey()
{ Up=1; if(Up==0)
{ mdelay(8);
switch(count)
{ case 1:
temp=Read1302(DS1302_SECOND);
temp=temp+1;
up_flag=1;
if((temp&0x7f)>0x59)
temp=0; break;
case 2:
temp=Read1302(DS1302_MINUTE);
temp=temp+1;
up_flag=1;
if(temp>0x59)
temp=0; break;
case 3:
temp=Read1302(DS1302_HOUR);
temp=temp+1;
up_flag=1;
if(temp>0x23)
temp=0; break;
case 4:
temp=Read1302(DS1302_WEEK);
temp=temp+1;
up_flag=1;
if(temp>0x7)
temp=1; break;
case 5:
temp=Read1302(DS1302_DAY);
temp=temp+1;
up_flag=1;
if(temp>0x31)
temp=1; break;
case 6:
temp=Read1302(DS1302_MONTH);
temp=temp+1;
up_flag=1;
if(temp>0x12)
temp=1; break;
case 7:
temp=Read1302(DS1302_YEAR);
temp=temp+1;
up_flag=1;
if(temp>0x85)
temp=0; break;
default:break;
}
while(Up==0);
}
}
viod Downkey()
{ Down=1; if(Down==0)
{ mdelay(8);
switch(count)
{ case 1:
temp=Read1302(DS1302_SECOND);
temp=temp-1;
up_flag=1;
if(temp==0x7f)
temp=0x59; break;
case 2:
temp=Read1302(DS1302_MINUTE);
temp=temp-1;
up_flag=1;
if(temp==-1)
temp=0x59; break;
case 3:
temp=Read1302(DS1302_HOUR);
temp=temp-1;
up_flag=1;
if(temp==-1)
temp=0x23; break;
case 4:
temp=Read1302(DS1302_WEEK);
temp=temp-1;
up_flag=1;
if(temp==0)
temp=0x7; break;
case 5:
temp=Read1302(DS1302_DAY);
temp=temp-1;
up_flag=1;
if(temp==0)
temp=31; break;
case 6:
temp=Read1302(DS1302_MONTH);
temp=temp-1;
up_flag=1;
if(temp==0)
temp=12; break;
case 7:
temp=Read1302(DS1302_YEAR);
temp=temp-1;
up_flag=1;
if(temp==-1)
temp=0x85; break;
default:break;
}
while(Down==0);
}
}
viod Setkey()
{ Set=1; if(Set==0)
{ mdelay(8);count=count+1;
done=1;
whole(Set==0);
}
}
viod keydone()
{ uchar Second;
if(flag==0)
{ Write1302(0x8e,0x00);
temp=Read1302(0X80);
Write1302(0x80,temp|0x80);
Write1302(0x8e,0x80);
flag=1;
}
Setkey();
switch(count)
{ case 1: do
{ Outkey();
Upkey();
Downkey();
if(up_flag==1||down_flag==1)
{ Write1302(0x8e,0x00);
Write1302(0x80,temp|0x80);
Write1302(0x8e,0x80);
up_flag=0;
down_flag=0;
}
hide_sec++;
if(hide_sec>3)
hide_sec=0;
show_tome();
}while(count==0); break;
case 2: do
{ hide_sec=0;
Outkey();
Upkey();
Downkey();
if(up_flag==1||down_flag==1)
{ Write1302(0x8e,0x00);
Write1302(0x82,temp);
Write1302(0x8e,0x80);
up_flag=0;
down_flag=0;
}
hide_min++;
if(hide_min>3)
hide_min=0;
show_tome();
}while(count==3); break;
case 3: do
{ hide_min=0;
Outkey();
Upkey();
Downkey();
if(up_flag==1||down_flag==1)
{ Write1302(0x8e,0x00);
Write1302(0x84,temp);
Write1302(0x8e,0x80);
up_flag=0;
down_flag=0;
}
hide_hour++;
if(hide_hour>3)
hide_hour=0;
show_tome();
}while(count==4); break;
case 4: do
{ hide_hour=0;
Outkey();
Upkey();
Downkey();
if(up_flag==1||down_flag==1)
{ Write1302(0x8e,0x00);
Write1302(0x8a,temp);
Write1302(0x8e,0x80);
up_flag=0;
down_flag=0;
}
hide_week++;
if(hide_week>3)
hide_week=0;
show_tome();
}while(count==5); break;
case 5: do
{ hide_week=0;
Outkey();
Upkey();
Downkey();
if(up_flag==1||down_flag==1)
{ Write1302(0x8e,0x00);
Write1302(0x86,temp);
Write1302(0x8e,0x80);
up_flag=0;
down_flag=0;
}
hide_day++;
if(hide_day>3)
hide_day=0;
show_tome();
}while(count==6); break;
case 6: do
{ hide_day=0;
Outkey();
Upkey();
Downkey();
if(up_flag==1||down_flag==1)
{ Write1302(0x8e,0x00);
Write1302(0x88,temp);
Write1302(0x8e,0x80);
up_flag=0;
down_flag=0;
}
hide_month++;
if(hide_month>3)
hide_month=0;
show_tome();
}while(count==7); break;
case 7: do
{ hide_month=0;
Outkey();
Upkey();
Downkey();
if(up_flag==1||down_flag==1)
{ Write1302(0x8e,0x00);
Write1302(0x8c,temp);
Write1302(0x8e,0x80);
up_flag=0;
down_flag=0;
}
hide_year++;
if(hide_year>3)
hide_year=0;
show_tome();
}while(count==8); break;
case 8: count=0; hide_year=0;
Second=Read1302(DS1302_SECOND);
Write1302(0x8e,0x00);
Write1302(0x80,Second&0x7f);
Write1302(0x8e0x80);
done=0; break;
default:break;
}
}
viod show_time()
{ DS1302_GetTime(&CurrentTime);
TimeToStr(&CurrentTime);
DataToStr(&CurrentTime);
GotoXY(0,1);
Print(CurrentTime.TimeString);
GotoXY(0,0);
Print(CurrentTime.DataString);
GotoXY(15,0);
Print(week_value);
GotoXY(11,0);
Print("week");
Delay 1ms(400);
main()
{ flag=1;
LCD_Initial();
Initial_DS1302();
up_flag=0;
down_flag=0;
done=0;
while(1)
{ while(done==1) keydone();
while(done==0)
{ show_time();
flag=0;
Setkey();
}
}
}
}
|