Arduino入門筆記(7):利用1602、1302實現時鍾和定時器


轉載請注明:@小五義 http://www.cnblogs.com/xiaowuyi

歡迎加入討論群 64770604

      常常聽到老媽在做飯時說“開鍋15分鍾后叫我一下”,為何不做個定時器,來提醒老媽呢?結合前面學習的知識,再加上1302時間模塊,我決定自己做一個。

一、本次實驗所需器材

1、Arduino UNO板 https://item.taobao.com/item.htm?spm=a1z10.5-c-s.w4002-15820725129.16.AtgoEm&id=545093340395

2、1602液晶板:http://www.cnblogs.com/xiaowuyi/p/3390024.html(或者http://wikicode.net/?p=232)已經介紹過。

3、DS1302實時時鍾模塊:DALLAS 公司推出的涓流充電時鍾芯片,內含有一個實時時鍾/日歷和31 字節靜態RAM ,通過簡單的串行接口與單片機進行通信。實時時鍾/日歷電路提供秒、分、時、日、周、月、年的信息,每月的天數和閏年的天數可自動調整。時鍾操作可通過 AM/PM 指示決定采用24 或12 小時格式。DS1302 與單片機之間能簡單地采用同步串行的方式進行通信,僅需用到三個口線:(1)RST 復位(2)I/O 數據線(3)SCLK串行時鍾。

(1)DS1302主要性能指標
★ 實時時鍾具有能計算2100 年之前的秒、分、時、日、星期、月、年的能力,還有閏年調整的能力
★ 31 8 位暫存數據存儲RAM
★ 串行 I/O 口方式使得管腳數量最少
★ 寬范圍工作電壓2.0 5.5V
★ 工作電流 2.0V 時,小於300nA
★ 讀/寫時鍾或RAM 數據時有兩種傳送方式單字節傳送和多字節傳送字符組方式
★ 8 腳DIP 封裝或可選的8 腳SOIC 封裝根據表面裝配
★ 簡單 3 線接口
★ 與 TTL 兼容Vcc=5V
★ 可選工業級溫度范圍-40 +85
★ 雙電源管用於主電源和備份電源供應
(2)接線方法(以本實驗程序為例)

VCC→+5V/3.3V

GND→GND

CLK→5

DAT→3

RST→2

