專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計實(shí)例 >> 瀏覽文章

51單片機(jī)的ds1302驅(qū)動程序

作者:劉溫電   來源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時間:2013年11月26日   【字體:

 

////////////////////////////////////////////////////////////頭文件/////////////////////////////////////////////////
/*******************************************************************************
*  標(biāo)題:  ds1302時鐘芯片驅(qū)動程序                                                                                                  *
*  文件:  ds1302.h ds1302.c                                                                                                               *
*  日期:  2010-3-12                                                                                                                             *   
*  版本:  1.12(試驗(yàn)通過版)可用51hei單片機(jī)開發(fā)板                                                  *
*  郵箱:  acsdf139@163.com       qq:526083029                                                                              *
*  網(wǎng)站: 無                                                                                                                                       *
********************************************************************************
*  描述:                                                                                                                                                 *
*         用法:首先在主程序內(nèi)添加頭文件#include"ds1302.c"                                                         *
*      在程序中使用dsgettime(&currenttime)函數(shù)獲取時鐘芯片的時間數(shù)據(jù)                                     *
*      使用timetostr(&currenttime)函數(shù)將時間數(shù)據(jù)轉(zhuǎn)換液晶字符                                                      *
*      使用datetostr(&currenttime)函數(shù)將日期數(shù)據(jù)轉(zhuǎn)換液晶字符                                                      *           
*       存數(shù)據(jù)時,直接使用 wr1302(uchar add,uchar dat)即可                                                           *
********************************************************************************
*【版權(quán)】自己參照網(wǎng)上,朋友,以及書本資料上寫的,所以沒有版權(quán)                                    *
*【聲明】此程序,可用于學(xué)習(xí),參考及實(shí)際設(shè)計中,歡迎轉(zhuǎn)載復(fù)制以及建議批評                *
*【技術(shù)支持】qq:526083029  小張                                                                                                *
********************************************************************************/


#ifndef _DS1302_H_
#define _DS1302_H_
#include<AT89X52.H>
#include<intrins.h>
typedef struct __SYSTEMTIME__
{
     unsigned char Second;
     unsigned char Minute;
     unsigned char Hour;
     unsigned char Week;
     unsigned char Day;
     unsigned char Month;
     unsigned char Year;
     unsigned char datestr[11];
     unsigned char timestr[9];
}systime; //定義的時間類型

#define uchar unsigned char
#define uint unsigned int
#define am(x) x
#define pm(x) (x+12)               // 轉(zhuǎn)成24小時制
#define dssecond 0x80          //時鐘芯片的寄存器位置,存放時間
#define dsminute 0x82
#define dshour  0x84
#define dsweek  0x8A
#define dsday  0x86
#define dsmonth  0x88
#define dsyear  0x8C
#define dsbaohu     0x8E
#define on 0x80
#define off 0x00
 

extern uchar change(uchar x);
extern uchar bcdtohex(uchar val);
extern void wr1302b(uchar temp);
extern void wr1302(uchar add,uchar dat);
extern uchar re1302b();
extern uchar re1302(uchar address);
extern void dsinit(void);
extern void dsgettime(systime *ds1302);
extern void timetostr(systime *ds1302);
extern void datetostr(systime *ds1302);

 

#endif
 
 
 
 
////////////////////////////////////////////////////////////c程序////////////////////////////////////////////////////
 
#include <AT89X52.H>
#include "ds1302.h"
#include <intrins.h>
 
