ds1307怎么使用(ds1307引脚图及功能_c语言程序及典型应用威廉希尔官方网站 )

芯片引脚图

713人已加入

描述

实时时钟DS1307 介绍:

DS1307是低功耗、两线制串行读写接口、日历和时钟数据按BCD码存取的时钟/日历芯片。它提供秒、分、小时、星期、日期、月和年等时钟日历数据。另外它还集成了如下几点功能:

(1)56 字节掉电时电池保持的NV SRAM 数据存储器

(2)可编程的方波信号输出

(3)掉电检测和自动切换电池供电模式

DS1307 把8 个寄存器和56 字节的RAM 进行了统一编址,具体地址和寄器数据组织格式如下表:

C语言

(日期为BCD码)

C语言

在读写过程中DS1307 内部维护一个地址指针,通过写操作可对它 值,读和写每一字节时自动加一,当指针越过DS1307 内部RAM 尾 时指针将返回到0 地址处。

DS1307 的时钟和日历数据按BCD 码存储。

ds1307引脚图及功能

DS1307

串行实时时钟记录年、月、日、时、分、秒、星期及日期; AM、PM 分别表示上午和下午; 56 个字节的NVRAM存放数据; 2线串口; 可编程的方波输出;电源故障检测及自动切换威廉希尔官方网站 ;电池电流小于500nA。

主要引脚定义如下: X1、32.768kHz 晶振接入端;

VBAT:X2:+3V 电池电压输入;

SDA: 串行数据;

SCL:串行时钟;

SQW/OUT:方波/输出驱动器。

C语言

方波信号输出功能

方波信号输出功能从SQW/OUT 引脚输出设置频率的方波,CONTROL 寄存器用于控制SQW/OUT 脚的输出。

BIT7(OUT):此位表示在方波输出被禁止时(BIT4=0),SQW/OUT 引脚的逻辑电平,在BIT4=0(SQWE=0方波输出禁止)时,若BIT7(OUT) 为1 则SQL/OUT 引脚为高电平, 反之亦然。

BIT4(SQWE)方波输出允许/禁止控制位,SQWE =1 允许方波输出(有效);BIT4=0 禁止方波输出。

BIT0(RS0)、BIT1(RS1)于设定输出波形的频率,如下表:

C语言

要注意的是,00h 地址的第7 位为器件时钟允许位(CH),由于在在开始上电时内部RAM内容随机,所以在初始化时将CH 位设零(时钟允许)是非常重要的。

DS1307 在TWI 总线上是从器件,地址(SLA)固定为”11010000”

DS1307 写操作 TWI 被控接收模式

主控器件按如下顺序将数据写入到DS1307 寄存器或内部RAM 中:

第一步.START 信号

第二步。写SLA+W(0xd0)字节,DS1307 应答(ACK)

第三步。写1 字节内存地址(在以下第四步写入的第一字节将存入到DS1307 内该地址处),DS1307应答。

第四步。写数据(可写多个字节,每一字节写入后DS1307 内部地址计数器加一,DS1307 应答)

第五步.STOP 信号

DS1307 读操作TWI 被控发送模式

主控器件按如下顺序将DS1307 寄存器或内部RAM 数据读取:

第一步.START 信号

第二步。写SLA+R(0xd1)字节,DS1307 应答(ACK)

第三步。读数据(可读多个字节,读取数据的DS1307 内部地址由上次写操作或读操作决定,读取每一字节DS1307 内部地址计数器加一,主器件应答,读取最后一字节时主器件回应一NACK信号)

第四步.STOP 信号

典型应用威廉希尔官方网站 图

C语言

特征

实时时钟(RTC)计算秒,分钟,小时,月,月,日的日期周和年份,闰年补偿,有效期至2100年

56字节,由电池供电,通用RAM与无限写操作I2C串行接口可编程方波输出信号

自动电源失效检测和切换威廉希尔官方网站 消耗的电池备份超过500nA的少与振荡器运行模式

可选的工业温度范围:-40°C至+ 85°C提供8引脚塑料DIP或SO

美国保险商实验室(UL)认证

DS1307 C语言程序

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

//***************************DS1307调试 *****************************

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

//**DS1307实时时钟芯片地址0xD0 读0xD1 写0xD0 *********************

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

#include《reg51.h》 //单片机80C51

sbit SCL=P1^1; //串口时钟信号

sbit SDA=P1^0; //串口数据信号

sbit clock=P1^2; //调试用脉冲输出信号**************

unsigned char error; //通讯正常error=0x10;超时error=0x11

void delay(int i); //延时子函数

void TimeInitial(); //时钟初始化子函数

void Start_I2C(); //打开串口子函数

void Stop_I2C (); //关闭串口子函数

void Ack_I2C(); //接受应答信号并判断是否正常子函数

void SendAck(); //发送应答信号子函数

void SendNotAck(); //发送非应答信号子函数

void Send_I2C (int ch); //向总线上发送一个字节

unsigned int Receive_I2C(); //在总线上接受一个字节

int read_time(int address); //从芯片D1307读出10为字节 地址1:秒 2:分 3:时 4:星期 5:号 6:月7:年 8 控制字

void write_time(int address,int date); //向芯片D1307 之中地址为address的寄存器写入数据date 仅为八位字节

void main() //主程序************************************************************

{

TimeInitial(); //时钟初始化

write_time(0x07,0x10); //向芯片D1307写入控制字(芯片地址0X07)0x10 控制字:1晶振使能(0有效)4:SOUT方波输出 7、8:方波频率编码

while(1)

{

}

}

void TimeInitial() //时钟初始化

