历史上的今天
返回首页

历史上的今天

今天是:2024年11月02日(星期六)

2021年11月02日 | DS1302时钟 ---- 自学笔记

2021-11-02 来源:eefocus

一、什么是DS1302时钟

具有实时时钟计算能力,能计算2100年之前的秒、分、时、日、日期、星期、月、年及闰年调整能力。

内部含有31个字节静态RAM,可提供用户访问。

采用串行数据传送方式,使得管脚数量最少,简单SPI3线接口。

工作电压范围宽:2.0~5.5V。

工作电流:2.0v时,小于300NA。

时钟或RAM数据的读/写有两种传送方式:单字节传送和多字节传送方式

采用8脚DIP封装或SOIC封装。

与TTL兼容,Vcc=5v

可选工业级温度范围:-40摄氏度~+85摄氏度

具有涓流充电能力

采用主电源和备份电源双电源供应

备份电源可由电池或大容量电容实现


二、SPI总线

2.1、概念

SPI接口(Serial Peripheral Interface):串行外围接口

SPI接口主要应用在EEPROM,FLASH,实时时钟,AD转换器,数字信号处理器和数字信号解码器之间

SPI接口是在CUP外围低速器件之间进行同步串行数据传输,在主器件的移位脉冲下,数据按位传输,高位在前,低位在后,全双工通信数据传输速度总体来说比IIC总线要快,速度可达到几Mbps.

SPI接口是以从方式工作的,这种模式通常有一个主器件和一个或多个从器件,器接口包括以下四种信号;

MOSI  ----  主器件数据输出,从器件数据输入。  (MO:主机输出  SI:从机输入)

MISO  ----  主器件数据输入,从器件数据输出。  (MI:主机输入  SO:从机输出)

SCLK  ----  时钟信号,由主器件产生。

/CS(CAN信号)       ----  从器件使能信号,主器件控制。  

2.2、SPI接口内部结构

缺点:没有指定的流控制,没有应答机制确认是否接收到数据


2.3、DS1302的引脚

三、DS1302的寄存器及片内RAM

DS1302有一个控制寄存器,12个日历,时钟寄存器和31个RAM。


3.1、控制寄存器

控制寄存器由于存放DS1302的控制命令字,DS1302的RST引脚回到高电平后写入的第一个字就为控制命令。


它用于对DS1302读写过程进行控制,它的格式如下

D7:固定位1

D6:RAM/CK位,=1片内RAM,=0日历、时钟寄存器选择位。

D5~D1:地址位,用于选择进行读写的日历时钟寄存器或片内RAM。

D0:读写选择,=0写,=1读

3.2、日历、时钟寄存器

DS1302共有12个寄存器,其中有7个与日历,时钟相关,存放的数据为BCD码形式。日历、时钟寄存见下表

数据都以BCD码形式表现

小时寄存器的D7位为12小时制/24小时制的选择位,当为1时选12小时制,当为0时选24小时制。当12小时制时,D5位为1时是上午,D5位位为0时是下午,D4为小时的十位。当24小时制时,D5,D4位为小时的十位。

秒寄存器中的CH位为时钟暂停位,当1为时钟暂停,为0时钟开启启动。

写保护寄存器:wp位写保护位,当wp=1,写保护,当wp=0未写保护、当对日历、时钟寄存器或片内RAM进行写时wp应当清零,当对日历,时钟寄存器或片内RAM进行读时WP一般置1。

慢充电寄存器的TCS位为控制慢充电的选择,当它为1010才能使慢充电工作。DS位二极管选择位。DS位01选择一个二极管,DS为10选择二个二级管。DS为11或00充电器被禁止,与TCS无关。RS用与选择连接在Vcc2与Vcc1之间的电阻,RS为00,充电器被禁止,与TCS无关,电阻选择情况见表

3.3、什么是BCD码

BCD码是通过4位二进制来表示1位十进制中的0~9这10个数码

二进制码转换位BCD码的方式为:4位二进制码大于1001(十进制:9)时,加6

如:BCD码0000 1100 的二进制为 0000 1100 +6 = 0001 0010

四、片内RAM

DS1302片内有31个RAM单元,对片内RAM的操作有两种方式:单字节方式和多字节方式当控制命令位COH~FDH时位单字节读写方式,命令字中的D5~D1用于选择对应的RAM单元,其中奇数为读操作,偶数为写操作。

当控制命令字节为FEH,FFH时为多字节操作(表中RAM突发模式),多字节操作可一次把所有的RAM单元内容进行读写。FEH为写操作,FFH为读操作。

4.1、数据输入输出(i/o)

在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。同样,在紧跟8位的控制指令字节的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7.


4.2、单字节的读写

