其中wp为1时禁止更改寄存器数据,为0时可以
CH为1时时钟震荡器停止,为0时开始运行,
85h/84h第7位为模式选择位,为1时为12时模式,为0时为24时模式
驱动方式为spi模式
不管读写,输出格式都是,控制字+数据,也就是说第一步都是先写后读。
数据发送和接收都是从低位开始
上升沿发送数据,产生下降沿时DS1302才会产生数据。
注意:1,sclk为低电平期间,CE才可以变高
2.读秒时只有前7位有效,第8位为无效位,但为0所以可以直接读取,并不影响。
3.数据以BCD码进行存储,所以读取时要对数据要进行转换,除16得十位,%16得个位。
读取数据时可以移位在赋值后,这样第1个数据会移动8为导致溢出,而第一个数据正好为无效数据,而第2为数据移动7位,正好为有效第一位数据,然后依次,最终得到7位有效数据。
#ifndef _DS1302_
#define _DS1302_
#include "reg52.h"
sbit RST= P0^2;
sbit IO =P3^3;
sbit SCLK=P0^3;
unsigned int read_DS1302(unsigned int add);
void DS1302_Write(unsigned char add ,unsigned char date);
void DS1302_init();
#endif
#include "DS1302.H"
#include "intrins.h"
//---DS1302写入和读取时分秒的地址命令---//
//---秒分时日月周年 最低位读写位;-------//
unsigned char code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
unsigned char code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
//---DS1302时钟初始化2016年5月7日星期六12点00分00秒。---//
//---存储顺序是秒分时日月周年,存储格式是用BCD码---//
unsigned char code TIME1[7] = {0x00, 0x20, 0x13, 0x21, 0x03, 0x02, 0x23};
/*
读取函数
控制字读格式:10+读取地址(4位)+1
add:读取地址, 81h秒,83h分,85h时,87h日,89h月,8Bh周几,8Dh年,
return :返回数据
控制字从低位开始输出,返回数据从低位开始返回
*/
unsigned int read_DS1302(unsigned int add)
{
static unsigned char i,b;
static unsigned int date=0,date1=0;
RST=0;
_nop_();
SCLK=0;
_nop_();
RST=1;//DS1302片选信号高电平有效
_nop_();
for(i=0;i<8;i++) //上升沿发送数据,数据在低电平准备,上升沿发送
{
SCLK = 0;
IO=add&0x01;
add>>=1;
SCLK = 1;
}
//发送第8个脉冲和第9个脉冲合二为1,上升沿为第八个脉冲,下降沿为第9个脉冲,
for(b=0;b<8;b++)//下降沿产生数据,第一个数据右移8次溢出,从第2个数据开始产生一个下降沿读取1次右移一次一共7位,以此减少。
{ //最高位无效位,最多7位有效数。
if(IO==1) date=date|0X80;
date>>=1;
SCLK = 1;
_nop_();
SCLK = 0;
}
RST=0;_nop_();
date1=date%16;
date=date/16;
date=date*10+date1;
return date;
}
void DS1302_Write(unsigned char add ,unsigned char date)
{
static unsigned char i;
RST=0;
_nop_();
SCLK=0;
_nop_();
RST=1;//DS1302片选信号高电平有效
_nop_();
for(i=0;i<8;i++) //上升沿发送数据
{
SCLK = 0;
IO=add&0x01;
add>>=1;
SCLK = 1;
}
for(i=0;i<8;i++) //上升沿发送数据
{
SCLK = 0;
IO=date&0x01;
date>>=1;
SCLK = 1;
}
RST=0;
_nop_();
}
void DS1302_init()
{
unsigned char n;
DS1302_Write(0X8E,0);//取消写保护
for(n=0;n<7;n++)
{
DS1302_Write( WRITE_RTC_ADDR[n] ,TIME1[n]);
}
DS1302_Write(0X8E,1);//打开写保护
}