{

TMOD=0x10; //时钟选择方式2 T1时钟

TH1=0x15;

TL1=0xA0; //定时60ms

EA=1; //中断准许

ET1=1; //时钟T1 溢出中断准许

TR1=1; //启动时钟T1

}

//**********************************延时

void delay(int i)

{

int j,h;

for(j=1;j《99;j++)

{

for(h=0;h《i;h++)

;

}

}

//**********************************传送启动

void Start_I2C()

{

EA=0; //关闭中断

SCL=0; //总线放空,以便更改总线数据

delay(1); //延时

SDA=1; //发送I2C总线起始条件的数据信号1以便总线使能时产生下降沿

delay(1); //延时

SCL=1; //发送I2C总线起始条件的时钟信号

delay(1); //延时

SDA=0; //产生下降沿 总线传输开始

delay(1); //延时

SCL=0; //时钟线从高到低一次跳变,总线放空 准备传输数据

}

//**********************************传送关闭

void Stop_I2C ()

{

SCL=0; //发送I2C总线时钟信号放空

SDA=0; //发送I2C总线停止条件的数据信号0以便产生上升沿

delay(1); //延时

SCL=1; //时钟线从低到高一次跳变 总线 使能

delay(1); //延时

SDA=1; //发送I2C总线数据信号产生上升沿 终止传送

delay(1); //延时

SCL=0; //发送I2C总线时钟信号放空

delay(1);

SDA=0; //发送I2C总线放空 准备下次动作

EA=1; //传输结束开启中断

}

//**********************************传送响应

void Ack_I2C()

{

unsigned char errtime=255; //因故障接收方无ACK,超时值为255。

SDA=1; //数据线升高,以便捕捉相应信号,(相应信号:拉低数据线)

SCL=1; // 主机放出一脉冲,等待捕捉相应信号

error=0x10; //通讯正常(即:接受到了相应信号)为0X10;

while(SDA) //等待捕捉相应信号,信号没有到来前一直保持循环,信号到来后迅速跳出循环

{

errtime--; //每循环一次,倒计时减一

if(!errtime) //判断倒计时是否减到了0,即循环了255次,如果减到了0,判定此次通讯未接受到响应信号,传送失败

{

Stop_I2C (); //传送失败,停止传送

error=0x11; //传送结果未传送失败0x11

return; //跳出循环

}

}

SCL=0; //无论传送是否正确,都需放空总线,以备后用

}

//**********************************向总线传送响应

void SendAck()

{

SDA=0; //数据线保持拉低,时钟线发生一次从高低的跳变 发送一个应答信号

delay(1);

SCL=1;

delay(1);

SCL=0;

}

//**********************************向总线传送非响应

void SendNotAck()

{

SDA=1; //数据线保持高,时钟线发生一次从高低的跳变 没有应答

delay(1);

SCL=1;

delay(1);

SCL=0;

}

//**********************************向总线传送字节

void Send_I2C (int ch)

{

int i;

for (i=1;i《=8;i++) //发送八位

{

SCL=0; //总线放空

delay(1); //延时

SDA=(ch&0x80); //根据给定数据,又高位到低位逐步提出字节位,发送到总线上

ch《《=1; //左循环以便输出下一位

delay(1); //延时

SCL=1; //总线使能,发送总线数据

delay(1); //延时

}

SCL=0; //总线8位传送完成,总线放空

}

//**********************************向总线读入字节

unsigned int Receive_I2C()

{

unsigned char i,a;

SDA=1; //不知道为啥,1的时候读入正确 0的时候读入全部为0;

for (i=1;i《=8;i++) //读入八个位

{

a《《=1; // 读入数据左循环

SCL=0; //总线放空

delay(1);

SCL=1; //时钟做一次从低到高的跳变 可以接收一位数据

delay(1);

a|=SDA; // 将数据编入变量a

}

SCL=0; //总线放空

return a; //反馈接收到的信息

}

//**********************************向芯片D1307 之中地址为address的寄存器写入数据date 仅为八位字节

void write_time(int address,int date)

{

Start_I2C(); //启动总线

Send_I2C (0xD0); //呼叫芯片D1307,并定义为 写 动作

Ack_I2C(); //等待响应信号

Send_I2C (address); //发送地址

Ack_I2C(); //等待响应信号

Send_I2C (date); //发送数据

Ack_I2C(); //等待响应信号

Stop_I2C (); //停止总线

}

//****************从芯片D1307读出10为字节 地址1:秒 2:分 3:时 4:星期 5:号 6:月7:年 8 控制字

int read_time(int address)

{

int a[10]; //定义一个数组以便接受数据

int i=1;

Start_I2C(); //启动传送

Send_I2C (0xD0); //呼叫芯片D1307,并定义为 写 动作

Ack_I2C(); //等待响应信号

Send_I2C (0x00); //发送起始地址

Ack_I2C(); //等待响应信号

Stop_I2C (); //关闭总线

Start_I2C(); //启动总线

Send_I2C (0xD1); //呼叫芯片D1307,并定义为 读 动作

SendAck(); //发送应答就位,准备接受数据

for(i;i《10;i++)

{

a[i]=Receive_I2C(); //接受自初始地址开始的10个字节 地址1:秒 2:分 3:时 4:星期 5:号 6:月7:年 8 控制字

SendAck(); //每成功接受一位发送一个响应信号 以便接受下一位

}

Stop_I2C (); //接受完成停止

return a[address]; //反馈所需数据

}

void t1(void) interrupt 3 using 0 //T1溢出中断

{

TH1=0x15;

TL1=0xa0; //重新载入60ms

clock=~clock; //调试用脉冲

P0=read_time(1); //将实时时钟 秒 送入P0口

}

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分