DS1302是通过SPI串行总线跟单片机通信的,当进行一次读写操作时最少得读写两个字节,第一个字节是控制字节,就是一个命令,告诉DS1302是读还是写操作,是对RAM还是对CLOK寄存器操作,第二个自己就是要读或写的数据。


单字节读写:只有在SCLK位低电平时,才能将CE置为高电平,所以在进行操作之前先将SCLK置低电平,然后将CE置位高电平,接着开始在IO上面放入要传送的电平信号,然后跳变SCLK,数据在SCLK上升沿时,DS1302读写数据,在SCLK下降沿时,DS1302放置数据到IO上。

 

五、硬件设计

 

六、软件设计

6.1、ds1302.h

#ifndef __DS1302_H_

#define __DS1302_H_

 

//---包含头文件---//

#include

#include

 

//---重定义关键词---//

#ifndef uchar                 // 如果没有定义uchar

#define uchar unsigned char   // 那么就将uchar定义为无符号的字符形

#endif

 

#ifndef uint                  // 如果没有定义uint

#define uint unsigned int     // 那么就将uchar定义为无符号整型

#endif

 

//---定义ds1302使用的IO口---//

sbit DSIO=P3^4; // 输出/输入端口

sbit RST=P3^5;  //CE复位端口

sbit SCLK=P3^6; // 串行时钟

 

//---定义全局函数---//

void Ds1302Write(uchar addr, uchar dat);

uchar Ds1302Read(uchar addr);

void Ds1302Init();

void Ds1302ReadTime();

 

//---加入全局变量--//

extern uchar TIME[7]; //加入全局变量

 

#endif

6.2、ds1302.c

#include"ds1302.h"

 

//---DS1302写入和读取时分秒的地址命令---//

//---秒分时日月周年 最低位读写位;-------//

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

DS1302的寄存器及片内RAM

  D7     D6     D5     D4     D3     D2     D1     D0

   1    RAM/CK    D5~D1,地址位用与选择读写日历   RD/W 

  固定 1片内RAM   时钟寄存器或片内RAM    0写

        0日历,时钟寄存器选择位    1读

***********************************************************

寄存器名称 D7      D6      D5   D4   D3   D2   D1    D0        

             1 RAM/ck   A4   A3   A2   A1   A0    R/W     读十六进制       写十六进制 

秒寄存器      1       0       0    0    0    0    0     0 or 1        0x81 0x80

  

分寄存器     1 0 0   0    0    0    1    0 or 1        0x83 0x82

小时寄存器 1 0 0   0    0 1 0     0 or 1      0x85 0x84

日寄存器     1 0 0   0    0 1 1     0 or 1      0x87 0x86

月寄存器     1 0 0   0    1 0 0    0 or 1      0x89 0x88

  

星期寄存器 1 0 0   0    1 0 1    0 or 1      0x8b 0x8a

年寄存器     1 0 0   0    1 1 0    0 or 1      0x8d     0x8c

写保护寄存器 1      0 0   0    1 1 1     0 or 1      0x8f 0x8e

慢充电寄存器 1 0 0   1    0 0 0    0 or 1 0x91 0x90

时钟突发模式 1      0 1   1    1 1 1     0 or 1 0xbf 0xbe

RAM0         1 1 0   0    0    0 0    0 or 1      0xc1           0xc0

RAM30      1 1 1   1    1 1 0    0 or 1 0xfd     0xfc

RAM突发模式 1 1 1   1    1    1    1    0 or 1        0xff           0xfe

 */

uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; 

uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};

 

//---DS1302时钟初始化2016年5月7日星期六12点00分00秒。---//

/*uchar TIME[7] = {0, 0, 0x12, 0x07, 0x05, 0x06, 0x16};

                   秒,分,时,日,  月,   周,   年

*/

 

//---存储顺序是秒分时日月周年,存储格式是用BCD码---//

//2020年5月16日 星期六 10点30分

uchar TIME[7] = {0,0x30,0x10,0x16,0x05,0x06,0x20};

 

 

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

* 函 数 名         : Ds1302Write

* 函数功能    : 向DS1302命令(地址+数据)

* 输    入         : addr,dat

* 输    出         : 无

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

/*DS1302是通过SPI串行总线跟单片机通信的,

当进行一次读写操作时最少得读写两个字节,第一个字节是控制字节,

就是一个命令,告诉DS1302是读还是写操作,

是对RAM还是对CLOK寄存器操作。第二个字节就是要读或写的数据了。*/

void Ds1302Write(uchar addr, uchar dat)

