本程序一共有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);
}