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

51單片機(jī)驅(qū)動(dòng)高精度時(shí)鐘DS3231源代碼

作者:huqin   來源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2014年04月08日   【字體:

本程序一共有2個(gè)文件,成功的用stc89c51單片機(jī)驅(qū)動(dòng),完整的代碼從 http://www.torrancerestoration.com/f/ds3231code.rar 處下載
下面是源碼預(yù)覽(第一個(gè)文件):
 ///////////////////////////////////////////////////////////////////////////////////
/*
DS3231.h文件

*/
////////////////////////////////////////////////////////////////////////////////////

#ifndef _ds3231_h_
#define _ds3231_h_
#define uint unsigned int
#define uchar unsigned char
/**************************************/
extern void IIC_Init(void);
extern uchar l_tmpdate[];
extern uchar l_tmpdisplay[];
extern void delay_IIC(void);
extern void IIC_start(void);
extern void IIC_stop(void);
extern bit IIC_Tack(void);
extern void Read_RTC(void);
extern void Set_RTC(void);
extern void DS1302_Initial();
#endif
///////////////////////////////////////////////////////////////////////////////////
/*
DS3231.C文件

*/
////////////////////////////////////////////////////////////////////////////////////
#include<reg52.h>
#include<intrins.h>
#include"ds3231.h"
sbit IIC_SDA=P0^3;
sbit IIC_RST=P0^2;
sbit IIC_SCL=P0^1;
code unsigned char rtc_address[7]={0x00,0x01,0x02,0x04,0x05,0x03,0x06}; //秒分時(shí)日月周年 最低位讀寫位