{

uchar n;

RST = 0;    // 复位  RST=P3^5;

_nop_(); // 延时一个机器周期

 

SCLK = 0;   //先将SCLK置低电平。  SCLK=P3^6; 串行时钟输入引脚

_nop_();    // 延时一个机器周期

RST = 1;    //然后将RST(CE)置高电平。复位引脚,低电平有效,操作时高电平。

 

_nop_();

 

for (n=0; n<8; n++)//开始传送八位地址命令

{

/*写操作:赋值语句在移位操作的前面

  读操作:赋值语句在移位操作的后面*/

DSIO = addr & 0x01; //数据从低位开始传送

addr >>= 1;

SCLK = 1;//数据在上升沿时,DS1302读取数据

_nop_();

SCLK = 0;  //串行时钟 置低电平

_nop_();

}

 

for (n=0; n<8; n++)//写入8位数据

{

DSIO = dat & 0x01;

dat >>= 1;

SCLK = 1;//数据在上升沿时,DS1302读取数据

_nop_();

SCLK = 0;

_nop_();

}

 

RST = 0;//传送数据结束

_nop_();

}

 

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

* 函 数 名         : Ds1302Read

* 函数功能    : 读取一个地址的数据

* 输    入         : addr

* 输    出         : dat

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

   /*只有在SCLK位低电平时,才能将CE置为高电平,所以在进行操作之前先将SCLK置低电平,

   然后将CE置位高电平,接着开始在IO上面放入要传送的电平信号,然后跳变SCLK,

   数据在SCLK上升沿时,DS1302读写数据,在SCLK下降沿时,DS1302放置数据到IO上。*/

uchar Ds1302Read(uchar addr)

{

uchar n,dat,dat1;

RST = 0;

_nop_();

 

SCLK = 0;//先将SCLK置低电平。

_nop_();

RST = 1;//然后将RST(CE)置高电平。

_nop_();

 

for(n=0; n<8; n++)//开始传送八位地址命令

{

DSIO = addr & 0x01;//数据从低位开始传送

addr >>= 1;

SCLK = 1;//数据在上升沿时,DS1302读取数据

_nop_();

SCLK = 0;//DS1302下降沿时,放置数据

_nop_();

}

_nop_();

for(n=0; n<8; n++)//读取8位数据

{

dat1 = DSIO;//从最低位开始接收

dat = (dat>>1) | (dat1<<7);

SCLK = 1;

_nop_();

SCLK = 0;//DS1302下降沿时,放置数据

_nop_();

}

 

RST = 0;

_nop_(); //以下为DS1302复位的稳定时间,必须的。

SCLK = 1;

_nop_();

DSIO = 0;

_nop_();

DSIO = 1;

_nop_();

return dat;

}

 

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

* 函 数 名         : Ds1302Init

* 函数功能    : 初始化DS1302.

* 输    入         : 无

* 输    出         : 无

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

 

void Ds1302Init()

{

uchar n;

Ds1302Write(0x8E,0X00); //禁止写保护,就是关闭写保护功能

for (n=0; n<7; n++)//写入7个字节的时钟信号:分秒时日月周年

{

Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);

}

Ds1302Write(0x8E,0x80); //打开写保护功能

}

 

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

* 函 数 名         : Ds1302ReadTime

* 函数功能    : 读取时钟信息

* 输    入         : 无

* 输    出         : 无

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

 

void Ds1302ReadTime()

{

uchar n;

for (n=0; n<7; n++)//读取7个字节的时钟信号:分秒时日月周年

{

TIME[n] = Ds1302Read(READ_RTC_ADDR[n]);

}

}

6.3、main.c

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

*

实验现象:下载程序后,数码管显示时钟

  

接线说明: (具体接线图可见开发攻略对应实验的“实验现象”章节)

   1,单片机-->DS1302时钟模块

    P34-->DIO

P35-->CE

P36-->CLK

   2,单片机-->动态数码管模块

    J22-->J6

P22-->J9(A)

P23-->J9(B)

P24-->J9(C)

注意事项:

  

**************************************************************************************

推荐阅读

史海拾趣

General Transistor Corp公司的发展小趣事

为了进一步巩固市场地位和提升竞争力,GTC开始实施并购整合战略。公司通过收购具有技术优势和市场潜力的企业,实现了技术、产品和市场的快速扩张。同时,GTC还积极寻求战略转型,从单一的电子元器件分销商和生产商向综合性电子解决方案提供商转变。这一战略转型为公司带来了新的增长点和发展机遇。

Blaze Display Technology Co Ltd公司的发展小趣事

在国内市场取得一定成绩后,Blaze公司开始积极拓展国际市场。通过与全球知名企业的合作,公司成功将产品打入国际市场,并赢得了良好的口碑。此外,公司还积极参加国际电子展会和交流活动,与全球同行建立了广泛的合作关系,为公司的进一步发展奠定了坚实的基础。

AMICC [AMIC TECHNOLOGY]公司的发展小趣事