//管角定義
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
sbit dssck=P1^0; 
sbit dssda=P1^1; 
sbit dsrst=P1^2;// DS1302復(fù)位
 
 
systime currenttime;      //定義結(jié)構(gòu)體變量不可以在點(diǎn)h文件中定義
uchar flaghour,flagmin,flagsec,flagyear,flagmonth,flagday,flagweek,week_value[2];
/*************************************
函數(shù)名:change
函數(shù)功能:十進(jìn)制轉(zhuǎn)換成十六進(jìn)制
參數(shù):x(十六進(jìn)制數(shù))
返回:y(十進(jìn)制數(shù))
備注:無
*************************************/ 
uchar bcdtohex(uchar val)
{
       uchar i;
 
       i = val&0x0f; //按位與,i得到低四位數(shù)。
       val >>= 4;    //右移四位,將高四位移到低四位的位置,得到高四位碼值。
       val &= 0x0f; //防止移位時高位補(bǔ)進(jìn)1,只保留高四位碼值
       val *= 10;    //高位碼值乘以10
       i += val;     //然后與第四位碼值相加。
       return i;     //將得到的十進(jìn)制數(shù)返回
}
/*************************************
函數(shù)名:wr1302b
函數(shù)功能:實(shí)時時鐘寫入一個字節(jié)
參數(shù):d
返回:無
備注:配合wr1302使用
*************************************/
void wr1302b(uchar d)
{
    unsigned char i;
    ACC = d;
    for(i=8; i>0; i--)
    {
        dssda = ACC0;            //相當(dāng)于匯編中的 RRC
        dssck = 1;
        dssck = 0;
        ACC = ACC >> 1;
    }
}
/*************************************
函數(shù)名:wr1302
函數(shù)功能:向1302中寫數(shù)據(jù)
參數(shù):ucAddr(DS1302地址), ucData(要寫的數(shù)據(jù))
返回:無
備注:無
*************************************/
 
void wr1302(uchar ucAddr, uchar ucDa)     
{
    dsrst = 0;
    dssck = 0;
    dsrst = 1;
    wr1302b(ucAddr);          // 地址,命令
    wr1302b(ucDa);              // 寫1Byte數(shù)據(jù)
    dssck = 1;
    dsrst = 0;
}
 
/*************************************
函數(shù)名:re1302b
函數(shù)功能:實(shí)時時鐘讀取一字節(jié)
參數(shù):無
返回:ACC
備注:配合re1302使用
*************************************/
 
uchar re1302b(void)    
{
    unsigned char i;
    for(i=8; i>0; i--)
    {
        ACC = ACC >>1;                        //相當(dāng)于匯編中的 RRC
        ACC7 = dssda;
        dssck = 1;
        dssck = 0;
    }
    return(ACC);
}
 
/*************************************
函數(shù)名:re1302
函數(shù)功能:讀數(shù)據(jù)
參數(shù):ucAddr(地址)
返回:ucData(數(shù)據(jù))
備注:無
*************************************/
uchar re1302(uchar ucAddr) //讀取DS1302某地址的數(shù)據(jù)
{
    unsigned char ucData;
    dsrst = 0;
    dssck = 0;
    dsrst = 1;
    wr1302b(ucAddr|0x01);        // 地址,命令
    ucData = re1302b();         // 讀1Byte數(shù)據(jù)
    dssck = 1;
    dsrst = 0;
    return(ucData);
}
/*************************************
函數(shù)名:dsinit
函數(shù)功能:時鐘初始化
參數(shù):無
返回:無
備注:無
*************************************/
void dsinit(void) //時鐘初始化可以不填
{
 
              wr1302(dsbaohu,off);
              wr1302(dsyear,0x09);
              wr1302(dsmonth,0x11);
              wr1302(dsday,0x02);
              wr1302(dsweek,0x01);
              wr1302(dshour,0x23);
              wr1302(dsminute,0x57);
              wr1302(dssecond,0x55);
              wr1302(dsbaohu,on);
 
}
/*************************************
函數(shù)名:dsgettime
函數(shù)功能:獲取時間到時間型指針
參數(shù):systime *ds1302(時間型數(shù)據(jù)指針)
返回:無
備注:無
*************************************/
 
void dsgettime(systime *ds1302) //獲取時鐘芯片的時鐘數(shù)據(jù)到自定義的結(jié)構(gòu)型數(shù)組
{
       unsigned char ReadValue;
       ReadValue = re1302(dssecond);
       ds1302->Second = bcdtohex(ReadValue);
       ReadValue = re1302(dsminute);
       ds1302->Minute = bcdtohex(ReadValue);
       ReadValue = re1302(dshour);
       ds1302->Hour = bcdtohex(ReadValue);
       ReadValue = re1302(dsday);
       ds1302->Day = bcdtohex(ReadValue); 
       ReadValue = re1302(dsweek);
       ds1302->Week = bcdtohex(ReadValue);
       ReadValue = re1302(dsmonth);
       ds1302->Month =bcdtohex(ReadValue);
       ReadValue = re1302(dsyear);
       ds1302->Year = bcdtohex(ReadValue);
}
 
