Simple digital tube electronic clock based on DS1302

Publisher:糖三角Latest update time:2012-08-10 Source: 51heiKeywords:DS1302 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
#include
#include
#include"DS1302.h"
#include"KEY.h"
#include"IIC.H"
#define uchar unsigned char
#define uint unsigned int
#define LEDIO P0
#define LEDCHIP P2
sbit BEEP=P3^7;
/*****************************Digital tube definition**************************************/
  //Segment code 0 1 2 3 4 5 6 7 8 9 AB - P d
uchar code led[15]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x40,0x73,0x5E};
  // All bit selection signals are off
uchar code selchip[7]={0x01,0x02,0x04,0x08,0x10,0x20,0x10};
        //Data format: seconds, minutes, hours, days, months, weeks, and years
uchar time_temp[7]={0x00,0x50,0x10,0x12,0x30,0x01,0x11}; //Store initialization time and set ds1302 data
uchar DataTime[7]; //Read the data from DS1302
/**********************************************************/    
uchar display[4][6]={0x06,0x5b,0x6d,0x6f,0x6d,0x6f}; //digital tube display
uchar i=0,key1,key2=20,pos=0,p,k; //key and scan variables
uchar mod=0; //Mode: set time to enter button
bit bflash=0,clockdown=0; //Set and alarm flag
uchar hour,minute,second,year,month,date; //Variable storage related to time
uchar ss=1; //The number of times the alarm rings can be modified by yourself
uchar clock1[3]={0x06,0,0x01},clock2[3]={14,0,0x01}; //Alarm time and switch, default switch is on
uint num=5000; //Set the time to automatically return to the main interface
/////////////////////////////////
void TimeInit() //Timed scan initialization
{
 EA = 0;
 TMOD |= 0x10;
 TH1 = 0xfd;
 TL1 = 0xe6;
 EA=1;
// ET0=1;
 ET1=1;
 TR1=1;
}
///////////////////////////////////////////////////////
/*
void t0int() interrupt 1 //T0 interrupt program, control the tone of pronunciation
{
    TR0 = 0; //Close T0 first
    BEEP = ~BEEP; // Output square wave, sound
    TH0 = t0h; //The next interruption time, this time, controls the pitch
    TL0 = t0l;
    TR0 = 1; //Start T0
 LEDIO=display[mod][i];
 LEDCHIP=selchip[i];
 if(i>=5)
  i=0;
 else
  i++;
}
*/
/////////////////////////////////////////
void TimeInt() interrupt 3 //Timed scan interrupt
{
 if(i==pos)
 {
   if(bflash==1) // flashing flag; set time, date and alarm
  {
   if(k++<40)
   {
    if(i==4)
    i=0;
    else
    i=i+2;
   }  
   else
   {
    if(p++>40)
    {
     p=0;
     k=0;
    }
   }
  }
 }
 LEDIO=display[mod][i];
 LEDCHIP=selchip[i];
 if(num==0) //Automatically return to the time interface
 {
  against=0;
  bflash=0;
 }
 else
  num--;
 if(i>=5)
  i=0;
 else
  i++;
 TH1=0xfa;
 TL1=0xd8;
}
////////////////////////////////////////////////////////
void TimeToBin() //Convert time into binary
{
 second=DataTime[0]/16*10+DataTime[0]%16;
 minute=DataTime[1]/16*10+DataTime[1]%16;
 hour=DataTime[2]/16*10+DataTime[2]%16;
 date=DataTime[3]/16*10+DataTime[3]%16;
 month=DataTime[4]/16*10+DataTime[4]%16;
 year=DataTime[6]/16*10+DataTime[6]%16;
}
////////////////////////////////////////////////////////
void TimeToBCD() //Convert time to BCD code
{
 time_temp[0]=second/10*16+second%10;
 time_temp[1]=minute/10*16+minute%10;
 time_temp[2]=hour/10*16+hour%10;
 time_temp[3]=date/10*16+date%10;
 time_temp[4]=month/10*16+month%10;
 time_temp[6]=year/10*16+year%10;
}
////////////////////////////////////////////////
    
void  TimerDis()
{ /****************************Time scan settings************************/
 display[0][0]=led[hour/10];
 display[0][1]=led[hour%10]|0x80;
 display[0][2]=led[minute/10];
 display[0][3]=led[minute%10]|0x80;
 display[0][4]=led[second/10];
 display[0][5]=led[second%10];
 /****************************Date scan settings****************************/
 display[1][0]=led[year/10];
 display[1][1]=led[year%10]|0x80;
 display[1][2]=led[month/10];
 display[1][3]=led[month%10]|0x80;
 display[1][4]=led[date/10];
 display[1][5]=led[date%10];
 /**********************Alarm 1 scan settings********************************/
 display[2][0]=led[10]; //The first alarm clock
 display[2][1]=led[14-clock1[2]]; //P alarm on d alarm off
 display[2][2]=led[clock1[0]/10];
 display[2][3]=led[clock1[0]%10]|0x80;
 display[2][4]=led[clock1[1]/10];
 display[2][5]=led[clock1[1]%10];
 /***********************Alarm 2 scan settings**************************/
 display[3][0]=led[11]; //The first alarm clock
 display[3][1]=led[14-clock2[2]]; //P alarm on d alarm off
 display[3][2]=led[clock2[0]/10];
 display[3][3]=led[clock2[0]%10]|0x80;
 display[3][4]=led[clock2[1]/10];
 display[3][5]=led[clock2[1]%10];
 /********************************************************/
 //second=DataTime[0]/16*10+DataTime[0]%16;
}
///////////////////////////////////////////////////////
void KeySet()
{
 key1=KeyTab[KeyRvs()]; //Read keyboard value
 if(key2!=key1) //Prevent continuous jumping and release the key
 {
  if(key1=='*')
  {
   pos=0; //Return to the first position for easy setting
   if(!bflash) //Advanced time setting interface
   against=0;
   else
   mod=(mod+1)%4; //Function selection
   bflash=1; //Enter the clock setting flag
   num=5000; //If there is no operation, it will automatically return to the main interface
  }
  ////////////////////////////////Shift button to select the setting position
  if((key1=='0')&&(bflash))
  {
   pos=(pos+2)%6;
   num=5000;
  }
  if((!bflash)&&(key1=='0')) //One-touch turn off the alarm and sleep in, then turn on the alarm next time
  {  
   clockdown=1;       
  }
  //////////////////////////////// Hours, minutes, and seconds settings, add buttons,
  if((key1=='#')&&(bflash))
  { 
   num=5000; //
   if(mod==0) //Time setting
   {
    if(pos==0)
    {
     hour=(hour+1)%24;
    }
    else if(pos==2)
    {
     minute=(minute+1)%60;
    }
    else
    {
     second=(second+1)%60;
    }
   }
   ///////////////////////////////////Year, month and day settings
   if(mod==1)
   {
    if(pos==0)
    {
     year=(year+1)%100;
    }
    else if(pos==2)
    {
     month=(month+1)%13;
    }
    else
    {
     if(month==2) //Processing for February
     {
      if(year%4==0) // February in a leap year
      date=(date+1)%30;
      else
      date=(date+1)%29;
     }
     /// ...
     else if((month==1)||(month==3)||(month==5)||(month==7)||(month==8)||(month==10)||(month==12))
      date=(date+1)%32;
     else /////////////////////////////////////////////Xiaoyue settings
      date=(date+1)%31;
     }     
   }
   ///////////////////////////////////////////////////Alarm 1 settings
   if(mod==2)
   {
    if(pos==0) ​​//Alarm 1 switch setting
    {
     clock1[2]=(clock1[2]+1)%2;
    }
    if(pos==2)
    {
     clock1[0]=(clock1[0]+1)%24;
    }
    if(pos==4)
    {
     clock1[1]=(clock1[1]+1)%60;
    }
   }
   ///////////////////////////////////////////////////Alarm 2 settings
   if(mod==3)
   {
    if(pos==0) ​​//Alarm 2 switch setting
    {
     clock2[2]=(clock2[2]+1)%2;
    }
    if(pos==2)
    {
     clock2[0]=(clock2[0]+1)%24;
    }
    if(pos==4)
    {
     clock2[1]=(clock2[1]+1)%60;
    }
   }
  }
  if((!bflash)&&(key1=='#')) //Check the alarm settings
  {  
   mod=(mod+1)%2+2;       
  }
  ///////////////////////////////////////////////////Confirm key settings
  if(key1=='D')
  {
   if(bflash) //clear setting flag
   {
    bflash=0;
    against=0;
    TimeToBCD();
    Set_Ds1302(time_temp);
    while(!Write_Nbyte_iic(SLAVE,0x50,clock1,3));
    while(!Write_Nbyte_iic(SLAVE,0x60,clock2,3));
   }
   else //Switch time and date
    mod=(mod+1)%2;
   num=5000; //Automatically return to the time interface
  }
  key2=key1;
 } //Save the key value. Release the key to
}
//////////////////////////////////////
/********************The alarm rings for one minute****************************/
void CLOCK()
{ 
 if((clock1[0]==hour)&&(clock1[1]==minute)&&(clock1[3])||((clock2[0]==hour)&&(clock2[1]==minute)&&(clock2[3])))
 {
 
  if(!clockdown) //If you don't sleep in, the clock will ring normally
   BEEP=~BEEP;
  else
   BEEP=1; //Otherwise turn off the alarm
 }        
 else
 {
  clockdown=0; //Restore alarm
  BEEP=1; //Turn off the alarm
 }     
}
/////////////////////////////////////////
main()
{
 while(!Read_Nbyte_iic(SLAVE,0x50,clock1,3));
 while(!Read_Nbyte_iic(SLAVE,0x60,clock2,3));
 TimeInit(); //Wake up the clock after power failure
 Init_Ds1302();
 while(1)
 {
  Get_Ds1302(DataTime); //Read time
  TimerDis(); //Segment code processing
  KeySet(); //Scan keys
  if(!bflash) //If you do not enter the setting time, the display will be normal, otherwise the time will be paused
  {
   TimeToBin();
  }
  CLOCK(); //Alarm setting
 }
}
/*******************************************************************************************************************************/
#ifndef  _DS1302_H_
#define  _DS1302_H_
/*********************************************************************************/
#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit RST = P3^4;
sbit SCLK  = P3^5;
sbit IO = P3^6;
/********The following is the function declaration********/
void Ds1302_Write_Byte(uchar ch); //Write one byte of data function declaration
uchar Ds1302_Read_Byte(); //Read one byte of data function declaration
void Write_Ds1302(uchar cmd,uchar indata); //Write DS1302 function declaration
uchar Read_Ds1302(uchar addr); //Read DS1302 function declaration
void Set_Ds1302(uchar *str); //Set the clock data address format to: seconds, minutes, hours, days, months, weeks, and years
void Get_Ds1302(uchar *str); //Read current time function declaration
void Init_Ds1302(); //DS1302 initialization function declaration
/********The following is a function to write one byte of data********/
void Ds1302_Write_Byte(uchar ch)
{
   flying n;
   EA=0;
   for(n=0;n<8;n++)
   {
    SCLK=0; //Low level changes data when writing
    if(ch&0x01)
    IO=1;
    else
    IO=0;
    SCLK=1; //High level writes data into DS1302
    _nop_();
 _nop_();
    ch=ch>>1;
   }
   EA=1;
}
/********The following is a function to read one byte of data********/
uchar Ds1302_Read_Byte()   
{
   fly n,temp=0;
   EA=0;
   IO=1;               
   for(n=0;n<8;n++)
   {
    SCLK=1;
    if(IO)
    temp|=0x80;
    else
    temp&=0x7f;
    SCLK=0; //Generate falling edge
    temp=temp>>1;
   }
   EA=1;
   return (temp);
}
/********Write DS1302 function, write data to a certain address of DS1302********/
void Write_Ds1302(uchar cmd,uchar indata)
{
   SCLK=0;
   RST=1;
   Ds1302_Write_Byte(cmd);       
   Ds1302_Write_Byte(indata);
   SCLK=0;
   RST=0;
}
/********Read DS1302 function, read the data of a certain address of DS1302********/
fly Read_Ds1302(fly addr)
{
   fly backdata;
   RST=0;
   SCLK=0;
   RST=1;
   Ds1302_Write_Byte(addr); //Write address first
   backdata=Ds1302_Read_Byte(); //Then read the data
   SCLK=0;
   RST=0;
   return (backdata);
}
/********Set the initial time function********/
void Set_Ds1302(uchar *str)
{
   float n,addr = 0x80;
   Write_Ds1302(0x8e,0x00); //Write control word, allow write operation
   for(n=0;n<7;n++)
   {
     Write_Ds1302(addr,*str);
     addr=addr+2;
  str++;
   }
   Write_Ds1302(0x8e,0x80); //Write protection, writing is not allowed
}
/********Read current time function********/
void Get_Ds1302(uchar *str)
{
 fly n,addr = 0x81;
 for(n=0;n<7;n++)
 {
  str[n]=Read_Ds1302(addr);
  addr+=2;
 }
}
/************Initialization time********************/
void Init_Ds1302()
{
 RST=0;
    SCLK=0;
 RST=1;
 Write_Ds1302(0x80,0x00); //Write the seconds register
    Write_Ds1302(0x90,0xab); //Write charger
    Write_Ds1302(0x8e,0x80); //Write protection control word, prohibit writing
}
///////////////////////////////////////
#endif
/***********************************************************************************************************************/
#ifndef _KEY_H_
#define _KEY_H_
/****************************************************/
#define KEYIO P1 //Define the keyboard input port
unsigned char code KeyTab[17]="123A456B789C*0#D"; //Keyboard lookup table
/***********************************************/
void delay_ms(unsigned int time)   //误差 -0.000000000003us
{
    unsigned char a,b;
 while(time--)
 {
       for(b=102;b>0;b--)
        for(a=3;a>0;a--);
 }
}
/**************************************************/
///////////////////////////////////////////////
unsigned char KeyRvs(void) //Reversal method
{
  unsigned char temH, temL, key;
 delay_ms(10); //The interval between two scans is 10ms to eliminate erroneous operations caused by jitter
  KEYIO = 0x0f; temL = KEYIO; //The upper four bits are output as 0 first; read in, the lower four bits contain the key information
  KEYIO = 0xf0; temH = KEYIO; //Then invert and output 0; read in, the upper four bits contain the key information
 switch(temL)
 {
  case 0x0e: key = 0; break;
  case 0x0d: key = 1; break;
  case 0x0b: key = 2; break;
  case 0x07: key = 3; break;
  default: return 16; //If the button pressed is not one of the above, it is considered as no button
  }
 switch(temH)
 {
  case 0xe0: return  key;
  case 0xd0: return (key + 4);
  case 0xb0: return (key + 8);
  case 0x70: return (key + 12);
  default: return 16; //If the button pressed is not one of the above, it is considered as no button
 }
 
 
}
/**********************************************************/ 
#endif
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef  _IIC_H
#define  _IIC_H_
/***************************************************/