随着产品线的不断丰富和技术实力的不断提升,AMICC开始积极拓展国内外市场。公司通过与大型电子企业建立战略合作关系,成功打入国际市场。同时,AMICC还积极参加各类行业展会和交流活动,提升品牌知名度和影响力。在市场拓展的过程中,AMICC始终坚持客户至上的原则,为客户提供优质的产品和服务,赢得了客户的信任和好评。

Eagle-Picher公司的发展小趣事

1958年,Eagle-Picher公司的电池技术得到了重大的突破。在美国宇航局的探索者1号卫星上,Eagle-Picher的电池成功发射到太空,为卫星的运行提供了稳定的电源。这一里程碑式的事件标志着Eagle-Picher的电池技术在太空探索领域的应用达到了新的高度,也为公司赢得了更多的科研和商业机会。

EDAL公司的发展小趣事

为了进一步巩固市场地位和提升技术实力,EDAL公司开始通过收购和合作的方式拓展业务。公司成功收购了几家在EDA领域具有领先地位的公司,获得了更多的技术专利和市场份额。此外,EDAL公司还与其他科技公司建立了战略合作关系,共同研发新技术、新产品,推动整个EDA行业的发展。

Alpha (Taiwan)公司的发展小趣事

Alpha (Taiwan)公司自创立之初,便致力于电子技术的研发与创新。面对日益激烈的市场竞争,公司不断投入资金,引进先进设备,吸引了一批优秀的研发人才。这些人才凭借深厚的专业知识和敏锐的市场洞察力,成功开发出一系列具有竞争力的电子产品,如高性能的芯片、精密的传感器等。这些产品的推出,不仅提升了公司的市场地位,也为公司的快速发展奠定了坚实基础。

问答坊 | AI 解惑

LCD的一点资料

本帖最后由 paulhyde 于 2014-9-15 08:54 编辑 大家好 这是我收集到的一些LCD的资料 希望对大家有用!  …

查看全部问答>

linux下i2c控制radio的问题

目前用ut6410想实现 radio的功能使用si47xx的模块 ut6410本身有提供i2c的接口和驱动 kernel linux2.6.24 硬件部份問題排除 有用示波器 sda sck脚位有讯号出来. 现在遇到的状况是想从user space透过i2c对si47xx丢cmd 但是write read回传都是-1 部 ...…

查看全部问答>

wince5.0 2440背光问题

背光代码 volatile S3C2440A_IOPORT_REG * v_pIOPregs= NULL; BOOL BacklightInitialize() {     BOOL    bRet = TRUE;     BL_PowerOn(TRUE);               & ...…

查看全部问答>

第三方控件如何部署到wince中,在运行时提示无法找到第三方控件的dll

第三方控件如何部署到wince中 在运行时提示无法找到第三方控件的dll…

查看全部问答>

晶振运行正常吗?

我用示波器测量了一下F149的PIN9,X1OUT波形,有一个在2V范围,幅度在0。2V左右的锯齿波,频率有26US左右。而在PIN52,X2OUT上没有波形。我LXT1上接得是32678HZ的晶振,X2上接得是8M晶振。 请问这样状态正常吗?…

查看全部问答>

【求助】msp430芯片RAM居然不能外扩??

msp430芯片RAM居然不能外扩??很郁闷,最近程序大了,需要大于2K的RAM了,可是msp430芯片RAM不能外扩,这个怎么办呢?课题做到一半,555555555555 谢谢各位,请出出主意!…

查看全部问答>

TinyOS在MSP430F2618+CC2520平台上移植交流

目前TinyOS还仅支持MSP430低端的MCU比如f1611,以及CC2420等射频芯片。针对MSP430高端系列单片机,以及TI推出的第二代射频芯片CC2520还未能支持 前段时间把TinyOS移植到了上述平台上,基本功能都已经实现,针对无线协议栈还需要进一步优化!希望有 ...…

查看全部问答>

关于CC2530串口中断接收的问题

CC2530串口中断接收的自定义缓存BUF最大可以定义多大? 我现在需要一个最少160字节的BUF存接收到的数据进行解析;但是定义buf[160]后用IAR编译总是提示IDATA空间不够;后来通过调节IAR-option -stack/heap 中的设置;但是最大也是只能设置到buf[135 ...…

查看全部问答>

用七段数码管显示26个字母的方案

一般来说,七段数码管(也有称日字管)只能显示10个阿拉伯数字和部分英文字母,但是,按排列组合来算,七段数码管可以有128个组合,因此,就七段数码管可包含的信息量来说,显示26个字母加10个数字共36个字符是没问题的,只是人们没有建立一套显示 ...…

查看全部问答>

CC2500发射很正常,但是接收的数据异常

做了块CC2500模块,模块发射数据很正常,但是接收的数据全部异常,找了两天了还没找到原因,程序问题已经排除(用别人的模块发射和接受都正常),请懂的人帮下小弟,小弟搞开始搞RF…

查看全部问答>