本程序一共有2個文件,成功的用stc89c51單片機驅動,完整的代碼從 http://www.zg4o1577.cn/f/ds3231code.rar 處下載
下面是源碼預覽(第一個文件):
///////////////////////////////////////////////////////////////////////////////////
/*
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}; //秒分時日月周年 最低位讀寫位
//-------------------------------------------------------------------
void delay_IIC(void)
{//IIC總線限速延時函數。
//該函數是空函數,延時4個機器周期。
_nop_();_nop_();_nop_();_nop_();
}
//-------------------------------------------------------------------
void IIC_Init(void)
{//IIC總線初始化函數
IIC_RST=1;
IIC_SDA=1;//釋放IIC總線的數據線。
IIC_SCL=1;//釋放IIC總線的時鐘線。
}
//-------------------------------------------------------------------
void IIC_start(void)
{//IIC總線產生起始信號函數
IIC_SDA=1;//拉高數據線
IIC_SCL=1;//拉高時鐘線
delay_IIC();
IIC_SDA=0;//在時鐘線為高電平時,拉低數據線,產生起始信號。
delay_IIC();
IIC_SCL=0;//拉低時鐘線
}
//-------------------------------------------------------------------
void IIC_stop(void)
{//IIC總線產生停止信號函數
IIC_SDA=0;//拉低數據線
delay_IIC();
IIC_SCL=1;//拉高時鐘線。
delay_IIC();
IIC_SDA=1;//時鐘時線為高電平時,拉高數據線,產生停止信號。
delay_IIC();
}
//-------------------------------------------------------------------
bit IIC_Tack(void)
{//接收應答信號函數
bit ack;//定義一個位變量,來暫存應答狀態。
IIC_SDA=1;//釋放數據總線,準備接收應答信號。
delay_IIC();
IIC_SCL=1;//拉高時鐘線。
delay_IIC();
ack=IIC_SDA;//讀取應答信號的狀態。
delay_IIC();
IIC_SCL=0;//拉低時鐘線。
delay_IIC();
return ack;//返回應答信號的狀態,0表示應答,1表示非應答。
}
//-------------------------------------------------------------------
void IIC_write_byte(unsigned char Data)
{//向IIC總線寫入一個字節的數據函數
unsigned char i;
for(i=0;i<8;i++)//有8位數據
{
IIC_SDA=Data&0x80;//寫最高位的數據
delay_IIC();
IIC_SCL=1; //拉高時鐘線,將數寫入到設備中。
delay_IIC();
IIC_SCL=0;//拉低時鐘線,允許改變數據線的狀態
delay_IIC();
Data=Data<<1;//數據左移一位,把次高位放在最高位,為寫入次高位做準備
}
}
//-------------------------------------------------------------------
unsigned char IIC_read_byte()
{//從IIC總線讀取一個字節的數據函數
unsigned char i;
unsigned char Data; //定義一個緩沖寄存器。
for(i=0;i<8;i++)//有8位數據
{
IIC_SCL=1;//拉高時鐘線,為讀取下一位數據做準備。
delay_IIC();
Data=Data<<1;//將緩沖字節的數據左移一位,準備讀取數據。
delay_IIC();
if(IIC_SDA)//如果數據線為高平電平。
Data=Data|0x01;//則給緩沖字節的最低位寫1。
IIC_SCL=0;//拉低時鐘線,為讀取下一位數據做準備。
delay_IIC();
}
return Data;//返回讀取的一個字節數據。
}
//-------------------------------------------------------------------
void IIC_single_byte_write(unsigned char Waddr,unsigned char Data)
{//向任意地址寫入一個字節數據函數
IIC_start();//產生起始信號
IIC_write_byte(0xd0);//寫入設備地址(寫)
IIC_Tack();//等待設備的應答
IIC_write_byte(Waddr);//寫入要操作的單元地址。
IIC_Tack();//等待設備的應答。
IIC_write_byte(Data);//寫入數據。
IIC_Tack();//等待設備的應答。
IIC_stop();//產生停止符號。
}
//-------------------------------------------------------------------
unsigned char IIC_single_byte_read(unsigned char Waddr)
{//從任意地址讀取一個字節數據函數
unsigned char Data;//定義一個緩沖寄存器。
IIC_start();//產生起始信號
IIC_write_byte(0xd0);//寫入設備地址(寫)
IIC_Tack();//等待設備的應答
IIC_write_byte(Waddr);//寫入要操作的單元地址。
IIC_Tack();//等待設備的應答。
IIC_stop();//產生停止符號。
IIC_start();//產生起始信號
IIC_write_byte(0xd1);//寫入設備地址(寫)
IIC_Tack();//等待設備的應答
Data=IIC_read_byte();//寫入數據。
delay_IIC();
IIC_stop();//產生停止符號。
//-------------------返回讀取的數據--------------------
return Data;//返回讀取的一個字節數據。
}
void Read_RTC(void)
{
unsigned char i,*p;
p=rtc_address; //地址傳遞
for(i=0;i<7;i++) //分7次讀取 秒分時日月周年
{
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次寫入 秒分時日月周年
{
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總線的數據線。
IIC_SCL=1;
IIC_single_byte_write(0x0e,0x0c);
}