/*************************************
函數(shù)名:timetostr
函數(shù)功能:將時間轉(zhuǎn)換液晶顯示字符放入數(shù)組timestr[]
參數(shù):systime *ds1302(時間型數(shù)據(jù)指針)
返回:無
備注:無
*************************************/
void timetostr(systime *ds1302) 
{ if(flaghour<2)
   {
        ds1302->timestr[0] = ds1302->Hour/10 + '0';
        ds1302->timestr[1] = ds1302->Hour%10 + '0';
       }
        else
          {
             ds1302->timestr[0] = ' ';
             ds1302->timestr[1] = ' ';
              }
       ds1302->timestr[2] = ':';
    if(flagmin<2)
       {
        ds1302->timestr[3] = ds1302->Minute/10 + '0';
        ds1302->timestr[4] = ds1302->Minute%10 + '0';
       }
        else
           {
             ds1302->timestr[3] = ' ';
             ds1302->timestr[4] = ' ';
        }
       ds1302->timestr[5] = ':';
    if(flagsec<2)
    {
        ds1302->timestr[6] = ds1302->Second/10 + '0';
        ds1302->timestr[7] = ds1302->Second%10 + '0';
    }
      else
      {
        ds1302->timestr[6] = ' ';
            ds1302->timestr[7] = ' ';
      }
       ds1302->timestr[8] = '\0';
}
 
/*************************************
函數(shù)名:datetostr
函數(shù)功能:將日期轉(zhuǎn)換液晶顯示字符放入數(shù)組datestr[]
參數(shù):systime *ds1302(時間型數(shù)據(jù)指針)
返回:無
備注:無
*************************************/
 
void datetostr(systime *ds1302)    //將時間年,月,日,星期數(shù)據(jù)轉(zhuǎn)換成液晶顯示字符串,放到數(shù)組里DateString[]
{   if(flagyear<2)                 //這里的if,else語句都是判斷位閃爍,<2顯示數(shù)據(jù),>2就不顯示,輸出字符串為 2007/07/22
    {                              
        ds1302->datestr[0] = '2';
        ds1302->datestr[1] = '0';   
        ds1302->datestr[2] = ds1302->Year/10 + '0';
        ds1302->datestr[3] = ds1302->Year%10 + '0';
       }
        else
           {
             ds1302->datestr[0] = ' ';
             ds1302->datestr[1] = ' ';           
             ds1302->datestr[2] = ' ';
             ds1302->datestr[3] = ' ';
              }
       ds1302->datestr[4] = '/';
       if(flagmonth<2)
       {
        ds1302->datestr[5] = ds1302->Month/10 + '0';
        ds1302->datestr[6] = ds1302->Month%10 + '0';
       }
        else
        {
           ds1302->datestr[5] = ' ';
           ds1302->datestr[6] = ' ';
        }
       ds1302->datestr[7] = '/';
       if(flagday<2)
       {
        ds1302->datestr[8] = ds1302->Day/10 + '0';
        ds1302->datestr[9] = ds1302->Day%10 + '0';
       }
        else
        {
           ds1302->datestr[8] = ' ';
           ds1302->datestr[9] = ' ';    
        }
       if(flagweek<2)
       {
        week_value[0] = ds1302->Week%10 + '0'; 
     //星期的數(shù)據(jù)另外放到 week_value[]數(shù)組里,跟年,月,日的分開存放,因?yàn)榈纫幌乱谧詈箫@示
       }
        else
        {
           week_value[0] = ' ';
        }
        week_value[1] = '\0';
 
       ds1302->datestr[10] = '\0'; //字符串末尾加 '\0' ,判斷結(jié)束字符
}

關(guān)閉窗口

相關(guān)文章