sjiliang 发表于 2020-2-28 10:59:55

Arduino + DS1307 RTC+LCD1602 学习心得共享

做温度记录仪中用到几个巡检按键,之中感觉按键反应迟钝;感觉LCD1602刷新缓慢,占时多是主要原因之一。
为此,想到一个概念:电视机屏幕刷新的一种方式是,只针应对图像中变化部位;故此,可以极大简化运行时长和难度。
在此,针对性调整LCD1602显示方式,见程序。

初始程序
#include <Wire.h>
#include <RTClib.h>

#include <LiquidCrystal.h>

RTC_DS1307 RTC;

const int rs = 9, en = 8, d4 = 7, d5 = 6, d6 = 5, d7 = 4;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup ()
{
    Serial.begin(9600);
    Wire.begin();
    RTC.begin();

    lcd.begin(16,2);

    if (! RTC.isrunning())    //初次运行对DS1307初始化时间。此后不再运行。
    {
      Serial.println("RTC is NOT running!");      // following line sets the RTC to the date & time this sketch was compiled
      RTC.adjust(DateTime(__DATE__, __TIME__));//此句经 if 选择后调用。
   }   
}

void loop ()
{
    DateTime now = RTC.now();   
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.println(now.second(), DEC);

    lcd.setCursor(0,0);
    lcd.print(now.year(), DEC);
    lcd.print('/');
      if (now.month()<10)
      lcd.print('0');
    lcd.print(now.month(), DEC);
    lcd.print('/');
      if (now.day()<10)
      lcd.print('0');
    lcd.print(now.day(), DEC);
    lcd.setCursor(11,0);
      if (now.hour()<10)
      lcd.print('0');
    lcd.print(now.hour(), DEC);
    lcd.print(':');            //此处每500ms亮灭一次,代替秒显示。
      if (now.minute()<10)
      lcd.print('0');
    lcd.print(now.minute(), DEC);

    lcd.setCursor(0,1);         //欢迎词显示
    lcd.print("Tem Logger No.01");
   
    delay(500);lcd.setCursor(13,0);lcd.print(' ');
    delay(500);
   
    /*******以下为主程序段 此处省略**********/
    {   }
}



/*改进后程序*/
/*按键 弱上拉设置,测试
F功能键:
Y确认键:长按选择 时长设置/记录运行;短按调整时长 小时/分钟。

SD管脚配置
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 10
*/
#include <Wire.h>
#include <SD.h>
#include "RTClib.h"
RTC_DS1307 RTC;            //启动 RTC对象
      //Lcd 库 配置
#include <LiquidCrystal.h>
const int rs = 9, en = 8, d4 = 7, d5 = 6, d6 = 5, d7 = 4;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup ()
{
    Serial.begin(9600);
    Wire.begin();
    RTC.begin();
    if(!SD.begin(CS_PIN)){
      digitalWrite(A3,1);delay(300);digitalWrite(A3,0);//响铃
      }
      
    //按键管脚状态设置
    fourButton();
   
    // 响应鸣叫管脚
    pinMode(A3, OUTPUT);                        
    digitalWrite(A3,0);                        

   //初次运行对DS1307时间初始化。此后不再运行。
    if (! RTC.isrunning()){
      RTC.adjust(DateTime(__DATE__, __TIME__));   //此句经 if 选择后调用。
      }         
   DateTime Now = RTC.now();
   //首行显示:年/月/日 小时:分钟。
    lcd.setCursor(0,0);                        
      lcd.print(Now.year(), DEC);   
    lcd.print('/');
      if (Now.month()<10)
      lcd.print('0');
      lcd.print(Now.month(), DEC);   
    lcd.print('/');
      if (Now.day()<10)             //若数字小于2位数,前面加0
      lcd.print('0');
    lcd.print(Now.day(), DEC);   
    lcd.setCursor(11,0);
      if (Now.hour()<10)         //若数字小于2位数,前面加0
      lcd.print('0');
      lcd.print(Now.hour(), DEC);   
    lcd.print(':');                  //此处每500ms亮灭一次,代替秒显示。见后面语句
      if (Now.minute()<10)         //若数字小于2位数,前面加0
      lcd.print('0');
      lcd.print(Now.minute(), DEC);
      
   old_minute = Now.minute();
   old_hour = Now.hour();
   old_day = Now.day();
   old_month = Now.month();
   old_year = Now.year();   
}
void loop (){                                          
    DateTime Now = RTC.now();   
      lcd.setCursor(13,0);lcd.blink();            //首行秒':'光标闪烁      
   //时钟利用覆盖更新
    if( Now.minute()!=old_minute ){            //分钟覆盖
   lcd.setCursor(14,0);
   if ( Now.minute()<10 )lcd.print('0');   //小于10补0   
   lcd.print(Now.minute(), DEC);
   old_minute=Now.minute();
         
   if(Now.hour()!=old_hour){                  //小时覆盖 嵌套1
       lcd.setCursor(11,0);
       if (Now.hour()<10)lcd.print('0');         
       lcd.print(Now.hour(), DEC);
       old_hour=Now.hour();
      
       if(Now.day()!=old_day){               //日期覆盖 嵌套2
      lcd.setCursor(8,0);
      if (Now.day()<10)lcd.print('0');         
      lcd.print(Now.day(), DEC);
         old_day=Now.day();
               
      if( Now.month()!=old_month){      //月份覆盖 嵌套3
         lcd.setCursor(5,0);
         if (Now.month()<10) lcd.print('0');
         lcd.print(Now.month(), DEC);
            old_month=Now.month();
                     
          if(Now.year()!=old_year){         //年份覆盖 嵌套4
            lcd.setCursor(0,0);                        
            lcd.print(Now.year(), DEC);
             old_year=Now.year();
          }}}}}
      /******以下为主程序段 此处省略******/
}

入门较浅,抛石引玉。也望大家都拿出心得共享。

sjiliang 发表于 2020-2-28 11:01:53

第二段程序粘贴不利。还需各位指点。
页: [1]
查看完整版本: Arduino + DS1307 RTC+LCD1602 学习心得共享