DS1302驱动详解
DS1302驱动程序
}
SDA = 0;
RST = 0; //复位置0,结束突发连写连读
set_ds1302_WP(); //写保护
for (i=0; i<7; i++) // 转化为正常格式
{
tmp = timedata[i] / 16;
timedata[i] = timedata[i] % 16;
}
/**
* 设置写保护
*/
void set_ds1302_WP(void)
{
reset_ds1302();
RST = 1;
write_ds1302_byte(0x8E);
write_ds1302_byte(0x80);
SDA = 0;
RST = 0;
}
for (i=0; i<7; i++) //7组数据秒分时日月周年分别写入寄 //存器中
{
write_ds1302_byte(timedata[i]);
delay1(10);
}
write_ds1302_byte(0); //写入0,
SDA = 0;
RST = 1;
}
/**
* 清除写保护
*/
void clear_ds1302_WP(void)
{
reset_ds1302();
RST = 1;
write_ds1302_byte(0x8E);
write_ds1302_byte(0);
SDA = 0;
RST = 0;
Timer_display(time[2],time[1],time[0]);
时钟芯片DS1302驱动程序
return date; } uchar RE1302( uchar addr ) { uchar Date; RST=0; CK=0; RST=1; //CK 为 0 时,RST 才能为 1,然后才能读写 WRdate(addr); //写地址 Date=REdate(); //读数据 CK=1; RST=0; re02(0x8E,0X00); // 0X8E 是 WP 写保护地址,最高位赋 0 表示可以写 WR1302( 0x80, Z10BCD( sec ) ); //向秒单元赋初值 WR1302( 0x82, Z10BCD( min ) ); //向分单元赋初值 WR1302( 0x84, Z10BCD( hor ) ); //向时单元赋初值 WR1302( 0x86, Z10BCD( day ) ); //向日单元赋初值 WR1302( 0x88, Z10BCD( yue ) ); //向月单元赋初值 WR1302( 0x8a, Z10BCD( week) ); //向周单元赋初值 WR1302( 0x8c, Z10BCD( year) ); //向年单元赋初值 } main()
时钟芯片 DS1302 驱动程序
芯片介绍 DS1302 是 DALLAS 公司推出的串行接口实时时钟芯片。芯片使用简单, 外部连线少,在智能化仪表及自动控制领域具有广泛用途。其主要特点为简 单的三线串行 I/O 接口; 2.5~5.5V 的电压工作范围(在 2.5V 工作时耗电 小于 300nA); 与 TTL 兼容(Vcc=5V)时; 实时时钟包括秒、分、小时、 日、月、星期和年(闰年)等信息; 31*8 静态 RAM 可供用户使用; 可 选的涓流充电方式; 工作电源和备份电源双引脚输入; 备份电源可由大容 量电容来替代。 2 脚和 3 脚接 32768Khz 晶振,1 脚接主电源,8 脚接备用电池(亦可用大 电容代替)。5、6、7 脚与单片机连接。 #include #include #define uint unsigned int #define uchar unsigned char
DS1302的驱动程序
DS1302的驱动一、芯片介绍DALLAS公司推出的专用时钟芯片DS1302内含有一个实时时钟/日历和31 字节静态RAM ,通过简单的串行接口与单片机进行通信。
实时时钟/日历电路提供秒﹑分﹑时﹑日﹑星期﹑月﹑年的信息,每月的天数和闰年的天数可自动调整。
时钟操作可通过AM/PM 指示决定采用24 或12 小时格式。
时钟/RAM 的读/写数据以一个字节或多达31 个字节的字符组方式通信,DS1302 工作时功耗很低保持数据和时钟信息时功率小于1mW,采用普通晶振。
DS1302 与单片机之间能简单地采用同步串行的方式进行通信,仅需用到三个口线:RES 复位;I/O 数据线;SCLK串行时钟,其引脚图如图2-8所示。
图2-8 DS1302引脚图其中VCC1为后备电源,VCC2为主电源。
在主电源关闭的情况下,也能保持时钟的连续运行。
DS1302由Vcc1或Vcc2两者中的较大者供电。
当Vcc2大于Vcc1+时,Vcc2给DS1302供电。
当Vcc2小于Vcc1时,DS1302由Vcc1供电。
X1和X2是振荡源,外接晶振。
RST是复位/片选线,通过把RST输入驱动置高电平来启动所有的数据传送。
RST输入有两种功能:首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST提供终止单字节或多字节数据的传送手段。
当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。
如果在传送过程中RST 置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。
上电运行时,在Vcc≥之前,RST必须保持低电平。
只有在SCLK为低电平时,才能将RST置为高电平,I/O 为串行数据输入输出端,SCLK始终是输入端。
1)DS1302的控制字节DS1302 的控制字如图2-9所示。
控制字节的最高有效位必须是逻辑1,如果它为0,则不能把数据写入DS1302中,位6如果为0,则表示存取日历时钟数据,为1表示存取RAM数据;位5至位1指示操作单元的地址;最低有效位(位0)如为0表示要进行写操作,为1表示进行读操作,控制字节总是从最低位开始输出。
实时时钟电路DS1302芯片的原理及应用
实时时钟电路DS1302芯片的原理及应用DS1302是一种实时时钟(RTC)电路芯片,由Dallas Semiconductor (现被Maxim Integrated收购)设计和制造。
它提供了一个准确的时间和日期计时功能,适用于许多应用,例如电子设备、仪器仪表、通讯设备和计算机系统等。
DS1302芯片的原理如下:1.时钟发生器:DS1302芯片内部集成了一个时钟发生器电路,它使用外部XTAL晶体和一个频率分频器来产生准确的时钟信号。
晶体的频率通常为32.768kHz,这是由于此频率具有较好的稳定性。
2.电源管理:DS1302芯片可以使用3V到5.5V的电源供电。
它内部具有电源管理电路,可以自动切换到低功耗模式以延长电池寿命。
3.时间计数器:DS1302芯片内部包含一个时间计数器,用于计算并保存当前时间、日期和星期。
它采用24小时制,并提供了BCD编码的小时、分钟、秒、日、月和年信息。
4.控制和数据接口:DS1302芯片使用串行接口与外部器件进行通信,如微控制器或外部检测电路。
控制和数据信息通过三根线SCLK(串行时钟)、I/O(串行数据输入/输出)和CE(片选)进行传输。
5.电源备份:为了确保即使在电源中断的情况下仍能保持时间数据,DS1302芯片通过附带的外部电池来提供电源备份功能。
当主电源中断时,芯片会自动切换到电池供电模式,并将时间数据存储在内部RAM中。
DS1302芯片的应用包括但不限于以下几个方面:1.时钟和日历显示:DS1302芯片可以直接连接到LCD显示屏、LED显示器或数码管等设备,用于显示当前时间和日期。
2.定时控制:DS1302芯片可以用作定时器或闹钟,在特定的时间触发一些事件。
例如,可以使用它作为控制家庭设备的定时开关。
3.数据记录:由于DS1302芯片具有时间计数功能,它可以用于记录事件的时间戳,如数据采集、操作记录或系统状态记录。
4.电源失效保护:DS1302芯片的电源备份功能可确保即使在电源中断的情况下,时间数据也能被保存,以避免系统重新启动后时间重置的问题。
DS1302时钟芯片C语言驱动程序
/*********************************************************************/ /* 实时时钟模块时钟芯片型号:DS1302 *//*/*//*********************************************************************/sbit T_CLK = P2^7; /*实时时钟时钟线引脚*/sbit T_IO = P1^4; /*实时时钟数据线引脚*/sbit T_RST = P1^5; /*实时时钟复位线引脚*//********************************************************************** 名称: v_RTInputByte* 说明:* 功能: 往DS1302写入1Byte数据* 调用:* 输入: ucDa 写入的数据* 返回值: 无***********************************************************************/ void v_RTInputByte(uchar ucDa){uchar i;ACC = ucDa;for(i=8; i>0; i--){T_IO = ACC0; /*相当于汇编中的RRC */T_CLK = 1;T_CLK = 0;ACC = ACC >> 1;}}/********************************************************************** 名称: uchar uc_RTOutputByte* 说明:* 功能: 从DS1302读取1Byte数据* 调用:* 输入:* 返回值: ACC***********************************************************************/ uchar uc_RTOutputByte(void){uchar i;for(i=8; i>0; i--){ACC = ACC >>1; /*相当于汇编中的RRC */ACC7 = T_IO;T_CLK = 1;T_CLK = 0;}return(ACC);}/********************************************************************** 名称: v_W1302* 说明: 先写地址,后写命令/数据* 功能: 往DS1302写入数据* 调用: v_RTInputByte()* 输入: ucAddr: DS1302地址, ucDa: 要写的数据* 返回值: 无***********************************************************************/ void v_W1302(uchar ucAddr, uchar ucDa){T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(ucAddr); /* 地址,命令*/v_RTInputByte(ucDa); /* 写1Byte数据*/T_CLK = 1;T_RST =0;}/********************************************************************** 名称: uc_R1302* 说明: 先写地址,后读命令/数据* 功能: 读取DS1302某地址的数据* 调用: v_RTInputByte() , uc_RTOutputByte()* 输入: ucAddr: DS1302地址* 返回值: ucDa :读取的数据***********************************************************************/ uchar uc_R1302(uchar ucAddr){uchar ucDa;T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(ucAddr); /* 地址,命令*/ucDa = uc_RTOutputByte(); /* 读1Byte数据*/T_CLK = 1;T_RST =0;return(ucDa);}/********************************************************************** 名称: v_BurstW1302T* 说明: 先写地址,后写数据(时钟多字节方式)* 功能: 往DS1302写入时钟数据(多字节方式)* 调用: v_RTInputByte()* 输入: pSecDa: 时钟数据地址格式为: 秒分时日月星期年控制* 8Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B 1B* 返回值: 无***********************************************************************/ void v_BurstW1302T(uchar *pSecDa){uchar i;v_W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xbe); /* 0xbe:时钟多字节写命令*/for (i=8;i>0;i--) /*8Byte = 7Byte 时钟数据+ 1Byte 控制*/{v_RTInputByte(*pSecDa);/* 写1Byte数据*/pSecDa++;T_CLK = 1;T_RST =0;}/********************************************************************** 名称: v_BurstR1302T* 说明: 先写地址,后读命令/数据(时钟多字节方式)* 功能: 读取DS1302时钟数据* 调用: v_RTInputByte() , uc_RTOutputByte()* 输入: pSecDa: 时钟数据地址格式为: 秒分时日月星期年* 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B* 返回值: ucDa :读取的数据***********************************************************************/ void v_BurstR1302T(uchar *pSecDa){uchar i;T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xbf); /* 0xbf:时钟多字节读命令*/for (i=8; i>0; i--){*pSecDa = uc_RTOutputByte(); /* 读1Byte数据*/pSecDa++;}T_CLK = 1;T_RST =0;/********************************************************************** 名称: v_BurstW1302R* 说明: 先写地址,后写数据(寄存器多字节方式)* 功能: 往DS1302寄存器数写入数据(多字节方式)* 调用: v_RTInputByte()* 输入: pReDa: 寄存器数据地址* 返回值: 无***********************************************************************/ void v_BurstW1302R(uchar *pReDa){uchar i;v_W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xfe); /* 0xbe:时钟多字节写命令*/for (i=31;i>0;i--) /*31Byte 寄存器数据*/{v_RTInputByte(*pReDa); /* 写1Byte数据*/pReDa++;}T_CLK = 1;T_RST =0;}/********************************************************************** 名称: uc_BurstR1302R* 说明: 先写地址,后读命令/数据(寄存器多字节方式)* 功能: 读取DS1302寄存器数据* 调用: v_RTInputByte() , uc_RTOutputByte()* 输入: pReDa: 寄存器数据地址* 返回值: 无***********************************************************************/ void v_BurstR1302R(uchar *pReDa){uchar i;T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xff); /* 0xbf:时钟多字节读命令*/for (i=31; i>0; i--) /*31Byte 寄存器数据*/{*pReDa = uc_RTOutputByte(); /* 读1Byte数据*/pReDa++;}T_CLK = 1;T_RST =0;}/********************************************************************** 名称: v_Set1302* 说明:* 功能: 设置初始时间* 调用: v_W1302()* 输入: pSecDa: 初始时间地址。
ds1302工作原理
ds1302工作原理DS1302是一款广泛应用于实时时钟(RTC)模块的集成电路芯片,它的工作原理是如何实现的呢?接下来我们将详细介绍DS1302的工作原理。
DS1302的工作原理主要包括时钟信号的生成、时间数据的存储和读取以及电源管理等几个方面。
首先,我们来看时钟信号的生成。
DS1302内部集成了一个时钟发生器电路,它能够产生稳定的时钟信号,这个时钟信号的频率可以通过外部晶体振荡器来调节,一般情况下为32.768kHz。
这个时钟信号会被用于驱动DS1302内部的计数器,从而实现对时间的计时和计数。
其次,DS1302还具有时间数据的存储和读取功能。
它内部集成了31个静态RAM存储单元,用于存储年、月、日、时、分、秒等时间数据。
通过串行接口,我们可以向DS1302写入时间数据,也可以从中读取时间数据。
这样就实现了对时间的存储和读取,为实时时钟的功能提供了基础支持。
此外,DS1302还具有电源管理功能。
它可以通过外部电池或超级电容来提供备份电源,以保证在主电源断电的情况下,实时时钟模块仍能够正常工作,并且不会丢失时间数据。
这种设计保证了实时时钟的稳定性和可靠性。
总的来说,DS1302的工作原理是基于时钟信号的生成、时间数据的存储和读取以及电源管理等几个关键功能。
通过这些功能的协同作用,DS1302能够实现精准的时间计时和计数,并且在断电情况下能够保持时间数据的稳定和可靠。
这使得DS1302在很多领域都有着广泛的应用,比如电子钟表、温度计、湿度计等各种需要时间计时功能的设备中都可以看到DS1302的身影。
综上所述,DS1302作为一款实时时钟模块的集成电路芯片,其工作原理主要包括时钟信号的生成、时间数据的存储和读取以及电源管理等几个方面。
这些功能的协同作用使得DS1302能够稳定可靠地实现时间的计时和计数,为各种设备和系统提供了精准的时间支持。
DS1302时钟芯片驱动程序
DS1302时钟芯片驱动程序//DS1302时钟芯片驱动程序#include <reg51.h>//下面是引脚连接关系sbit clock_dat=P1^0;sbit clock_clk=P1^1;sbit clock_clk=P1^2;sbit a0=ACC^0;sbit a1=ACC^1;sbit a2=ACC^2;sbit a3=ACC^3;sbit a4=ACC^4;sbit a5=ACC^5;sbit a6=ACC^6;sbit a7=ACC^7;void clock_out(unsigned char dd) {ACC=dd;clock_dat=a0;clock_clk=1;clock_clk=0; clock_dat=a1;clock_clk=1;clock_clk=0; clock_dat=a2;clock_clk=1;clock_clk=0; clock_dat=a3;clock_clk=1;clock_clk=0; clock_dat=a4;clock_clk=1;clock_clk=0; clock_dat=a5;clock_clk=1;clock_clk=0; clock_dat=a6;clock_clk=1;clock_clk=0; clock_dat=a7;clock_clk=1;clock_clk=0; }unsigned char clock_in(void) {clock_dat=1;a0=clock_dat;clock_clk=1;clock_clk=0;a1=clock_dat; clock_clk=1;clock_clk=0;a2=clock_dat; clock_clk=1;clock_clk=0;a3=clock_dat; clock_clk=1;clock_clk=0;a4=clock_dat; clock_clk=1;clock_clk=0;a5=clock_dat;clock_clk=1;clock_clk=0;a6=clock_dat;clock_clk=1;clock_clk=0;a7=clock_dat;return(ACC);}unsigned char read_clock(unsigned char ord) {unsigned char dd=0;clock_clk=0;clock_rst=0;clock_rst=1;clock_out(ord);dd=clock_in();clock_rst=0;clock_clk=1;return(dd);}void write_clock(unsigned char ord,unsigned char dd) {clock_clk=0;clock_rst=0;clock_rst=1;clock_out(ord);clock_out(dd);clock_rst=0;clock_clk=1;}/*注意事项:1.每次上电,必须把秒寄存器高位(第7位)设置为0,时钟才能走时。
实时时钟芯片DS1302
实时时钟芯片DS1302
DS1302 是一种三线制的串行时钟芯片,即CE(片选),SCLK(时钟),
I/O(双向数据)。
从严格意义上来说,它不是SPI 总线类型的,因为SPI 的数
据线的输入输出是分开的,但是我们操作的时候可以用带SPI 的硬件接口的MCU,比如PIC16F877 的MSSP 模块。
命令字节的基本格式
存储器结构
需要注意的地方:
1.在上电时,RST 必须为逻辑0 直至Vcc>
2.0V。
同时SCLK 在RST 驱动至逻辑1 状态时必须为逻辑0。
2.数据输入是在SCLK 的上升沿,数据输出是在SCLK 的下降沿。
3.传输方式:低位先传输。
4.时钟运行:秒寄存器的最高位(BIT7)是作为时钟控制位,当为逻辑1 时,时钟停止,为0 时钟运行。
所以如果要时钟运行的话就必须将秒寄存器的最高
位清0
5.12/24 小时模式:小时寄存器的第7 位(最高位)是选择12 小时制还是24 小时制。
当为逻辑1 时选择12 小时,逻辑0 选择24 小时。
当为12 小时制时,小时寄存器的第5 位用来表示上午AM 和下午PM,逻辑1 的时候表示PM,
逻辑0 的时候表示AM。
6.在企图对DS1302 操作之前,必须将WP 位清零。
7.读写模式:有两种模式,可以单字节读写,以及连续多字节读写(burst mode)。
在连续多字节读写时,即burst mode,地址是必须从地址0 的0 位开。
STM32F103驱动DS1302程序(带注释)
1简介主控芯片是STM32F103ZET6,DS1302模块在某宝购买,测试两个小时,发现一个小时大概差1秒钟。
芯片受温度、电压影响较大。
输出结果用串口打印到串口调试助手。
如果要oled或者其他显示需要转换为十进制。
2.代码部分2.1 led部分------------led.h--------------------#ifndef __LED_H#define __LED_H#include "sys.h"void LED_Init(void);//初始化#endif------------led.c--------------------#include "led.h"//LED IO初始化void LED_Init(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//使能PB端口时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//LED0-->PB.5 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//IO口速度为50MHzGPIO_Init(GPIOB, &GPIO_InitStructure);//根据设定参数初始化GPIOB.5GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB5 输出高}2.2 usart部分---------------usart.h------------------------#ifndef __USART_H#define __USART_H#include "stdio.h"#include "sys.h"void uart_init(u32 bound);void usart1_send_string(u8 *BuffToSend);void usart1_sendbyte(u8 data);#endif---------------usart.c-----------------------#include "sys.h"#include "usart.h"void uart_init(u32 bound){//GPIO端口设置GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Peri ph_GPIOA, ENABLE); //使能USART1,GPIOA时钟//USART1_TX GPIOA.9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9//USART1_RX GPIOA.10初始化GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10 //Usart1 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ; //抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC 寄存器//USART 初始化设置USART_ART_BaudRate = bound;//串口波特率USART_ART_WordLength = USART_WordLength_8b;//字长为8位数据格式USART_ART_StopBits = USART_StopBits_1;//一个停止位USART_ART_Parity = USART_Parity_No;//无奇偶校验位USART_ART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制USART_ART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式USART_Init(USART1, &USART_InitStructure); //初始化串口1USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断USART_Cmd(USART1, ENABLE); //使能串口1 }//打印字节void usart1_sendbyte(u8 data){USART_SendData(USART1, data);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);}//打印字符串void usart1_send_string(u8 *BuffToSend){u8 i=0;while(BuffToSend[i]!='\0'){USART_SendData(USART1, BuffToSend[i]);while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);i++;}}2.3 ds1302部分---------------ds1302.h-----------------------#ifndef __DS1302_H#define __DS1302_H#include "sys.h"//写年月日时间寄存器#define WriteSecond 0x80#define WriteMinute 0x82#define WriteHour 0x84#define WriteDay 0x86#define WriteMonth 0x88#define writeWeek 0x8a#define writeYear 0x8c//读年月日时间寄存器#define ReadSecond 0x81#define ReadMinute 0x83#define ReadHour 0x85#define ReadDay 0x87#define ReadMonth 0x89#define ReadWeek 0x8b#define ReadYear 0x8d//引脚分配 SDA-PC3 SCL-PC4 RST-PC5#define DS_SDA_IN {GPIOC->CRL&=0XFFFF0FFF;GPIOC->CRL|=(u32)8<<12;}#define DS_SDA_OUT{GPIOC->CRL&=0XFFFF0FFF;GPIOC->CRL|=(u32)3<<12;}#define DS_SDA_DATA GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)//SDA#define DS_SDA_HIGH GPIO_SetBits(GPIOC,GPIO_Pin_3)#define DS_SDA_LOW GPIO_ResetBits(GPIOC,GPIO_Pin_3)#define DS_SCK_HIGH GPIO_SetBits(GPIOC,GPIO_Pin_4)//SCL#define DS_SCK_LOW GPIO_ResetBits(GPIOC,GPIO_Pin_4)#define DS_RST_HIGH GPIO_SetBits(GPIOC,GPIO_Pin_5)//CE#define DS_RST_LOW GPIO_ResetBits(GPIOC,GPIO_Pin_5)void ds1302_init(void);void write_one_byte(u8 data);u8 read_one_byte(void);void ds1302_write_data(u8 reg,u8 data);u8 ds1302_read_data(u8 reg);void time_init(void);void time_read(void);u8 hex_to_bcd(u8 hex_data);u8 bcd_to_hex(u8 bcd_data);#endif---------------ds1302.c-----------------------#include "ds1302.h"#include "delay.h"u8 DSsecond,DSminute,DShour,DSweek,DSday,DSmonth,DSyear;u8 time[7]={0x18,0x06,0x10,0x19,0x23,0x59,0x30};//年星期月日时分秒void ds1302_init(){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_ResetBits(GPIOC,GPIO_Pin_5);//CE拉低GPIO_SetBits(GPIOC, GPIO_Pin_3|GPIO_Pin_4); //拉高}//写入一个字节void write_one_byte(u8 data){u8 i;DS_SDA_OUT;for(i=0;i<8;i++){DS_SCK_LOW;if(data&0x01) //从低位开始{DS_SDA_HIGH;}else{DS_SDA_LOW;}delay_us(2);DS_SCK_HIGH;data>>=1;delay_us(2);}}//读一个字节u8 read_one_byte(){u8 i,data;DS_SDA_IN ;for(i=0;i<8;i++){data>>=1;DS_SCK_HIGH;if(DS_SDA_DATA==1){data|=0x80;}else{data&=0x7F;}delay_us(2);DS_SCK_LOW;}return data;}//ds1302写寄存器写数据void ds1302_write_data(u8 reg,u8 data) {DS_SCK_LOW;DS_RST_LOW;//初始rst为低delay_us(2);DS_RST_HIGH;//sck为低时rst才可置高 write_one_byte(reg); //sck低到高delay_us(5);DS_SCK_LOW;write_one_byte(data); //sck低到高delay_us(5);//DS_SCK_HIGH;DS_RST_LOW;}//读ds1302寄存器数据u8 ds1302_read_data(u8 reg){u8 temp;DS_SCK_LOW;DS_RST_LOW;//初始rst为低delay_us(2);DS_RST_HIGH;//sck为低时rst才可置高 delay_us(2);write_one_byte(reg); //sck低到高delay_us(5);DS_SCK_LOW;temp=read_one_byte(); //sck由高到低delay_us(5);//DS_SCK_HIGH;DS_RST_LOW;return temp;}u8 hex_to_bcd(u8 hex_data){u8 temp;temp=(hex_data/10*16 + hex_data%10);return temp;}u8 bcd_to_hex(u8 bcd_data){u8 temp;temp=(bcd_data/16*10 + bcd_data%16);return temp;}//time初始化void time_init(){ds1302_write_data(0x8e,0x00);//关闭写保护ds1302_write_data(writeYear ,(time[0]));//写入hex格式数据ds1302_write_data(writeWeek,(time[1]));ds1302_write_data(WriteMonth,(time[2]));ds1302_write_data(WriteDay,(time[3]));ds1302_write_data(WriteHour,(time[4]));ds1302_write_data(WriteMinute,(time[5]));//ds1302_write_data(WriteSecond,(time[6]));//ds1302_write_data(0x8e,0x80);//开启写保护}//读取寄存器时间void time_read(){DSyear=ds1302_read_data(ReadYear);DSweek=ds1302_read_data(ReadWeek);DSmonth=ds1302_read_data(ReadMonth);DSday=ds1302_read_data(ReadDay);DShour=ds1302_read_data(ReadHour);DSminute=ds1302_read_data(ReadMinute);DSsecond=ds1302_read_data(ReadSecond);}2.4主函数---------------main-----------------------#include "sys.h"#include "delay.h"#include "usart.h"#include "led.h"#include "ds1302.h"Extern u8 DSsecond,DSminute,DShour,DSweek,DSday,DSmonth,DSyear;int main(void){delay_init();LED_Init();uart_init(115200);ds1302_init();time_init();while(1){time_read();//更新时间usart1_sendbyte(DSyear);usart1_sendbyte(DSmonth);usart1_sendbyte(DSday);usart1_sendbyte(DShour);usart1_sendbyte(DSminute);usart1_sendbyte(DSsecond);usart1_sendbyte(DSweek);GPIO_ResetBits(GPIOB,GPIO_Pin_5); //LED0闪烁delay_ms(250);GPIO_SetBits(GPIOB,GPIO_Pin_5); //delay_ms(250);}}3.结果串口调试助手hex显示,打印的是十六进制数据。
DS1302的驱动程序
v1.0 可编辑可修改DS1302的驱动一、芯片介绍DALLAS公司推出的专用时钟芯片DS1302内含有一个实时时钟/日历和31 字节静态RAM ,通过简单的串行接口与单片机进行通信。
实时时钟/日历电路提供秒﹑分﹑时﹑日﹑星期﹑月﹑年的信息,每月的天数和闰年的天数可自动调整。
时钟操作可通过AM/PM 指示决定采用24 或12 小时格式。
时钟/RAM 的读/写数据以一个字节或多达31 个字节的字符组方式通信,DS1302 工作时功耗很低保持数据和时钟信息时功率小于1mW,采用普通晶振。
DS1302 与单片机之间能简单地采用同步串行的方式进行通信,仅需用到三个口线:RES 复位;I/O 数据线;SCLK串行时钟,其引脚图如图2-8所示。
图2-8 DS1302引脚图其中VCC1为后备电源,VCC2为主电源。
在主电源关闭的情况下,也能保持时钟的连续运行。
DS1302由Vcc1或Vcc2两者中的较大者供电。
当Vcc2大于Vcc1+时,Vcc2给DS1302供电。
当Vcc2小于Vcc1时,DS1302由Vcc1供电。
X1和X2是振荡源,外接晶振。
RST是复位/片选线,通过把RST输入驱动置高电平来启动所有的数据传送。
RST输入有两种功能:首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST提供终止单字节或多字节数据的传送手段。
当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。
如果在传送过程中RST 置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。
上电运行时,在Vcc≥之前,RST必须保持低电平。
只有在SCLK为低电平时,才能将RST置为高电平,I/O 为串行数据输入输出端,SCLK始终是输入端。
1)DS1302的控制字节2)DS1302 的控制字如图2-9所示。
图2-9 DS1302 的控制字节控制字节的最高有效位必须是逻辑1,如果它为0,则不能把数据写入DS1302中,位6如果为0,则表示存取日历时钟数据,为1表示存取RAM数据;位5至位1指示操作单元的地址;最低有效位(位0)如为0表示要进行写操作,为1表示进行读操作,控制字节总是从最低位开始输出。
ds1302中文资料
1 DS1302 简介:DS1302是美国DALLAS公司推出的一种高性能、低功耗的实时时钟芯片,附加31字节静态RAM,采用SPI三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号和RAM 数据。
实时时钟可提供秒、分、时、日、星期、月和年,一个月小与31天时可以自动调整,且具有闰年补偿功能。
工作电压宽达2.5~5.5V。
采用双电源供电(主电源和备用电源),可设置备用电源充电方式,提供了对后背电源进行涓细电流充电的能力。
DS1302的外部引脚分配如图1所示及内部结构如图2所示。
DS1302用于数据记录,特别是对某些具有特殊意义的数据点的记录上,能实现数据与出现该数据的时间同时记录,因此广泛应用于测量系统中。
图1 DS1302的外部引脚分配图2 DS1302的内部结构各引脚的功能为:Vcc1:主电源;Vcc2:备份电源。
当Vcc2>Vcc1+0.2V时,由Vcc2向DS1302供电,当Vcc2< Vcc1时,由Vcc1向DS1302供电。
SCLK:串行时钟,输入,控制数据的输入与输出;I/O:三线接口时的双向数据线;CE:输入信号,在读、写数据期间,必须为高。
该引脚有两个功能:第一,CE开始控制字访问移位寄存器的控制逻辑;其次,CE提供结束单字节或多字节数据传输的方法。
DS1302有下列几组寄存器:① DS1302有关日历、时间的寄存器共有12个,其中有7个寄存器(读时81h~8Dh,写时80h~8Ch),存放的数据格式为BCD码形式,如图3所示。
图 3 DS1302有关日历、时间的寄存器小时寄存器(85h、84h)的位7用于定义DS1302是运行于12小时模式还是24小时模式。
当为高时,选择12小时模式。
在12小时模式时,位5是,当为1时,表示PM。
在24小时模式时,位5是第二个10小时位。
秒寄存器(81h、80h)的位7定义为时钟暂停标志(CH)。
当该位置为1时,时钟振荡器停止,DS1302处于低功耗状态;当该位置为0时,时钟开始运行。
DS1302通俗易懂的教程
DS1302通俗易懂的教程晨辉教你轻松学51--------外围芯片之ds1302和ds18b20对于市面上的大多数51单片机开发板来说。
ds1302和ds18b20应该是比较常见的两种外围芯片。
ds1302是具有SPI总线接口的时钟芯片。
ds18b20则是具有单总线接口的数字温度传感器。
下面让我们分别来认识并学会应用这两种芯片。
首先依旧是看DS1302的datasheet中的相关介绍。
上面是它的一些基本的应用介绍。
下面是它的引脚的描述。
下面是DS1302的时钟寄存器。
我们要读取的时间数据就是从下面这些数据寄存器中读取出来的。
当我们要想调整时间时,可以把时间数据写入到相应的寄存器中就可以了。
这是DS1302内部的31个RAM寄存器。
在某些应用场合我们可以应用到。
如我们想要做一个带定时功能的闹钟。
则可以把闹钟的时间写入到31个RAM寄存器中的任意几个。
当单片机掉电时,只要我们的DS1302的备用电池还能工作,那么保存在其中的闹钟数据就不会丢失~~由于对于这些器件的操作基本上按照数据手册上面提供的时序图和相关命令字来进行操作就可以了。
因此在我们应用这些器件的时候一定要对照着手册上面的要求来进行操作。
如果觉得还不够放心的话。
可以到网上下载一些参考程序。
对着手册看别人的程序,看别人的思路是怎么样的。
DS1302和单片机的连接很简单。
只需一根复位线,一根时钟线,一根数据线即可。
同时它本身还需要接一个32.768KHz的晶振来提供时钟源。
对于晶振的两端可以分别接一个6PF左右的电容以提高晶振的精确度。
同时可以在第8脚接上一个3.6V的可充电的电池。
当系统正常工作时可以对电池进行涓流充电。
当系统掉电时,DS1302由这个电池提供的能量继续工作。
下面让我们来驱动它。
sbit io_DS1302_RST = P2^0 ;sbit io_DS1302_IO = P2^1 ;sbit io_DS1302_SCLK = P2^2 ;//-------------------------------------常数宏---------------------------------//#define DS1302_SECOND_WRITE 0x80 //写时钟芯片的寄存器位置#define DS1302_MINUTE_WRITE 0x82#define DS1302_HOUR_WRITE 0x84#define DS1302_WEEK_WRITE 0x8A#define DS1302_DAY_WRITE 0x86#define DS1302_MONTH_WRITE 0x88#define DS1302_YEAR_WRITE 0x8C#define DS1302_SECOND_READ 0x81 //读时钟芯片的寄存器位置#define DS1302_MINUTE_READ 0x83#define DS1302_HOUR_READ 0x85#define DS1302_WEEK_READ 0x8B#define DS1302_DAY_READ 0x87#define DS1302_MONTH_READ 0x89#define DS1302_YEAR_READ 0x8D//-----------------------------------操作宏----------------------------------//#define DS1302_SCLK_HIGH io_DS1302_SCLK = 1 ;#define DS1302_SCLK_LOW io_DS1302_SCLK = 0 ;#define DS1302_IO_HIGH io_DS1302_IO = 1 ;#define DS1302_IO_LOW io_DS1302_IO = 0 ;#define DS1302_IO_READ io_DS1302_IO#define DS1302_RST_HIGH io_DS1302_RST = 1 ;#define DS1302_RST_LOW io_DS1302_RST = 0 ;/******************************************************* 保存时间数据的结构体 *******************************************************/struct{uint8 Second ;uint8 Minute ;uint8 Hour ;uint8 Day ;uint8 Week ;uint8 Month ;uint8 Year ;}CurrentTime ;/************************************************************** **************** * Function: static void v_DS1302Write_f( uint8 Content ) ** Description:向DS1302写一个字节的内容 ** Parameter:uint8 Content : 要写的字节 ** **************************************************************** ***************/static void v_DS1302Write_f( uint8 Content ){uint8 i ;for( i = 8 ; i > 0 ; i-- ){if( Content & 0x01 ){DS1302_IO_HIGH}else{DS1302_IO_LOW}Content >>= 1 ;DS1302_SCLK_HIGHDS1302_SCLK_LOW}}/************************************************************** **************** * Function: static uint8 v_DS1302Read_f( void ) * * Description: 从DS1302当前设定的地址读取一个字节的内容* * Parameter: ** Return: 返回读出来的值(uint8) **************************************************************** ***************/static uint8 v_DS1302Read_f( void ){uint8 i, ReadValue ;DS1302_IO_HIGHfor( i = 8 ; i > 0 ; i-- ){ReadValue >>= 1 ;if( DS1302_IO_READ ){ReadValue |= 0x80 ;}else{ReadValue &= 0x7f ;}DS1302_SCLK_HIGHDS1302_SCLK_LOW}return ReadValue ;}/************************************************************** **************** * Function: void v_DS1302WriteByte_f( uint8 Address, uint8 Content ) ** Description: 从DS1302指定的地址写入一个字节的内容 ** Parameter: Address: 要写入数据的地址 ** Content: 写入数据的具体值 **Return: * ******************************************************************* ***********/ void v_DS1302WriteByte_f( uint8 Address, uint8 Content ){DS1302_RST_LOWDS1302_SCLK_LOWDS1302_RST_HIGHv_DS1302Write_f( Address ) ;v_DS1302Write_f( Content ) ;DS1302_RST_LOWDS1302_SCLK_HIGH}/************************************************************** **************** * Function: uint8 v_DS1302ReadByte_f( uint8 Address ) ** Description:从DS1302指定的地址读出一个字节的内容 ** Parameter:Address: 要读出数据的地址 ** ** Return: 指定地址读出的值(uint8) **************************************************************** ***************/ uint8 v_DS1302ReadByte_f( uint8 Address ) {uint8 ReadValue ;DS1302_RST_LOWDS1302_SCLK_LOWDS1302_RST_HIGHv_DS1302Write_f( Address ) ;ReadValue = v_DS1302Read_f() ;DS1302_RST_LOWDS1302_SCLK_HIGHreturn ReadValue ;}/************************************************************** **************** * Function: void v_ClockInit_f( void ) * * Description:初始化写入DS1302时钟寄存器的值(主程序中只需调用一次即可) **Parameter:** ** Return: **************************************************************** ***************/ void v_ClockInit_f( void ){if( v_DS1302ReadByte_f( 0xc1) != 0xf0 ){v_DS1302WriteByte_f( 0x8e, 0x00 ) ; //允许写操作v_DS1302WriteByte_f( DS1302_YEAR_WRITE, 0x08 ) ; //年v_DS1302WriteByte_f( DS1302_WEEK_WRITE, 0x04 ) ; //星期v_DS1302WriteByte_f( DS1302_MONTH_WRITE, 0x12 ) ; //月v_DS1302WriteByte_f( DS1302_DAY_WRITE, 0x11 ) ; //日v_DS1302WriteByte_f( DS1302_HOUR_WRITE, 0x13 ) ; //小时v_DS1302WriteByte_f( DS1302_MINUTE_WRITE, 0x06 ) ; //分钟v_DS1302WriteByte_f( DS1302_SECOND_WRITE, 0x40 ) ; //秒v_DS1302WriteByte_f( 0x90, 0xa5 ) ; //充电v_DS1302WriteByte_f( 0xc0, 0xf0 ) ; //判断是否初始化一次标识写入v_DS1302WriteByte_f( 0x8e, 0x80 ) ; //禁止写操作}}/************************************************************** **************** * Function: void v_ClockUpdata_f( void ) * * Description:读取时间数据,并保存在结构体CurrentTime中 * *Parameter:** **Return:**************************************************************** ***************/ void v_ClockUpdata_f( void ){CurrentTime.Second =v_DS1302ReadByte_f( DS1302_SECOND_READ ) ;CurrentTime.Minute = v_DS1302ReadByte_f( DS1302_MINUTE_READ ) ;CurrentTime.Hour = v_DS1302ReadByte_f( DS1302_HOUR_READ ) ;CurrentTime.Day = v_DS1302ReadByte_f( DS1302_DAY_READ ) ;CurrentTime.Month = v_DS1302ReadByte_f( DS1302_MONTH_READ ) ;CurrentTime.Week = v_DS1302ReadByte_f( DS1302_WEEK_READ ) ;CurrentTime.Year = v_DS1302ReadByte_f( DS1302_YEAR_READ ) ;}有了上面的这些函数我们就可以对DS1302进行操作了。
DS1302时钟芯片C51驱动程序
DS1302时钟芯片C51驱动程序/**********************************************程序名称:DS1302时钟芯片C51驱动程序简要说明:read_clockS函数为读取时钟数据调用Set_time即可调整时间并写入DS1302sel为调整标志,可通过外部按键来更改其值来源:整理杜洋程序文档所得**********************************************///定义头文件#include/************************************************************** ****///定义DS1302时钟接口sbit clock_clk = P1 ^ 0; //ds1302_clk(时钟线)sbit clock_dat = P1 ^ 1; //ds1302_dat(数据线)sbit clock_Rst = P1 ^ 2; //ds1302_Rst(复位线)/************************************************************** ****///定义累加器A中的各位sbit a0 = ACC ^ 0;sbit a1 = ACC ^ 1;sbit a2 = ACC ^ 2;sbit a3 = ACC ^ 3;sbit a4 = ACC ^ 4;sbit a5 = ACC ^ 5;sbit a6 = ACC ^ 6;sbit a7 = ACC ^ 7;/************************************************************** ****///定义全局变量unsigned char yy,mo,dd,xq,hh,mm,ss; //定义时间映射全局变量/************************************************************** ****///声明unsigned char clock_in(void);void clock_out(unsigned char dd);void Init_1302(void);unsigned char read_clock(unsigned char ord);void read_clockS(void);void Set_time(unsigned char sel);void write_clock(unsigned char ord, unsigned char dd);/************************************************************** ****///常用时钟数据读取void read_clockS(void){ss = read_clock(0x81); //读取秒数据mm = read_clock(0x83); //读取分钟数据hh = read_clock(0x85); //小时dd = read_clock(0x87); //日mo = read_clock(0x89); //月xq = read_clock(0x8b); //星期yy = read_clock(0x8d); //年}/************************************************************** ****///调时用加1或减1程序void Set_time(unsigned char sel){//根据选择调整的相应项目加1或减1并写入DS1302,sel为调整项标志,通过外部程序来影响它signed char address,item;signed char max,mini;if(sel==6) {address=0x80; max=0;mini=0;} //秒7if(sel==5) {address=0x82; max=59;mini=0;} //分钟6if(sel==4) {address=0x84; max=23;mini=0;} //小时5if(sel==3) {address=0x8a; max=7;mini=1;} //星期4if(sel==2) {address=0x86; max=31;mini=1;} //日3if(sel==1) {address=0x88; max=12;mini=1;} //月2if(sel==0) {address=0x8c; max=99; mini=0;} //年1//读取1302某地址上的数值转换成10进制赋给itemitem=((read_clock(address+1))/16)*10 + (read_clock(address+1))%16;if(ADD_KEY == 0){item++;} //增加键(ADD_KEY)按下,数加1if(DEC_KEY == 0){item--;} //减少键(DEC_KEY)按下,数减 1 if(item>max) item=mini; //查看数值有效范围if(itemwrite_clock(0x8e,0x00); //允许写操作write_clock(address,(item/10)*16+item%10);//转换成16进制写入1302write_clock(0x8e,0x80); //写保护,禁止写操作}/************************************************************** ****///设置1302的初始时间void Init_1302(void)//(2009年1月1日00时00分00秒星期一){write_clock(0x8e,0x00); //允许写操作write_clock(0x8c,0x09); //年write_clock(0x8a,0x01); //星期write_clock(0x88,0x01); //月write_clock(0x86,0x01); //日write_clock(0x84,0x00); //小时write_clock(0x82,0x00); //分钟write_clock(0x80,0x00); //秒write_clock(0x90,0xa5); //充电write_clock(0x8e,0x80); //禁止写操作}/************************************************************** ****///DS1302写数据(底层协议)void write_clock(unsigned char ord, unsigned char dd){clock_clk=0;clock_Rst=0;clock_Rst=1;clock_out(ord);clock_out(dd);clock_Rst=0;clock_clk=1;}/************************************************************** ****///1302驱动程序(底层协议)void clock_out(unsigned char dd){ACC=dd;clock_dat=a0; clock_clk=1; clock_clk=0;clock_dat=a1; clock_clk=1; clock_clk=0;clock_dat=a2; clock_clk=1; clock_clk=0;clock_dat=a3; clock_clk=1; clock_clk=0;clock_dat=a4; clock_clk=1; clock_clk=0;clock_dat=a5; clock_clk=1; clock_clk=0;clock_dat=a6; clock_clk=1; clock_clk=0;clock_dat=a7; clock_clk=1; clock_clk=0;}/************************************************************** ****///DS1302写入字节(底层协议)unsigned char clock_in(void){clock_dat=1;a0=clock_dat;clock_clk=1; clock_clk=0; a1=clock_dat;clock_clk=1; clock_clk=0; a2=clock_dat;clock_clk=1; clock_clk=0; a3=clock_dat;clock_clk=1; clock_clk=0; a4=clock_dat;clock_clk=1; clock_clk=0; a5=clock_dat;clock_clk=1; clock_clk=0; a6=clock_dat;clock_clk=1; clock_clk=0; a7=clock_dat;return(ACC);}/************************************************************** ****///DS1302读数据(底层协议)unsigned char read_clock(unsigned char ord){unsigned char dd=0;clock_clk=0;clock_Rst=0;clock_Rst=1;clock_out(ord);dd=clock_in();clock_Rst=0;clock_clk=1;return(dd);}/************************************************************** ****/。
基于STM32的DS1302时钟模块驱动程序(详细)
基于STM32的DS1302时钟模块驱动程序(详细)⽬录1.项⽬概述2.DS1032的数据⼿册解析2.1 DS1302的引脚介绍2.2 DS1302的通讯协议及时序2.3 DS1302的相关寄存器3.程序代码及其注释4.结果演⽰5.附录:7针0.96⼨OLED屏驱动代码(SPI驱动)1.项⽬概述本程序采⽤的主控芯⽚为STM32F103RCT6,通过主控芯⽚驱动DS1302时钟模块,并将其实时时间显⽰在7针0.96⼨OLED屏上。
使⽤STM32的普通IO⼝模拟DS1302的通信时序,使⽤STM32的SPI外设驱动OLED屏。
下⾯从DS1302的数据⼿册开始完成整个项⽬。
2.DS1302数据⼿册解析2.1DS1302引脚介绍VCC1,VCC2是电源引脚,VCC1是主供电引脚,VCC2接备⽤电池,当主供电电源电量不⾜或者断电时,备⽤电池会通过VCC2及时供电,保证时钟模块在主供电引脚断电后任然会正常计时。
GND是地引脚。
X1,X2是有关晶振的引脚,不做深究。
CE引脚是输⼊引脚,在单⽚机从DS1302读取数据或者向其写⼊数据时,CE引脚必须配置为⾼电平。
在芯⽚内部连接有40K下拉电阻。
I/O引脚充当双向数据引脚,即数据的发送和接收都在这条线上完成。
SCLK是同步时钟引脚,控制I/O引脚上数据的接收和发送。
2.2 DS1302的通讯协议及时序指令字节启动每次的数据传输,上图说明了指令字节的构造。
①位7必须为逻辑1,位7为逻辑0时指令会失效。
②我们使⽤的不是RAM当中的寄存器及数据,故位6应该为逻辑0。
③位1到位5为寄存器地址。
④位0为逻辑0时表明要往指定寄存器⾥⾯写数据,为逻辑1时要从指定寄存器⾥⾯读出数据。
指令字节的传输总是从位0(LSB)开始传输。
上图是ds1302通信时序图。
1.CE和时钟控制。
将CE置⾼将开启数据传输,CE输⼊提供俩个功能,⾸先CE开启了通信数据进⼊移位寄存器的通路,其次CE提供了⼀个可以终⽌单个字节或者多个字节的数据传输。
关于DS1302使用的一点心得
关于DS1302使用的一点心得
准确地说,我是从2012年的秋天开始接触DS1302这个芯片的。
时年大四,正在做电子专业的专业实习。
我们的题目是智能家居,其中用到了
DS1302这个芯片。
当时做下来只是知道了这个东西是干什幺用的,至于怎幺用,可以说是完全没弄明白。
但当时在网上找了相关的资料,也下载了一些前辈写的程序,当时扔到Proteus上去仿真,大概知道了改哪条语句可以实现什幺功能什幺的。
时隔一年以后,已经是毕业的人了。
刚刚到公司报道,工作还比较闲,晚上或周末就有时间学点电路什幺的,就又把DS1302翻了出来。
这期间买了IC和关键的32.768kHz的晶振。
于是就把电路给搭了出来。
这次算是一次入门,虽然没能完全搞透,但知道了以下几点:
1.DS1302的驱动分为往里写和往外读;
2.片内集成了一部分RAM,这部分内容是不受晶振影响的;个人观点,这部分应用很鸡肋。
3.往里写数据和往外读数据的时候,IO口方向(input或output)是不同的:在写数据的时候是先发8位的地址位,再发8位的时间信息(或将要写入RAM的内容),此过程中,IO口方向一直是output。
而读数据时,同样也是要先发8位的地址位,但之后要将IO口状态改为input,这时将开始允许从DS1302传来信息。
这里我只是说允许信息过来,而不是说接收信息,因为信息是一位一位传过来的,要加以整理并储存下来才算是接受,这是软件对应上的事情,但不考虑这些的话,至少此时是有信息过来的,只是你如何读取。
DS1302驱动程序
DS1302是课程设计和毕业设计经常用到的时钟芯片,还在愁怎么对DS1302操作吗?那么看完DS1302驱动程序,一切变得那么简单。
DS1302驱动程序://===========DS1302.H================#ifndef _DS1302_H__#define _DS1302_H__//DS1302管脚定义sbit T_IO=P2^6; //位定义1302芯片的接口,数据输出端定义在P2.5引脚sbit T_RST=P2^7; //位定义1302芯片的接口,复位端口定义在P2.6引脚sbit T_CLK=P2^5; //位定义1302芯片的接口,时钟输出端口定义在P2.4引脚//变量定义声明unsigned char TableDs1302[7]={55,59,23,4,3,5,11}; //初始化时时间日期设置//秒分时日月星期年//函数定义声明void Write1302(unsigned char ); //向1302写一个字节数据void WriteSet1302(unsigned char ,unsigned char );//根据命令字,向1302写一个字节数据unsigned char Read1302(void);//从1302读一个字节数据unsigned char ReadSet1302(unsigned char Cmd);//根据命令字从1302读取一个字节数据void InitDS1302(void);//初始化1302void GetTime(void);//获取1302的时间/*****************************************************函数功能:向1302写一个字节数据入口参数:x***************************************************/void Write1302(unsigned char dat){unsigned char i;T_CLK=0; //拉低T_CLK,为脉冲上升沿写入数据做好准备Delay1Us(2); //稍微等待,使硬件做好准备for(i=0;i<8;i++) //连续写8个二进制位数据{T_IO=dat&0x01; //取出dat的第0位数据写入1302Delay1Us(2); //稍微等待,使硬件做好准备T_CLK=1; //上升沿写入数据Delay1Us(2); //稍微等待,使硬件做好准备T_CLK=0; //重新拉低T_CLK,形成脉冲dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位}}/*****************************************************函数功能:根据命令字,向1302写一个字节数据入口参数:Cmd,储存命令字;dat,储存待写的数据,为十进制数***************************************************/void WriteSet1302(unsigned char Cmd,unsigned char dat){T_RST=0; //禁止数据传递T_CLK=0; //确保写数居前T_CLK被拉低T_RST=1; //启动数据传输Delay1Us(2); //稍微等待,使硬件做好准备Write1302(Cmd); //写入命令字Write1302((dat/10<<4)|(dat%10)); //写数据T_CLK=1; //将时钟电平置于已知状态T_RST=0; //禁止数据传递}/*****************************************************函数功能:从1302读一个字节数据入口参数:x***************************************************/unsigned char Read1302(void){unsigned char i,dat;Delay1Us(2); //稍微等待,使硬件做好准备for(i=0;i<8;i++) //连续读8个二进制位数据{dat>>=1; //将dat的各数据位右移1位,因为先读出的是字节的最低位if(T_IO==1) //如果读出的数据是1dat|=0x80; //将1取出,写在dat的最高位T_CLK=1; //将T_CLK置于高电平,为下降沿读出Delay1Us(2); //稍微等待T_CLK=0; //拉低T_CLK,形成脉冲下降沿Delay1Us(2); //稍微等待}return dat; //将读出的数据返回}/*****************************************************函数功能:根据命令字,从1302读取一个字节数据入口参数:Cmd***************************************************/unsigned char ReadSet1302(unsigned char Cmd){unsigned char temp,dat1,dat2;T_RST=0; //拉低T_RSTT_CLK=0; //确保写数居前T_CLK被拉低T_RST=1; //启动数据传输Write1302(Cmd); //写入命令字temp=Read1302(); //读出数据T_CLK=1; //将时钟电平置于已知状态T_RST=0; //禁止数据传递dat1=temp/16; //16进制转成BCDdat2=temp%16;temp=dat1*10+dat2; //转换成10进制数字return (temp); //将读出的数据返回}/*****************************************************函数功能: 1302进行初始化设置***************************************************/void InitDS1302(void){unsigned char i,add;add=0x80;WriteSet1302(0x8e,0x00); //允许写入for(i=0;i<7;i++){WriteSet1302(add,TableDs1302[i]);add+=2;}WriteSet1302(0x90,0xa6); //写充电控制寄存器.WriteSet1302(0x8e,0x80); //禁止写入}/*****************************************************程序功能:获取DS1302时间*****************************************************/void GetTime(){unsigned char i,add=0x81;WriteSet1302(0x8e,0x00); //允许向DS1302写入数据for(i=0;i<7;i++){TableDs1302[i]=ReadSet1302(add); //获得的数据已转换为十进制add+=2;}WriteSet1302(0x8e,0x80); //获取完一次时间,禁止向DS1302写入数据,提高可靠}endif。
DS1302驱动
单片机常用器件驱动及应用实例1 DS1302 简介:DS1302是美国DALLAS公司推出的一种高性能、低功耗的实时时钟芯片,附加31字节静态RAM,采用SPI三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号和RAM数据。
实时时钟可提供秒、分、时、日、星期、月和年,一个月小与31天时可以自动调整,且具有闰年补偿功能。
工作电压宽达2.5~5.5V。
采用双电源供电(主电源和备用电源),可设置备用电源充电方式,提供了对后背电源进行涓细电流充电的能力。
DS1302的外部引脚分配如图1所示及内部结构如图2所示。
DS1302用于数据记录,特别是对某些具有特殊意义的数据点的记录上,能实现数据与出现该数据的时间同时记录,因此广泛应用于测量系统中。
图1 DS1302的外部引脚分配图2 DS1302的内部结构各引脚的功能为:Vcc1:主电源;Vcc2:备份电源。
当Vcc2>Vcc1+0.2V时,由Vcc2向DS1302供电,当Vcc2< Vcc1时,由Vcc1向DS1302供电。
SCLK:串行时钟,输入;I/O:三线接口时的双向数据线;CE:输入信号,在读、写数据期间,必须为高。
该引脚有两个功能:第一,CE开始控制字访问移位寄存器的控制逻辑;其次,CE提供结束单字节或多字节数据传输的方法。
DS1302有下列几组寄存器:① DS1302有关日历、时间的寄存器共有12个,其中有7个寄存器(读时81h~8Dh,写时80h~8Ch),存放的数据格式为BCD码形式,如图3所示。
图 3 DS1302有关日历、时间的寄存器小时寄存器(85h、84h)的位7用于定义DS1302是运行于12小时模式还是AM/,24小时模式。
当为高时,选择12小时模式。
在12小时模式时,位5是PM当为1时,表示PM。
在24小时模式时,位5是第二个10小时位。
秒寄存器(81h、80h)的位7定义为时钟暂停标志(CH)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#define uint unsigned int
sbit IO=P1^0;//DS1302数据线
sbit SCLK=P1^1;//DS1302时钟线
sbit RST=P1^2;//DS1302复位线
uchar WEEK[][4]={"SUN","***","MON","TUS","WEN","THU","FRI","SAT"}; //亦可定义成指针数组*WEEK[]
{
uchar dat;
RST=0; //拉低RST
SCLK=0; //确保写数据前SCLK被拉低
RST=1;//启动数据传输,只有在SCLK为低电平时才能将RST置为高电平
Write_A_Byte_TO_DS1302(addr); //写入命令字
dat=Get_A_Byte_FROM_DS1302();
//命令字:也即读寄存器的地址最高位位7必须为1,位6如果为0表示存取日历数据,位5至位1表示操作单元的地址,位0为1表示读操作
//------------------------------------------------------------------
uchar Read_Data(uchar addr)
addr+=2;
}
}
//------------------------------------------------------------------
//日期与时间值转换为数字字符
//------------------------------------------------------------------
Display_LCD_String(0x00,LCD_DSY_BUFFER1); //第一行显示年、月、日、星期几
Display_LCD_String(0x40,LCD_DSY_BUFFER2); //第二行显示小时、分钟、秒
}
}
//--------------------------------------------------------
DS1302驱动程序详解
//------------------------------------------------------------------
//名称:DS1302时钟
//------------------------------------------------------------------
}
//------------------------------------------------------------------
//函数名称:Read_Data(uchar addr)
//函数功能:从DS1302的指定寄存器读数据
//输入参数:addr为读寄存器的地址
//返回值:dat读取的数据
//入后的下一个SCLK时钟的上升沿时数据被写入DS1302,数据输入从第0位开始
//------------------------------------------------------------------
void Write_A_Byte_TO_DS1302(uchar x)
uchar LCD_DSY_BUFFER1[]={"DATE 00-00-00 "};
uchar LCD_DSY_BUFFER2[]={"TIME 00:00:00 "};
uchar DateTime[7];
void Initialize_LCD();
void Display_LCD_String(uchar p,uchar *s);
SCLK=1; //将时钟电平置于已知状态
RST=0;//禁止数据传递
return dat;
}
//------------------------------------------------------------------
//函数名称:GetTime()
//函数功能:读取当前日期时间,将秒、分钟、小时、日期、月份、周日、年份七个数值分//别存入数组DateTime[0]~DateTime[6]
void Format_DataTime(uchar d,uchar *a)
{
a[0]=d/10+'0';
a[1]=d%10+'0';
}
//------------------------------------------------------------------
//主程序
//------------------------------------------------------------------
}
}
//------------------------------------------------------------------
//函数名称:Get_A_Byte_FROM_DS1302()
//函数功能:从DS1302读取一个字节
//输入参数:无
//返回值:读取的数据
//时序原理:在紧跟8位的控制指令字后的下一个SCLK时钟的下降沿时读出DS1302的数据,读出数据时从低位0位到高位7
//注意:DS1302中所存放的数据是BCD码,在读写时要注意转换
//例如:00011000,当把它视为二进制数时,其值为24;但作为2位BCD码时,其值为18。
//------------------------------------------------------------------
uchar Get_A_Byte_FROM_DS1302()
//0x8B周日寄存器
Format_DataTime(DateTime[2],LCD_DSY_BUFFER2+5); //0x85小时寄存器
Format_DataTime(DateTime[1],LCD_DSY_BUFFER2+8); //0x83分钟寄存器
Format_DataTime(DateTime[0],LCD_DSY_BUFFER2+11); //0x81秒寄存器
void DelayMS(uint ms);
//------------------------------------------------------------------
//函数名称:Write_A_Byte_TO_DS1302(uchar x)
//函数功能:向DS1302写入一个字节
//输入参数:x将要写入的数据
//说明:从DS1302中读取时钟数据,在LCD上显示日期和时间
//------------------------------------------------------------------
#include <reg51.h>
#include <intrins.h>
#include <string.h>
Format_DataTime(DateTime[3],LCD_DSY_BUFFER1+11);//0x87日期寄存器
//星期
strcpy (LCD_DSY_BUFFER1+13,WEEK[DateTime[5]]);//将字符串WEEK[DateTime[5]]复制到字符数组LCD_DSY_BUFFER1+13中
{
uchar i;
SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备
for (i=0;i<8;i++)
{
IO=x & 0x01; //取出x的第0位数据写入1302
SCLK=1;//上升沿写入数据
SCLK=0;//重新拉低SCLK,形成脉冲
x >>=1;//将x的各数据位右移1位,准备写入下一个数据位
void main()
{
Initialize_LCD();
while(1)
{
GetTime();
Format_DataTime(DateTime[6],LCD_DSY_BUFFER1+5);//0x8D年份寄存器
Format_DataTime(DateTime[4],LCD_DSY_BUFFER1+8);//0x89月份寄存器
{
uchar i,b=0x00;
for (i=0;i<8;i++)
{
b |= _crol_((uchar)IO,i);//将uchar类型的IO数据左移i位
SCLK=1; //将SCLK置于高电平,为下降沿读出
SCLK=0; //时钟下降沿读取
}
return (b/16)*10+b%16; //从二进制数返回BCD码
//注意:1.本例中DS1302的属性设置为:自动根据PC的时间初始化。
//可以编程写入某个自定的初始时间,然后由该时间开始显示时钟。
//
//
//--------------------------------------------------------
//输入参数:无
//返回值:无
//------------------------------------------------------------------
void GetTime()
{
uchar i,addr =0x81;
for (i=0;i<7;i++)