DS1302 uses 1602 display and keypad to adjust time

Publisher:WiseSage123Latest update time:2015-04-27 Source: 51heiKeywords:DS1302 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
#include

#include
/*************************************Port definition************************************/
sbit sclk = P3^4;
sbit io= P3^3;
sbit rst= P3^5;
sbit rs=P1^0;
sbit en=P1^2;
sbit rw=P1^1;
sbit GND=P2^4;
sbit key=P2^0;
sbit K1=P2^1;
sbit K2=P2^2;
#define uchar unsigned char
#define uint unsigned int
uchar S1num,flag,second,minute,hour,week,day,month,year;//seconds, minutes, hours, weeks, days, months, yearsbit
keyflag=0;

void delay(uint z) //延时子程序
{
  uint x,y;
  for(x=z;x>0;x--)
     for(y=110;y>0;y--);
}
void delayus()
{
_nop_();
_nop_();
_nop_();
_nop_();
}

void write_1602dat(uchar dat)//Define a data writing subroutine with parameters
{
 rs=1; //When rs of 1602 is 0, it receives commands, and when it is 1, it receives data
 P0=dat; //Send the data in COM in void write_shu(uchar shu) to P0 port
 delay(5);
 en=1;
 delay(5);
 en=0;
 delay(5);
}
 
 

void write_1602com(uchar com)//Define a write command subroutine with parameters
{
 rs=0; //When rs of 1602 is 0, it receives commands, and when it is 1, it receives data
 P0=com; //Send the data in COM in void write_com(uchar com) to P0 port
 delay(5);
 en=1;
 delay(5);
 en=0;
 delay(5);
}
void Write1602(uchar add,uchar dat)
{
 write_1602com(add);
 write_1602dat(dat);
}
void init1602()//Define an initialization subroutine
{
 en=0;
 rw=0;
write_1602com(0x38);//Call the write_com subroutine and assign 0x38 to the P0 port, and turn on the display mode
write_1602com(0x0e);//Call the write_com subroutine and assign the "turn on display, display cursor, and cursor flashing" instruction code to the P0 port
write_1602com(0x06);//Call the write_com subroutine and assign the "address pointer plus 1, the entire screen does not move" instruction code to the P0 port
 //write_com(0x80+0x10);//Initialize the data pointer and let the pointer point to the rightmost end of the display
write_1602com(0x80);//Initialize the data pointer and let the pointer point to the leftmost end, and the display starts from the first line
write_1602com(0x01);//Call the write_com subroutine and assign the "clear instruction" code to the P0 port
Write1602(0x80,'2');
Write1602(0x81,'0');
Write1602(0x80+4,'-');
Write1602(0x80+7,'-');
Write1602(0x80+0x40+5,':');
Write1602(0x80+0x40+8,':');
 }
/********************Write a byte**************/
void write_1302byte(dat)
{
uchar i;
sclk=0;
delayus();
for(i=8;i>0;i--)
  {
   io=dat&0x01;//As long as it is taken from the low position, it must be 0X01 and
   delayus();
   sclk=1;//Create a rising edge for writing data.
   delayus();
   sclk=0;//Prepare for the next rising edge to write the next byte
   dat>>=1;//Shift the data one bit to the left, prepare to write the next data
  }
}

/********************Read a byte***************/
uchar read_1302byte()
{
uchar i,dat;
delayus();
for(i=8;i>0;i--)
  {
   dat>>=1;
   if(io==1)
   {
     dat|=0x80;//Take out 1 and write it to the highest bit of dat.
   }
  
   sclk=1;//Pull sclk high to prepare for the falling edge of reading a byte
   delayus();//Wait for a while to create a high level
   sclk=0;//Create a falling edge for reading a byte
   delayus();
  }
return dat;
}