#include
#define uchar unsigned char
#define uint unsigned int
#define SLAVE 0xa0 //IIC device address, please note that all are grounded
#define Rslave SLAVE+1 //send and read control word
sbit SDA=P3^0; //IIC data interface
sbit SCL=P3^1; //IIC clock interface
////////////////////////////////////////////////////////
void delay_iic(uint time)
{
 for(time;time>0;time--);
}
///////////////////////////////////////
void start_iic()
{
 SDA=1;
 SCL=1;
 delay_iic(10);
 SDA=0;
 delay_iic(10);
 SCL=0;
}

void stop_iic()
{
 SDA=0;
 SCL=1;
 delay_iic(10);
 SDA=1;
 delay_iic(10);
 SCL=0;
}

void ack_iic()
{
 SDA=0;
 SCL=1;
 delay_iic(10);
 SCL=0;
 SDA=1;
}

void nack_iic()
{
 SDA=1;
 SCL=1;
 delay_iic(10);
 SCL=0;
 SDA=0;
}

////////////////////////* write 1 byte   *//////////////////////
void write_byte(uchar ch)
{
 flying i;
 for(i=0;i<8;i++)
 {
  if(ch&0x80)
  SDA=1;
  else
  SDA=0;
  SCL=1;
  delay_iic(10);
  SCL=0;
  ch=ch<<1;
 }
 SDA=1;
 SCL=1;
 delay_iic(10);
 if(SDA==1)
 F0=0;
 else
 F0=1;
 SCL=0;
}
///////////////////////////*  read 1 byte  *////////////////////////
fly read_byte()
{
 flying i;
 flying r=0;
 SDA=1;
 for(i=0;i<8;i++)
 {
  r=r<<1;
  SCL=1;
  delay_iic(10);
  if(SDA==1)
  r++;
  SCL=0;
 }
 return r;
}
/***********************Write a byte**************************
bit  Write_Byte_iic(uchar addr,uchar ch)
{
 start_iic(); //Generate start signal
 write_byte(SLAVE); //Send slave device address
 if(F0==0) return 0; //Check the response bit
 write_byte(addr); //Send destination address
 if(F0==0) return 0;
 write_byte(ch); //Send 8 as data
 if(F0==0) return 0;
 stop_iic(); //Stop signal
 return 1;
}
  
/********************Read a byte****************************
uchar Read_Byte_iic(uchar addr)
{ 
 fly ch;       
 start_iic(); //Start IIC
 write_byte(SLAVE); //write device address
 if(F0==0)return 0;
 write_byte(addr); //Write the read address
 if(F0==0)return 0;
 start_iic(); //Generate the start signal again, no less
 write_byte(Rslave); //send and read control word
 if(F0==0)return 0;
 ch=read_byte(); //Read the contents of the specified unit
 nack_iic(); //Non-acknowledgement signal
 stop_iic(); //Stop IIC
 return (ch); 
}
 ************************************************************/
////////////////////////////////////////////////////////////
bit Read_Nbyte_iic(uchar slave,uint addr,uchar *str,uchar  numb)
{
 flying i;
 start_iic();
 write_byte(slave);  //write  iic  addr
 if(F0==0)
 return 0;
 write_byte(addr);  //write  data   addr
 if(F0==0)
 return 0;
 start_iic(); //Generate the start signal again, no less
 write_byte(Rslave); //send and read control word
 if(F0==0)
 return 0;
 for(i=0;i				   
Keywords:DS1302 Reference address:Simple digital tube electronic clock based on DS1302

Previous article:Electronic clock written by single chip microcomputer
Next article:Mini operating system with semaphores and preemptive interrupt scheduling (based on 8051)

Recommended ReadingLatest update time:2024-11-16 17:55

Design of intelligent control system for temperature and humidity in warehouse based on single chip microcomputer
0 Introduction Temperature and humidity control are widely used in people's production and life. For agricultural product seeds, there are relatively strict requirements for environmental temperature and humidity. People usually use thermometers and hygrometers to measure the temperature and humidity of the warehouse
[Microcontroller]
Design of intelligent control system for temperature and humidity in warehouse based on single chip microcomputer
Real-time digital thermometer based on 89S51 (DS1302 18B20)
#include reg51.h #include intrins.h #include math.h #define uchar unsigned char #define uint unsigned int #define S_RST DS_RST=1 #define C_RST DS_RST=0 #define S_CLK DS_CLK=1 #define C_CLK DS_CLK=0 #define Write_Disable RW_DS1302(0x8e,0x80) //写保护 #define Write_Enable RW_DS1302(0x8e,0x00) //允许写入
[Microcontroller]
Real-time digital thermometer based on 89S51 (DS1302 18B20)
ST7920 LCD --- DS1302 clock program
sbit LCD12864_EN=P2^7; //E sbit LCD12864_DIN=P2^ 5; //  RS sbit LCD12864_CLK        = P2 ^6  ; //  RW sbit DS1302_CLK  = P2^0;// P1^0; sbit DS1302_IO =P2^1;// P1^1; sbit DS1302_RST =P2^2;// P1^2; unsigned char time ={0x10,0x01,0x27,0x03,0x14,0x00,0x00};// Initialization time year month day week hour minute second     
[Microcontroller]
DS1302 read and write driver
/**************************  Resources used in the file 1. Port: P0.4, P0.5, P0.6 2. Call delay_ms function ******************************/ /***********************  1302 pin definition ***************************/ sbit T_RST = P0^4; sbit T_DAT = P0^5; sbit T_CLK = P0^6; /********************************  1302 subrout
[Microcontroller]
[STC MCU Learning] Lesson 14: SPI Communication - Real-time Clock DS1302
1.14.1. Background knowledge about RTC 1.14.1.1 What is a Real Time Clock (RTC)? (1) Distinguishing between time points and time periods Time period: timer/counter; water boiling; not unique Time point: RTC; Alarm, calendar; Unique (2) Why does the microcontroller need a time point? Sometimes the microcontroller n
[Microcontroller]
[STC MCU Learning] Lesson 14: SPI Communication - Real-time Clock DS1302
AT89C2051+LCD1602+DS1302 Real-time Clock Design (c51)
#include #include intrins.h #define uchar unsigned char sbit rs=P3^0;//LCD1602控制脚 sbit rw=P3^1; sbit e=P3^2; sbit io=P3^4; //DS1302 PCI bus pin sbit rst=P3^5; sbit sclk=P3^3; uchar hour,minute,second,year,months,date,day; //Display time register uchar whour,wminute,wsecond,wyear,wmonths,wdate,wday; //Set i
[Microcontroller]
LCD1602&DS1302 clock test program + simulation diagram sharing
comments: 1. Eight-wire drive LCD1602B: PB0-PB7 are data lines, PD3/PD4/PD6 control RS, RW, EN of LCD1602B. 2. Set and read the internal clock of DS1302, and display it through LCD1602. 3. For this experiment, please plug in all 8 short-circuit blocks of JP1 and JP2, and short-circuit blocks of PC2, PC3, PC4, and PC7.
[Microcontroller]
LCD1602&DS1302 clock test program + simulation diagram sharing
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
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号