4、按鈕開關一個:按鈕開關在連接時,需要接一個1KΩ電阻做為下拉電阻。具體關於按鈕的使用可參考(http://www.geek-workshop.com/forum.php?mod=viewthread&tid=74

5、蜂鳴器一個

6、電阻:1KΩ電阻、10KΩ電阻

二、硬件連接方法

    DS1602的連接主要采用四位連接法(http://www.cnblogs.com/xiaowuyi/p/3390024.html),端口為12,11,9,8,7,6。DS1302的連接方法上面已給出,另外按鈕開關、蜂鳴器等的連接具體見下圖。

1602_bb

三、程序代碼

    具體代碼如下:

// DS1302:  RST pin    -> Arduino Digital 2
//          DAT pin   -> Arduino Digital 3
//          CLK pin  -> Arduino Digital 5
#include <LiquidCrystal.h>
#include <DS1302.h>
LiquidCrystal lcd(12, 11, 9, 8, 7, 6);
DS1302 rtc(2, 3, 5);
int j=0;//記錄定時設定分鍾數
int time=0;//remine the last time 
int button=13;//13口控制按鈕
boolean onoff= LOW; //記錄按鈕狀態
boolean timefix=LOW;//記時器開關,LOW表示未定時,HIGH表示定時
unsigned long buttonHoldTime = 0;//按鈕按下持續時間
int buttonStateOld;//按鈕上一時刻狀態
int buttonState;//按鈕本時刻狀態


void ting()//控制蜂鳴器發聲
{

    int checkstate = digitalRead(button);
    for(int i=0;i<80;i++)//輸出一個頻率的聲音
    {
      digitalWrite(10,HIGH);//發聲音
      delay(1);//延時1ms
      digitalWrite(10,LOW);//不發聲音
      delay(1);//延時ms
    }
    for(int i=0;i<100;i++)//輸出另一個頻率的聲音,這里的100與前面的80一樣,用來控制頻率,可以自己調節
    {
      digitalWrite(10,HIGH);
      delay(2);
      digitalWrite(10,LOW);
      delay(2);
    }
}

void clockdate()//1602顯示時間
{
        lcd.clear(); //清屏
        lcd.setCursor(0,0);
        lcd.print(rtc.getDateStr(FORMAT_LONG,FORMAT_BIGENDIAN, '-'));//從1302的庫文件可以看出,這里有下面幾種格式FORMAT_BIGENDIAN:2010-01-01;FORMAT_LITTLEENDIAN:01-01-2010
        lcd.setCursor(11,0);
        lcd.print(rtc.getDOWStr());
        lcd.setCursor(14,0);
        lcd.print("    ");
        lcd.setCursor(0, 1) ;
        lcd.print(rtc.getTimeStr());
}

void setup()
{
  lcd.begin(16, 2);  //初始化LCD
  pinMode(10,OUTPUT);//設置數字IO腳模式,OUTPUT為輸出
  pinMode(button,INPUT);//設置引腳為輸入模式
  // 設置時鍾初始值
  rtc.halt(false);
  rtc.writeProtect(false);

  rtc.setDOW(SATURDAY);        // 設置星期
  rtc.setTime(22, 56,00);     //設置時間
  rtc.setDate(9, 11, 2013);   // 設置日期2013年11月9日
  rtc.writeProtect(true);
}

void loop()
{ 
  buttonState = digitalRead(button);
  delay(20);
  if (buttonState==HIGH && buttonStateOld==LOW)//按鈕狀態發生變化
  {
    buttonHoldTime = millis();//用millis()時間函數來記時,該函數最長記錄時間為9小時22分,由於本程序最多記錄60分鍾,所以可以使用
    buttonStateOld =buttonState;

    if (onoff==HIGH)//當進入定時設置狀態時
    {

          if (j>59)
          {
              j=0;
              timefix=LOW;
          }
          else
          {
              j=j+1;
              timefix=HIGH;
              
          }
          lcd.setCursor(11,0); 
          lcd.print(j); 
    }
  }
  else if (buttonState ==HIGH && buttonStateOld==HIGH)//判斷按鈕是否持續按下
  {
     if (millis()-buttonHoldTime>3000)//當按鈕持續按下3秒種進入定時狀態
     {
        buttonStateOld=LOW;
  
        if (onoff==LOW)//進入
        {
          j=0;
          timefix=LOW;
          lcd.clear(); //清屏
          lcd.setCursor(0,0);
          lcd.print("Fixed Time:");
          lcd.setCursor(11,0); 
          lcd.print(j); 
          lcd.setCursor(13,0);
          lcd.print("min");
          
          onoff=HIGH;
        }
        else//退出
        {
          
          clockdate();
  //        Serial.println(rtc.getTimeStr());
          buttonHoldTime = millis();
          onoff= LOW;
        }
        
     }
     else
     {
       buttonStateOld =buttonState;
     }
  }
  else
  {
    buttonStateOld =buttonState;
  }


   if (onoff==LOW)
   {
     clockdate();
      
   }

    if (timefix==HIGH && j>0 && onoff==LOW)
    {
      unsigned long delaytime=j*60000;//把分鍾計算成秒

      if ((millis()-buttonHoldTime)>=delaytime )
      {

          do
          {
            buttonState = digitalRead(button);
            ting();
          }while (buttonState==LOW);//當按下按鈕后,停止蜂鳴
          j=0;
      }
      else
      {
        clockdate();
      }
    }

  delay(1000);
  
}

 

    這個代碼中,初始時間是設定好的,即2013年11月9日22點56分,因此本程序沒有加入時鍾時間設定功能,也可以再加上幾個按鈕,加上時間調節功能。另外在判斷按鈕按下時間這里,本程序的方法自我感覺有時笨,但也沒想出更好的方法,哪位有更好的方法,請給指導一下,謝謝。

四、實現效果

    實現過程中,發現存在兩個問題,一個是按鈕不是很靈敏,另一個是最后再退出調時狀態時,長按3秒,時間會增加1分鍾。如原本設定12分鍾,退出時長按3秒會依然會變成13分鍾。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM