Arduino DS1302 時鐘模塊應(yīng)用示例(帶鬧鐘功能)

呃吴汪,說點什么呢?

沒啥好說的蒸眠,很基礎(chǔ)的東西浇坐。也是多年前某寶買了來,一直丟在角落里黔宛。還能找點兒空閑近刘,就想讓它們也動一動。
免得怪我遺忘了它們臀晃。

時鐘模塊用的是 DS1302觉渴,蜂鳴器用的是有源蜂鳴器(無源的還要設(shè)置頻率編個曲兒啥的,我比較懶徽惋,喜歡直接一點的案淋,HIGH or LOW)。


就是上面這些東西险绘。

沒有加按鈕踢京,因為后續(xù)打算添加 LCD 顯示屏和溫濕度傳感器,做成一個比較完整的系統(tǒng)宦棺。所以 Arduino 的 IO 接口瓣距,能省就省了。時間設(shè)置以及其他功能代咸,可以通過串口輸入命令配置蹈丸。鬧鐘是在代碼的常量定義里手動修改(圖省事啊)呐芥。

還有就是逻杖,用到的庫文件來自網(wǎng)絡(luò),作者我他么也不認(rèn)識思瘟。剩下的代碼幾乎全是我個人完成荸百,沒系統(tǒng)地學(xué)過 C,所以應(yīng)該還有很大的提升空間滨攻。

線路連接圖如下:


運行效果如下:


上代碼了啊

ds1302.ino(這個是我寫的够话。。铡买。)

/******************************************************************************
-------------------------1.開發(fā)環(huán)境:Arduino IDE-----------------------------------
-------------------------------2.作者:starky-----------------------------------------
******************************************************************************/
#include <Arduino.h>
#include "DS1302.h"

#define Buzz_Pin 5                 // 有源蜂鳴器引腳
unsigned char Alarm_Hour=6;          // 鬧鐘小時設(shè)置
unsigned char Alarm_Minute=30;        // 鬧鐘分鐘設(shè)置
bool Always=false;                 //是否不間斷地輸出時間到串口(每隔 1 秒)

void setup()
{
  pinMode(Buzz_Pin,OUTPUT);
  DS1302_Init();
  Serial.begin(9600); 
  Serial.println("Welcome to use!");  
  DS1302_GetTime(&DS1302Buffer);
  Display_RTCC();
  Serial.println("Type \"help\" To Get The Help Information.");
}

//顯示時間
void Display_RTCC()
{
  
  if(DS1302Buffer.Year < 10)
  {
    Serial.print("200");
  }
  else
  {
    Serial.print("20");
  }
  Serial.print(DS1302Buffer.Year);
  Serial.print('-');
  Serial.print(DS1302Buffer.Month);
  Serial.print('-');
  Serial.print(DS1302Buffer.Day);

  Serial.print("   ");

  switch(DS1302Buffer.Week)
  {
    case 1:
        Serial.println("Mon");         //顯示星期一
        break;
    case 2:
        Serial.println("Tue");         //顯示星期二
        break;
    case 3:
        Serial.println("Wed");         //顯示星期三
        break;
    case 4:
        Serial.println("Thu");         //顯示星期四
        break;
    case 5:
        Serial.println("Fri");         //顯示星期五
        break;
    case 6:
        Serial.println("Sat");         //顯示星期六
        break;
    case 7:
        Serial.println("Sun");         //顯示星期日
        break;
    default : break;            
  }

  Serial.print(DS1302Buffer.Hour);
  Serial.print(':');
  Serial.print(DS1302Buffer.Minute);
  Serial.print(':');
  Serial.println(DS1302Buffer.Second);
}

// 獲取串口輸入
void Scan_Input()
{
  String comdata=""; 
  while (Serial.available() > 0)  
   {
     comdata += char(Serial.read());
     delay(2);
   }
  if(comdata.length()==20 && comdata.startsWith("set"))
    {
      Set_Time(comdata);
    }
  if(comdata=="show")
  {
    Serial.println("The Time Now Is:");
    Always=false;
    Display_RTCC();
  }

//是否不間斷地將時間輸出到串口
  if(comdata=="always")
  {
    Always=!Always;
  }

//顯示鬧鐘
  if(comdata=="alarm")
  {
    Serial.print("Alarm Set to ");
    Serial.print(Alarm_Hour); 
    Serial.print(":");
    Serial.println(Alarm_Minute);   
  }
  if(comdata=="help")
  {
    help();
  }
}

//時間設(shè)置函數(shù)
void Set_Time(String &command)
{
  DS1302_ON_OFF(0);     //關(guān)閉振蕩
  DS1302Buffer.Year=command.substring(4,6).toInt();
  DS1302Buffer.Month=command.substring(7,9).toInt();
  DS1302Buffer.Day=command.substring(10,12).toInt();
  DS1302Buffer.Week=command.substring(13,14).toInt();
  DS1302Buffer.Hour=command.substring(15,17).toInt();
  DS1302Buffer.Minute=command.substring(18).toInt();
  DS1302_SetTime( DS1302_YEAR , DS1302Buffer.Year );
  DS1302_SetTime( DS1302_MONTH , DS1302Buffer.Month );
  DS1302_SetTime( DS1302_DAY , DS1302Buffer.Day );
  DS1302_SetTime( DS1302_WEEK , DS1302Buffer.Week );
  DS1302_SetTime( DS1302_HOUR , DS1302Buffer.Hour );
  DS1302_SetTime( DS1302_MINUTE , DS1302Buffer.Minute );
  DS1302_ON_OFF(1);
  Always=false;
  Serial.println("Set Done");
  Display_RTCC();   
}

//蜂鳴器報警函數(shù)
void buzz(int &times)
{
  for(int i=0;i<times;i++){
    digitalWrite(Buzz_Pin,HIGH);
    delay(650);
    digitalWrite(Buzz_Pin,LOW);
    delay(250);
    }
}

//幫助內(nèi)容
void help()
{
  Serial.println("************************************* HELP *****************************************");
  Serial.println("Edited By Starky");
  Serial.println("Type \"set YY MM DD WEEK HH MM\" To Set The Time!");
  Serial.println("Such As Type \"set 08 08 08 1 12 00\" To Set The Time As 2008-8-8 Monday 12:00");
  Serial.println("Type \"show\" To Display The Time Now!");
  Serial.println("Type \"always\" To Print The Time Every Second!");
  Serial.println("Type \"alarm\" To Check The Current Alarm");
  Serial.println("Welcome To Use!"); 
  Serial.println("************************************* HELP *****************************************");
}

void loop()
{
  Scan_Input();
  DS1302_GetTime(&DS1302Buffer);        //獲取當(dāng)前RTCC值
  if(Always)
  {
    if(Flag_Time_Refresh == 1)
      {
          Flag_Time_Refresh = 0;
          Display_RTCC();
      }
  }
  
  // 鬧鐘激活
  if(DS1302Buffer.Hour==Alarm_Hour && DS1302Buffer.Minute==Alarm_Minute && DS1302Buffer.Second==0)
  {
    int times=15;        // 報警次數(shù)
    buzz(times);
  }
}

以下是庫文件內(nèi)容

DS1302.cpp

/******************************************************************************
----------------1.開發(fā)環(huán)境:Arduino IDE-----------------------------------------
----------------2.測試使用開發(fā)板型號:Arduino UNO R3-------
----------------3.單片機使用晶振:16M------------------------------------------
----------------4.作者:神秘藏寶室---------------------------------------------
******************************************************************************/
#include "DS1302.h"

SYSTEMTIME DS1302Buffer;
bool Flag_Time_Refresh = 1;

//****************************************************
//實時時鐘寫入一字節(jié)(內(nèi)部函數(shù))
//****************************************************
void DS1302_InputByte(unsigned char dat)    
{ 
    unsigned char i;

    pinMode(DS1302_IO,OUTPUT);

    for(i=0; i<8; i++)
    {
        if((dat & 0x01) == 1)
        {
            DS1302_IO_1;
        }
        else
        {
            DS1302_IO_0;
        }
          
        
        DS1302_CLK_0;               //上升沿寫入數(shù)據(jù)
        
        delayMicroseconds(2);
        
        DS1302_CLK_1;
        
        delayMicroseconds(2);
        dat >>= 1; 
    } 
}

//****************************************************
//實時時鐘讀取一字節(jié)(內(nèi)部函數(shù))
//****************************************************
unsigned char DS1302_OutputByte(void)   
{ 
    unsigned char i;
    unsigned char dat;
    pinMode(DS1302_IO,INPUT);
    for(i=0; i<8; i++)
    {
        DS1302_CLK_1;                   //下降沿讀出數(shù)據(jù)
        delayMicroseconds(2);
        DS1302_CLK_0;
        delayMicroseconds(2);
        dat >>= 1;                  
        if( digitalRead(DS1302_IO) == HIGH )
            dat |= 0x80;                //最高位置一
        else
            dat &= 0x7F;                //最高位清零       
    } 
    return(dat); 
}

//****************************************************
//ucAddr: DS1302地址, ucData: 要寫的數(shù)據(jù)
//****************************************************
void DS1302_Write(unsigned char ucAddr, unsigned char ucDa) 
{
    DS1302_RST_0;
    delayMicroseconds(2);
    DS1302_CLK_0;
    delayMicroseconds(2);
    DS1302_RST_1;
    delayMicroseconds(2);
    DS1302_InputByte(ucAddr);           // 地址更鲁,命令 
    DS1302_InputByte(ucDa);             // 寫1Byte數(shù)據(jù)
    DS1302_CLK_1;
    delayMicroseconds(2);
    DS1302_RST_0;
    delayMicroseconds(2);
}

//****************************************************
//讀取DS1302某地址的數(shù)據(jù)
//****************************************************
unsigned char DS1302_Read(unsigned char ucAddr) 
{
    unsigned char ucData;
    DS1302_RST_0;
    delayMicroseconds(2);
    DS1302_CLK_0;
    delayMicroseconds(2);
    DS1302_RST_1;
    delayMicroseconds(2);
    DS1302_InputByte(ucAddr|0x01);        // 地址,命令 
    ucData = DS1302_OutputByte();         // 讀1Byte數(shù)據(jù)
    DS1302_CLK_1;
    delayMicroseconds(2);
    DS1302_RST_0;
    delayMicroseconds(2);
    return(ucData);
}

//****************************************************
//是否寫保護
//****************************************************
void DS1302_SetProtect(unsigned char flag)       
{
    if(flag)
        DS1302_Write(0x8E,0x10);            //保護
    else
        DS1302_Write(0x8E,0x00);            //不保護
} 

//****************************************************
// 設(shè)置時間函數(shù)
//****************************************************
void DS1302_SetTime(unsigned char Address, unsigned char Value)        
{
    DS1302_SetProtect(0);
    DS1302_Write(Address, ((Value/10)<<4 | (Value%10))); 
}

//****************************************************
//獲取實時時間
//****************************************************
void DS1302_GetTime(SYSTEMTIME *Time)
{
    unsigned char ReadValue;
    ReadValue = DS1302_Read(DS1302_SECOND);
    ReadValue = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);            //BCD碼轉(zhuǎn)換十進制
    if(ReadValue != DS1302Buffer.Second)                                //跟上一次狀態(tài)不同奇钞,置位刷新標(biāo)志位
        Flag_Time_Refresh = 1;
    Time->Second = ReadValue;

    ReadValue = DS1302_Read(DS1302_MINUTE);
    Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
    ReadValue = DS1302_Read(DS1302_HOUR);
    Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
    ReadValue = DS1302_Read(DS1302_DAY);
    Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);    
    ReadValue = DS1302_Read(DS1302_WEEK);
    Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
    ReadValue = DS1302_Read(DS1302_MONTH);
    Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
    ReadValue = DS1302_Read(DS1302_YEAR);
    Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);   
}

//****************************************************
//初始化
//****************************************************
void DS1302_Init(void)
{
    unsigned char Second;

    pinMode(DS1302_RST,OUTPUT);
    pinMode(DS1302_IO,OUTPUT);
    pinMode(DS1302_CLK,OUTPUT);

    Second = DS1302_Read(DS1302_SECOND);
    if(Second&0x80)       
        DS1302_SetTime(DS1302_SECOND,Second & 0x7f);    //開啟振蕩    
}
//****************************************************
//DS1302振蕩器停止
//****************************************************
void DS1302_ON_OFF(bool FLAG_ON_OFF)
{
    unsigned char Second;
    Second = DS1302_Read(DS1302_SECOND);
    if(FLAG_ON_OFF == 0)
        DS1302_Write(DS1302_SECOND,Second | 0x80);              //關(guān)閉振蕩
    else
        DS1302_Write(DS1302_SECOND,Second & 0x7f);              //開啟振蕩
}

DS1302.h

/******************************************************************************
----------------1.開發(fā)環(huán)境:Arduino IDE-----------------------------------------
----------------2.測試使用開發(fā)板型號:Arduino Leonardo or Arduino UNO R3-------
----------------3.單片機使用晶振:16M------------------------------------------
----------------4.作者:神秘藏寶室---------------------------------------------
******************************************************************************/
#ifndef __DS1302_H__
#define __DS1302_H__

#include <Arduino.h>

//DS1302 IO設(shè)置
#define DS1302_RST 2     //實時時鐘復(fù)位線引腳
#define DS1302_IO 3      //實時時鐘數(shù)據(jù)線引腳
#define DS1302_CLK 4     //實時時鐘時鐘線引腳


#define DS1302_RST_0 digitalWrite(DS1302_RST,LOW)
#define DS1302_RST_1 digitalWrite(DS1302_RST,HIGH)

#define DS1302_IO_0 digitalWrite(DS1302_IO,LOW)
#define DS1302_IO_1 digitalWrite(DS1302_IO,HIGH)

#define DS1302_CLK_0 digitalWrite(DS1302_CLK,LOW)
#define DS1302_CLK_1 digitalWrite(DS1302_CLK,HIGH)


//宏定義
#define DS1302_SECOND   0x80
#define DS1302_MINUTE   0x82
#define DS1302_HOUR     0x84 
#define DS1302_DAY      0x86
#define DS1302_MONTH    0x88
#define DS1302_WEEK     0x8a
#define DS1302_YEAR     0x8c 


typedef struct __SYSTEMTIME__
{
    unsigned char Second;
    unsigned char Minute;
    unsigned char Hour;
    unsigned char Week;
    unsigned char Day;
    unsigned char Month;
    unsigned char  Year;
}SYSTEMTIME;    //定義的時間類型


//函數(shù)或者變量聲明
extern void DS1302_InputByte(unsigned char dat);
extern unsigned char DS1302_OutputByte(void) ;
extern void DS1302_Write(unsigned char ucAddr, unsigned char ucDa);
extern unsigned char DS1302_Read(unsigned char ucAddr);
extern void DS1302_SetProtect(unsigned char flag) ;
extern void DS1302_SetTime(unsigned char Address, unsigned char Value);
extern void DS1302_GetTime(SYSTEMTIME *Time);
extern void DS1302_Init(void);
extern void DS1302_ON_OFF(bool FLAG_ON_OFF);


extern SYSTEMTIME DS1302Buffer;
extern bool Flag_Time_Refresh;

#endif

三個文件放一起上傳就好了。至于都是些什么東西漂坏,你看看代碼就知道了景埃。
那么多媒至,實在懶得說。(又何況我也不太懂谷徙?)

All Done拒啰!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市完慧,隨后出現(xiàn)的幾起案子谋旦,更是在濱河造成了極大的恐慌,老刑警劉巖屈尼,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件册着,死亡現(xiàn)場離奇詭異,居然都是意外死亡脾歧,警方通過查閱死者的電腦和手機甲捏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鞭执,“玉大人司顿,你說我怎么就攤上這事⌒址模” “怎么了大溜?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長估脆。 經(jīng)常有香客問我猎提,道長,這世上最難降的妖魔是什么旁蔼? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任锨苏,我火速辦了婚禮,結(jié)果婚禮上棺聊,老公的妹妹穿的比我還像新娘伞租。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布旺芽。 她就那樣靜靜地躺著锻狗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪作喘。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天晕城,我揣著相機與錄音泞坦,去河邊找鬼。 笑死砖顷,一個胖子當(dāng)著我的面吹牛贰锁,可吹牛的內(nèi)容都是我干的赃梧。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼豌熄,長吁一口氣:“原來是場噩夢啊……” “哼授嘀!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起锣险,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蹄皱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后芯肤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體巷折,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年纷妆,在試婚紗的時候發(fā)現(xiàn)自己被綠了盔几。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡掩幢,死狀恐怖逊拍,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情际邻,我是刑警寧澤芯丧,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站世曾,受9級特大地震影響缨恒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜轮听,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一骗露、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧血巍,春花似錦萧锉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至鲫凶,卻和暖如春禀崖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背螟炫。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工波附, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓叶雹,卻偏偏與公主長得像财饥,于是被迫代替她去往敵國和親换吧。 傳聞我的和親對象是個殘疾皇子折晦,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容