这里的esp8266选用D1 mini开发板,DS1302加I2C转接模块。首先上效果图。

接着上代码。

/*  ---By www.yizu.org---
              Connect
        D1 mini       I2C_LCD
          5V            VCC
          GND           GND
          D2            SDA
          D1            SCL
        D1 mini       DS1302
          3V3           VCC
          GND           GND
          D6            CLK
          D7            DAT
          D8            RST
*/

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
#include <LiquidCrystal_I2C.h>
#include <TimeLib.h>
#include <Arduino.h>
#include <DS1302.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

//设置NTPClient
#define NTP_OFFSET   60 * 60 * 8  // 时区偏移量
#define NTP_ADDRESS  "ntp1.aliyun.com"  // NTP服务器
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, NTP_ADDRESS, NTP_OFFSET);

//设置时钟模块
DS1302 rtc(15,13,12);

//设置校对时间间隔(单位秒)
#define CALIBRATION_INTERVAL 60
unsigned long t_stamp=0;
unsigned long t_stamp2=0;

//设置WIFI账号密码
const char* ssid = "wifi";
const char* password = "123456789";

//显示字符
#if defined(ARDUINO) && ARDUINO >= 100
#define printByte(args)  write(args);
#else
#define printByte(args)  print(args,BYTE);
#endif

//要显示的特殊字符
//uint8_t nian[8] = {0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02,};//年
//uint8_t yue[8]  = {0x0f,0x09,0x0f,0x09,0x0f,0x09,0x0b,0x11,};//月
//uint8_t ri[8]   = {0x1F,0x11,0x11,0x1F,0x11,0x11,0x1F,0x00,};//日
uint8_t dian[8] = {0x02,0x05,0x02,0x00,0x00,0x00,0x00,0x00,};//点
uint8_t dianC[8] ={0x00,0x17,0x08,0x08,0x08,0x08,0x07,0x00,};//温度单位
uint8_t wificon[8] ={0x00,0x0E,0x11,0x04,0x0A,0x00,0x04,0x00,};//WIFI链接
uint8_t wificon2[8]={0x00,0x11,0x0A,0x04,0x0A,0x11,0x00,0x00,};//断网

const char * days[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"} ;

//连接WIFI
void connectToWiFi()
{
  Serial.println("");
  Serial.print("Connecting to ");
  Serial.print(ssid);
  
  WiFi.begin(ssid, password);
  Serial.println("");
  Serial.print("Connected to WiFi at ");
  Serial.print(WiFi.localIP());
  Serial.println("");
  unsigned int count = 0;
    while ((count < 10 ) & (WiFi.status() != WL_CONNECTED)) {
      delay(500);
      Serial.print(".");
      count ++;
  }
}

//显示WIFI连接状态
void showWifiStatus()
{
  lcd.setCursor(11, 0);
  if(WiFi.status() == WL_CONNECTED)
  {
    lcd.write(byte(5));
  }
  else
  {
    lcd.write(byte(6));
  }
}

//校对时间
void correctionTime()
{
  time_t tnow=now();
  if(t_stamp==0||tnow-t_stamp>=10)//每10秒校对系统时钟
  {
    Serial.println("");
    Serial.print(rtc.getTimeStr());
    Serial.print(" Correction the time.");
    if(WiFi.status() == WL_CONNECTED&&(t_stamp2==0||tnow-t_stamp2>=CALIBRATION_INTERVAL))
    {
      if(timeClient.update())
      {
        unsigned long t=timeClient.getEpochTime();
        //设置系统时间
        setTime(t);
        Serial.println("");
        Serial.print("SysTime=NTP:");
        Serial.printf("%02d:%02d:%02d",hour(t), minute(t), second(t));
        //设置RTC时钟
        if(rtc.peek(0)==88)
        {
          rtc.writeProtect(false);
          rtc.setDOW(weekday(t)+1);
          rtc.setTime(hour(t), minute(t), second(t));
          rtc.setDate(day(t), month(t), year(t));
          rtc.writeProtect(true);
        }
      }
      else
      {
        if(rtc.peek(0)==88)
        {
          //设置系统时间
          Time t=rtc.getTime();
          setTime(t.hour,t.min,t.sec,t.date,t.mon,t.year);
          Serial.println("");
          Serial.print("SysTime=RTC:");
          Serial.printf("%02d:%02d:%02d",t.hour,t.min,t.sec);
        }
      }
      t_stamp2=now();
    }
    else
    {
      if(rtc.peek(0)==88)
      {
        //设置系统时间
        Time t=rtc.getTime();
        setTime(t.hour,t.min,t.sec,t.date,t.mon,t.year);
        Serial.println("");
        Serial.print("SysTime=RTC:");
        Serial.printf("%02d:%02d:%02d",t.hour,t.min,t.sec);
      }
    }
    t_stamp=now();
  }
}

void setup()
{
  Serial.begin(115200);

  lcd.init();// 初始化lcd
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Starting...");
  lcd.setCursor(0, 1);
  lcd.print("Please wait.");
  //联网
  connectToWiFi();
  //初始化NTPClient
  timeClient.begin();
  //开启时钟
  if(rtc.peek(0)!=88)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("System reseted!");
    rtc.writeProtect(false);
    rtc.halt(false);
    rtc.poke(0,88);//写入启动标记
    rtc.writeProtect(true);
    delay(1000);
  }
  //对时
  correctionTime();
  lcd.clear();
}


void loop()
{
  correctionTime();
  // 打印到屏幕
  //lcd.createChar(1, nian);
  //lcd.createChar(2, yue);
  //lcd.createChar(3, ri);
  lcd.createChar(4, dianC);
  lcd.createChar(5, wificon);
  lcd.createChar(6, wificon2);
  
  time_t t=now();
  lcd.setCursor(0, 0);
  //lcd.printf("%04d",year(t));
  //lcd.write(byte(1));
  //lcd.printf("%02d",month(t));
  //lcd.write(byte(2));
  //lcd.printf("%02d",day(t));
  //lcd.write(byte(3));
  lcd.printf("%04d-%02d-%02d",year(t),month(t),day(t));
  lcd.setCursor(9, 1);
  lcd.print(days[weekday(t)-1]);
  lcd.setCursor(0, 1);
  lcd.printf("%02d:%02d:%02d",hour(t),minute(t),second(t));
  lcd.setCursor(13, 0);
  lcd.print("30");//显示温度,暂未加入该功能
  lcd.write(byte(4));
  lcd.setCursor(13, 1);
  lcd.print("25%");//显示湿度,暂未加入该功能
  showWifiStatus();
}

DS1302模块的库下载自http://www.rinkydinkelectronics.com/library.php?id=5,其他库均可在Arduino IDE中搜索下载。
此段代码可以做到没有网络,或者去掉DS1302时都可正常运行。代码中,每隔10秒系统与DS1302模块校对时间,每隔60秒与NTP服务器校对时间,可以按需修改即可。屏幕上显示了一个WIFI连接的图标,WIFI断开时会显示一个“X”。