//-------------------------------------------------------------------
void delay_IIC(void)  
{//IIC總線限速延時(shí)函數(shù)。
//該函數(shù)是空函數(shù),延時(shí)4個(gè)機(jī)器周期。
_nop_();_nop_();_nop_();_nop_();
}
//-------------------------------------------------------------------
void IIC_Init(void)
{//IIC總線初始化函數(shù)
    IIC_RST=1;
    IIC_SDA=1;//釋放IIC總線的數(shù)據(jù)線。
    IIC_SCL=1;//釋放IIC總線的時(shí)鐘線。
}
//-------------------------------------------------------------------
void IIC_start(void)
{//IIC總線產(chǎn)生起始信號函數(shù)
    
     IIC_SDA=1;//拉高數(shù)據(jù)線
     IIC_SCL=1;//拉高時(shí)鐘線
     delay_IIC();
     IIC_SDA=0;//在時(shí)鐘線為高電平時(shí),拉低數(shù)據(jù)線,產(chǎn)生起始信號。
     delay_IIC();
     IIC_SCL=0;//拉低時(shí)鐘線
}
//-------------------------------------------------------------------
void IIC_stop(void)
{//IIC總線產(chǎn)生停止信號函數(shù)
    IIC_SDA=0;//拉低數(shù)據(jù)線
    delay_IIC();
    IIC_SCL=1;//拉高時(shí)鐘線。
    delay_IIC();
    IIC_SDA=1;//時(shí)鐘時(shí)線為高電平時(shí),拉高數(shù)據(jù)線,產(chǎn)生停止信號。
    delay_IIC();
}
//-------------------------------------------------------------------
bit IIC_Tack(void)
{//接收應(yīng)答信號函數(shù)
    bit ack;//定義一個(gè)位變量,來暫存應(yīng)答狀態(tài)。
    IIC_SDA=1;//釋放數(shù)據(jù)總線,準(zhǔn)備接收應(yīng)答信號。
    delay_IIC();
    IIC_SCL=1;//拉高時(shí)鐘線。
    delay_IIC();
    ack=IIC_SDA;//讀取應(yīng)答信號的狀態(tài)。
    delay_IIC();
    IIC_SCL=0;//拉低時(shí)鐘線。
    delay_IIC();
    return ack;//返回應(yīng)答信號的狀態(tài),0表示應(yīng)答,1表示非應(yīng)答。
}
//-------------------------------------------------------------------
void IIC_write_byte(unsigned char Data)
{//向IIC總線寫入一個(gè)字節(jié)的數(shù)據(jù)函數(shù)
    unsigned char i;
     for(i=0;i<8;i++)//有8位數(shù)據(jù)
    {
        IIC_SDA=Data&0x80;//寫最高位的數(shù)據(jù)
          delay_IIC();
          IIC_SCL=1; //拉高時(shí)鐘線,將數(shù)寫入到設(shè)備中。
        delay_IIC();
        IIC_SCL=0;//拉低時(shí)鐘線,允許改變數(shù)據(jù)線的狀態(tài)
        delay_IIC();
        Data=Data<<1;//數(shù)據(jù)左移一位,把次高位放在最高位,為寫入次高位做準(zhǔn)備
    }
}
//-------------------------------------------------------------------
unsigned char IIC_read_byte()
{//從IIC總線讀取一個(gè)字節(jié)的數(shù)據(jù)函數(shù)
    unsigned char i;
    unsigned char Data;       //定義一個(gè)緩沖寄存器。
    for(i=0;i<8;i++)//有8位數(shù)據(jù)
    {
        IIC_SCL=1;//拉高時(shí)鐘線,為讀取下一位數(shù)據(jù)做準(zhǔn)備。
        delay_IIC();
        Data=Data<<1;//將緩沖字節(jié)的數(shù)據(jù)左移一位,準(zhǔn)備讀取數(shù)據(jù)。
        delay_IIC();
      
        if(IIC_SDA)//如果數(shù)據(jù)線為高平電平。
            Data=Data|0x01;//則給緩沖字節(jié)的最低位寫1。
        IIC_SCL=0;//拉低時(shí)鐘線,為讀取下一位數(shù)據(jù)做準(zhǔn)備。
        delay_IIC();
    }
    return Data;//返回讀取的一個(gè)字節(jié)數(shù)據(jù)。
}
//-------------------------------------------------------------------
void IIC_single_byte_write(unsigned char Waddr,unsigned char Data)
{//向任意地址寫入一個(gè)字節(jié)數(shù)據(jù)函數(shù)
    IIC_start();//產(chǎn)生起始信號
    IIC_write_byte(0xd0);//寫入設(shè)備地址(寫)
    IIC_Tack();//等待設(shè)備的應(yīng)答
    IIC_write_byte(Waddr);//寫入要操作的單元地址。
    IIC_Tack();//等待設(shè)備的應(yīng)答。
    IIC_write_byte(Data);//寫入數(shù)據(jù)。
    IIC_Tack();//等待設(shè)備的應(yīng)答。
    IIC_stop();//產(chǎn)生停止符號。
}
//-------------------------------------------------------------------
unsigned char IIC_single_byte_read(unsigned char Waddr)
{//從任意地址讀取一個(gè)字節(jié)數(shù)據(jù)函數(shù)
    unsigned char Data;//定義一個(gè)緩沖寄存器。
    IIC_start();//產(chǎn)生起始信號
    IIC_write_byte(0xd0);//寫入設(shè)備地址(寫)
    IIC_Tack();//等待設(shè)備的應(yīng)答
    IIC_write_byte(Waddr);//寫入要操作的單元地址。
    IIC_Tack();//等待設(shè)備的應(yīng)答。
    IIC_stop();//產(chǎn)生停止符號。

    IIC_start();//產(chǎn)生起始信號
    IIC_write_byte(0xd1);//寫入設(shè)備地址(寫)
    IIC_Tack();//等待設(shè)備的應(yīng)答
    Data=IIC_read_byte();//寫入數(shù)據(jù)。
    delay_IIC();
    IIC_stop();//產(chǎn)生停止符號。
    //-------------------返回讀取的數(shù)據(jù)--------------------
    return Data;//返回讀取的一個(gè)字節(jié)數(shù)據(jù)。
}

void Read_RTC(void)
{
    unsigned char i,*p;
     p=rtc_address;         //地址傳遞
    for(i=0;i<7;i++)            //分7次讀取 秒分時(shí)日月周年
    {
      l_tmpdate[i]=IIC_single_byte_read(*p);
      p++;
    }  
}
void Set_RTC(void)
{
    unsigned char i,tmp;
    for(i=0;i<7;i++)
    {       //BCD處理
        tmp=l_tmpdate[i]/10;
        l_tmpdate[i]=l_tmpdate[i]%10;
        l_tmpdate[i]=l_tmpdate[i]+tmp*16;
    }
//    IIC_single_byte_write(0x0e,0X8c);
     for(i=0;i<7;i++)        //7次寫入 秒分時(shí)日月周年
     {
        IIC_single_byte_write(rtc_address[i],l_tmpdate[i]);
    }
    IIC_single_byte_write(0x0e,0x0c);
}

void DS1302_Initial()
{
    IIC_RST=1;
    IIC_SDA=1;//釋放IIC總線的數(shù)據(jù)線。
    IIC_SCL=1;
    IIC_single_byte_write(0x0e,0x0c);
}

關(guān)閉窗口

相關(guān)文章