/*************Write a time bit********************/
void write_1302(uchar add,uchar dat)
{
 rst=0;
delayus();
sclk=0;
delayus();
rst=1;
write_1302byte(add);
delayus();
write_1302byte(dat);
delayus();
rst=0;
}
/****************Read the address of 1302******************/
uchar read_1302add(uchar add)
{
uchar timedat;
rst=0;
_nop_();
sclk=0;
_nop_();
rst=1;
write_1302byte(add);//Write the address to be read
timedat=read_1302byte();//Assign the data in the above address to timedat
sclk=1;
_nop_();
rst=0;
return timedat;
}
/****************Initialize 1302****************************/
void init_1302()
{
 
  flag=read_1302add(0x81);//The highest bit of the second register, read the clock status
  if(flag&0x80)//Judge whether the clock is turned off. If it is internally turned off, initialize it. If it is not turned off, do not initialize it and keep going
  
   {
   write_1302(0x8e,0x00);//Remove write protection
   write_1302(0x80,((55/10)<<4|(55%10)));//Write the second register and write the initial value 55
   write_1302(0x82,((59/10)<<4|(59%10)));//Write the minute register and write the initial value 59
   write_1302(0x84,((22/10)<<4|(22%10)));//Write the hour register and write the initial value 23
   write_1302(0x86,((24/10)<<4|(24%10)));//Write the day register, and write the initial value 18
   write_1302(0x88,((2/10)<<4|(2%10)));//Write the month register, and write the initial value 2
   write_1302(0x8a,((5/10)<<4|(5%10)));//Write the week register, and write the initial value 5
   write_1302(0x8c,((12/10)<<4|(12%10)));//Write the year register, and write the initial value 12. 2012 cannot be written
    write_1302(0x90,0xa5);//Write the charging mode
    write_1302(0x8e,0x80);//Add write protection
   }
}
/*****************Read out the decimal number of seconds***************************/

uchar readsecond()
{
uchar dat;
dat=read_1302add(0x81);
second=((dat&0x70)>>4)*10+(dat&0x0f);
return second;
}

/*****************Read the decimal number of minutes***************************/

uchar readminute()
{
uchar dat;
dat=read_1302add(0x83);
minute=((dat&0x70)>>4)*10+(dat&0x0f);
return minute;
}

/*****************Read out the decimal number of the hour***************************/

uchar readhour()
{
uchar dat;
dat=read_1302add(0x85);
hour=((dat&0x70)>>4)*10+(dat&0x0f);
return hour;
}
/********************Read the decimal number of the day***************************/

uchar readday()
{
uchar dat;
dat=read_1302add(0x87);
day=((dat&0x70)>>4)*10+(dat&0x0f);
return day;
}

/*****************Read the decimal number of the month***************************/

uchar readmonth()
{
uchar dat;
dat=read_1302add(0x89);
month=((dat&0x70)>>4)*10+(dat&0x0f);
return month;
}
/*****************Read the decimal number of the week***************************/

uchar readweek()
{
uchar dat;
dat=read_1302add(0x8b);
week=((dat&0x70)>>4)*10+(dat&0x0f);
return week;
}

/*****************Read out the decimal number of the year***************************/

uchar readyear()
{
uchar dat;
dat=read_1302add(0x8d);
year=((dat&0xf0)>>4)*10+(dat&0x0f);
return year;
}
 
/************************读出所有时间**********************/
readtime()
{
readsecond();
readminute();
readhour();
readday();
readmonth();
readweek();
readyear();
}[page]
/*********************向1602写入时间****************************/
void write_second()
{
uchar shi,ge;
shi=second/10;
ge=second%10;
Write1602(0x80+0x40+9,0x30+shi);
Write1602(0x80+0x40+10,0x30+ge);
}
void write_minute()
{
uchar shi,ge;
shi=minute/10;
ge=minute%10;
Write1602(0x80+0x40+6,0x30+shi);
Write1602(0x80+0x40+7,0x30+ge);
}
void write_hour()
{
uchar shi,ge;
shi=hour/10;
ge=hour%10;
Write1602(0x80+0x40+3,0x30+shi);
Write1602(0x80+0x40+4,0x30+ge);
}

void write_day()
{
uchar shi,ge;
shi=day/10;
ge=day%10;
Write1602(0x80+8,0x30+shi);
Write1602(0x80+9,0x30+ge);
}
void write_month()
{
uchar shi,ge;
shi=month/10;
ge=month%10;
Write1602(0x80+5,0x30+shi);
Write1602(0x80+6,0x30+ge);
}
void write_year()
{
uchar shi,ge;
shi=year/10;
ge=year%10;
Write1602(0x80+2,0x30+shi);
Write1602(0x80+3,0x30+ge);
}
void write_week()
{
Write1602(0x80+12,0x30+week);
//uchar week;
switch(week)
  {
   case 1: Write1602(0x80+12,'M');
        Write1602(0x80+13,'O');
     Write1602(0x80+14,'N');
     break;
    case 2:Write1602(0x80+12,'T');
        Write1602(0x80+13,'U');
     Write1602(0x80+14,'E');
     break;
    case 3:Write1602(0x80+12,'W');
        Write1602(0x80+13,'E');
     Write1602(0x80+14,'N');
     break;
    case 4:Write1602(0x80+12,'T');
        Write1602(0x80+13,'H');
     Write1602(0x80+14,'U');
     break;
 case 5:Write1602(0x80+12,'F');
        Write1602(0x80+13,'R');
     Write1602(0x80+14,'I');
     break;
    case 6:Write1602(0x80+12,'S');
        Write1602(0x80+13,'A');
     Write1602(0x80+14,'T');
     break;
 case 7:Write1602(0x80+12,'S');
        Write1602(0x80+13,'U');
     Write1602(0x80+14,'N');
     break;
  }
}
/*********************键盘扫描****************************/
void keyscan()
{
  if(key==0)
  {
    delay(5);
     if(key==0);//防止误动作
  {
    
     S1num++;
     while(!key);
     switch(S1num)
     {
      case 1:
        keyflag=1;
        write_1302(0x8e,0x00);//去除写保护
     write_1302(0x80,0x80);//时钟停下
     write_1602com(0x80+0x40+10);
     write_1602com(0x0f);
     break;
      case 2:
        write_1602com(0x80+0x40+7);
        break;
      case 3:
        write_1602com(0x80+0x40+4);
        break;
      case 4:
        write_1602com(0x80+9);
        break;
      case 5:
        write_1602com(0x80+6);
        break;
      case 6:
        write_1602com(0x80+3);
        break;
      case 7:
        write_1602com(0x80+12);
        break;
      case 8:
        S1num=0;
     keyflag=0;
    
                 write_1602com(0x0c);//Do not display the cursor                            
                  write_1302(0x80,0x00);//Disable write protection
         write_1302(0x80,(second/10)<<4|second%10);//Write the adjusted seconds into DS1302
                  write_1302(0x82,(minute/10)<<4|minute%10);//Write the adjusted minutes into DS1302
                  write_1302(0x84,(hour/10)<<4|hour%10);//Write the adjusted hours into DS1302
         write_1302(0x8a,(week/10)<<4|week%10);//Write the adjusted week into DS1302
                  write_1302(0x86,(day/10)<<4|day%10);//Write the adjusted day into DS1302
                  write_1302(0x88,(month/10)<<4|month%10);//Write the adjusted month into DS1302
         write_1302(0x8c,(year/10)<<4|year%10);//
        //write_1302(0x80,0x00);//The clock continues to run. This sentence cannot be added here, otherwise the seconds will return to 0 after each adjustment.
     write_1302(0x8e,0x80);//Write protection off
     //write_1602com(0x0c);
        break;
   }
  }
  }
  if(S1num!=0)
  {
    if(K1==0)
    {
     delay(5);
  while(!K1);
  switch(S1num)
  {
   case 1:
    second++;
    if(second==60)second=0;
    //write_1302(0x8e,0x00);//Remove write protection
    write_second();
    write_1602com(0x80+0x40+10);
    break;
   case 2:
    minute++;
    if(minute==60)minute=0;
    write_minute();
    write_1602com(0x80+0x40+7);
    break;
   case 3:
    hour++;
    if(hour==24)hour=0;
    write_hour();
    write_1602com(0x80+0x40+4);
    break;
   case 4:
    day++;
    write_day();
    write_1602com(0x80+9);
    break;
     case 5:
    month++;
    write_month();
    write_1602com(0x 80+6);
    break;
     case 6:
    year++;
    write_year();
    write_1602com(0x80+3);
    break;
     case 7:
    week++;
    write_week();
    write_1602com(0x80+12);
    break;
    // default:break;
     }
    }
    if(K2==0)
    {
     delay(5);
  while(!K2);
  switch(S1num)
  {
   case 1:
    second--;
    if(second<0)second=59;
    write_second() ;
    write_1602com(0x80+0x40+10);
    break;
   case 2:
    minute--;
    if(minute<0)minute=59;
    write_minute();
    write_1602com(0x80+0x40+7);
    break;
   case 3:
    hour--;
    if(hour<0)hour=23;
    write_hour();
    write_1602com(0x80+0x40+4);
    break;
   case 4:
    day--;
    write_day();
    write_1602com(0x80+9);
    break;
     case 5:
    month--;
    write_month();
    write_1602com(0x80+6);
    break;
     case 6:
    year--;
    write_year();
    write_1602com(0x80+3);
    break;
     case 7:
    week--;
    write_week();
    write_1602com(0x80+12);
    break;
   //  default:break;
  }
    }
  }
}

 void main()
{
  GND=0;
  delay(100);
  init1602();
  init_1302();
  while(1)
    {
  keyscan();
  if(keyflag==0)
  {
  readtime();
  write_second();
  write_minute();
  write_hour();
  write_day();
  write_month();
  write_year();
  write_week();
  }
 }
}

Keywords:DS1302 Reference address:DS1302 uses 1602 display and keypad to adjust time

Previous article:DS18b20 is matched with 1602, and also has high and low temperature (adjustable) alarm
Next article:AD conversion module PCF8591 based on IIC bus

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号