Ⅰ ds1302怎么接单片机
DS1302芯片与51单片机的连接
DS1302电路图
X1、X2:32.768KHz晶振接入引脚。(15分频1HZ——1S定时,时钟通用晶振)
GND:接地。
RET :复位引脚,低电平有效,操作时高电平。
I/O:数据输入/输出引脚,具有三态功能。
SCLK:串行时钟输入引脚。
Vcc1:工作电源引脚。
Vcc2:备用电源引脚。
Ⅱ 单片机中的DS1302编程时,它的读、写底层函数是干什么用的,DS1302的初始化又是做什么的
#include "ds1302.h"
void delaynus(unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++);
}
void Write1302(unsigned char dat)
{
unsigned char i;
SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备
delaynus(2); //稍微等待,使硬件做好准备
for(i=0;i<8;i++) //连续写8个二进制位数据
{ DATA=dat&0x01; //取出dat的第0位数据写入1302 低位在前,高位在后
delaynus(2); //稍微等待,使硬件做好准备
SCLK=1; //上升沿写入数据
delaynus(2); //稍微等待,使硬件做好准备
SCLK=0; //重新拉低SCLK,形成脉冲
dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位
} }
void WriteSet1302(unsigned char Cmd,unsigned char dat)
{
RST=0; //禁止数据传递
SCLK=0; //确保写数居前SCLK被拉低
RST=1; //启动数据传输
delaynus(2); //稍微等待,使硬件做好准备
Write1302(Cmd); //写入命令字
Write1302(dat); //写数据
SCLK=1; //将时钟电平置于高电平状态
RST=0; //禁止数据传递
}
unsigned char Read1302(void)
{
unsigned char i,dat;
delaynus(2); //稍微等待,使硬件做好准备
for(i=0;i<8;i++) //连续读8个二进制位数据
{ dat>>=1;
if(DATA==1) //如果读出的数据是1
dat|=0x80; //将1取出,写在dat的最高位
SCLK=1; //将SCLK置于高电平,为下降沿读出
delaynus(2); //稍微等待
SCLK=0; //拉低SCLK,形成脉冲下降沿
delaynus(2); //稍微等待
}
return dat; //将读出的数据返回
}
unsigned char ReadSet1302(unsigned char Cmd)
{
unsigned char dat;
RST=0; //拉低RST
SCLK=0; //确保写数居前SCLK被拉低
RST=1; //启动数据传输
Write1302(Cmd); //写入命令字
dat=Read1302(); //读出数据
SCLK=1; //将时钟电平置于已知状态
RST=0; //禁止数据传递
return dat; //将读出的数据返回
}
void Init_DS1302(void)
{
unsigned char flag;
flag= ReadSet1302(0x81);
if(flag&0x80) //判断时钟芯片是否关闭
{ WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令
WriteSet1302(0x80,((55/10)<<4|(55%10))); //根据写秒寄存器命令字,写入秒的初始值
WriteSet1302(0x82,((59/10)<<4|(59%10))); //根据写分寄存器命令字,写入分的初始值
WriteSet1302(0x84,((23/10)<<4|(23%10))); //根据写小时寄存器命令字,写入小时的初始值
WriteSet1302(0x86,((18/10)<<4|(18%10))); //根据写日寄存器命令字,写入日的初始值
WriteSet1302(0x88,((6/10)<<4|(6%10))); //根据写月寄存器命令字,写入月的初始值
WriteSet1302(0x8c,((9/10)<<4|(9%10))); //根据写年寄存器命令字,写入年的初始值
WriteSet1302(0x90,0xa5); //打开充电功能 选择2K电阻充电方式
WriteSet1302(0x8E,0x80); //根据写状态寄存器命令字,写入保护指令
}
}
Ⅲ 基于51单片机的数字时钟为什么用DS1302
你使用这样的电路可以,前提是不掉电的情况下,而且精确度有待商榷,如果使用DS1302,内置时间寄存器,并可对时间进行校正,同时,如果对其加电池,那么时间不会停止,一直走动,否则,按您的电路,你一关电,所有的时间你得重新设置。希望您明白我的意思。
Ⅳ 单片机和ds1302各自都怎么工作
ds1302是时钟芯片 主要是计算年、月、日和星期的,上电后他就自动计时,从他的初始时间开始计时。单片机就是负责去1302的相应寄存器中读取时间和改写时间(就是可以通过按键程序来设定时间),之后再负责显示出来。
Ⅳ ds1302时钟芯片工作原理
DS1302结构与工作原理
DS1302 是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟,有计时的作用,和日常接触的电子表,万年历差不多,可以对年月日、时分秒、星期计时。可以用单片机往DS1302里面写入时间进行时间设置,也可以用单片机从DS1302中读取时间,读出来的时间也可以放在液晶上显示。这样就可以实现一块电子表的功能了。
DS1302引脚及功能:
X1,X2: 振荡源管脚,外接32.768KHz晶振
GND: 地
RST: 复位/片选线(通过置高电平来启动所有的数据传送。)
IO: 数据输入输出
SCLK: 串行时钟
VCC1: 电池引脚
VCC2: 主电源引脚 (双电源供电,在主电源关闭的情况下,有VCC1的电池供电,也能保持时钟的连续运行)
DS1302的工作原理很简单,它外接32768Hz的晶振提供震荡时钟。芯片内部的电路对晶振频率32768分频后获得周期为1S的秒信号,然后对秒信号计数,获得分钟、小时、天、星期、月、年等的数值。
实现方法:
DS1302的时间信息以寄存器的形式存储在芯片内部。DS1302的通讯接口由3根线组成,即RST,SCLK,I/O。单片机与DS1302通讯,采用的是SPI通讯接口,只不过是半双工了,只能分时进行收发。通过SPI接口,对相应的寄存器进行读操作,可以获得当前时间数值;写操作,可以设定当前时间。
下面介绍怎么对DS1302发号施令。
DS1302的命令字节格式:
一个完整的通讯帧由由2字节组成。第一字节是控制字节,第二字节为数据位。控制字格式如下:
1.bit0:读写标志。高电平为读,第二字节(蓝色圈内)会由DS1302输出数据;低电平为写,第二字节由单片机输出数据, DS1302接收;
2.bit1~5: 5位操作元地址,就是要对哪个寄存器进行操作。寄存器地址列表如图2.1。(红色圈内)
3.bit6:选择RAM区或寄存器区。如果为0,则表示存取日历时钟数据,为1表示存取RAM数据;
4. bit7:必须是逻辑1,如果它为0,则不能把数据写入DS1302中。
图2.1
(CH:时钟停止位;为0时振荡器工作;为1时振荡器停止;AP=1时为下午模式,为0时上午模式。图2.1内还应该有第八个寄存器,地址为8E。它的bit7是需要重视的。bit7是一个保护位,如果这一位是1,那么是禁止给任何其他的寄存器或者那31个字节的RAM写数据的。因此在写数据之前,这一位必须先写成0。)
因为是SPI接口,单片机与DS1302通讯也是上升沿发送(写入1302数据),下降沿接收(读取1302数据)。控制字总是从最低位开始输出。在控制字指令输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从最低位(0位)开始。同样,在紧跟8位的控制字指令后的下一个SCLK脉冲的下降沿,读出DS1302的数据。读出的数据也是从最低位到最高位。数据读写时序如下图:
Ⅵ 单片机 DS1302
/********************************************************************
*
* 名称: DS1302_InputByte()
* 功能: 往DS1302写入1Byte数据
* 输入: ucDa 写入的数据
***********************************************************************/
void DS1302_InputByte(unsigned char ucDa)
{
unsigned char i;
unsigned char temp;
temp = ucDa;
for(i=8; i>0; i--)
{
T_IO = temp&0x01;
T_CLK = 1;
T_CLK = 0;
temp = temp >> 1;
}
}
/********************************************************************
*
* 名称: DS1302_OutputByte()
* 功能: 从DS1302读取1Byte数据
***********************************************************************/
unsigned char DS1302_OutputByte(void)
{
unsigned char i;
unsigned char temp;
temp=0;
for(i=0; i<8;i++)
{
T_CLK = 0;
if(T_IO!=0) temp|=(1<<i);
T_CLK = 1;
}
return(temp);
}
/********************************************************************
*
* 名称: DS1302_InputByte()
* 说明: 先写地址,后写命令/数据
* 功能: 往DS1302写入数据
* 输入: ucAddr: DS1302地址, ucDa: 要写的数据
***********************************************************************/
void DS1302_W1302(unsigned char ucAddr, unsigned char ucDa)
{
T_RST = 0;
T_CLK = 0;
T_RST = 1;
DS1302_InputByte(ucAddr); /* 地址,命令 */
DS1302_InputByte(ucDa); /* 写1Byte数据*/
T_CLK = 1;
T_RST =0;
}
/********************************************************************
*
* 名称: DS1302_R1302()
* 说明: 先写地址,后读命令/数据
* 功能: 读取DS1302某地址的数据
* 输入: ucAddr: DS1302地址
***********************************************************************/
unsigned char DS1302_R1302(unsigned char ucAddr)
{
unsigned char ucDa;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
DS1302_InputByte(ucAddr); /* 地址,命令 */
ucDa = DS1302_OutputByte(); /* 读1Byte数据 */
T_CLK = 1;
T_RST =0;
return(ucDa);
}
/********************************************************************
*
* 名称: DS1302_Get1302()
* 说明:
* 功能: 读取DS1302当前时间
* 调用: DS1302_R1302()
* 输入: ucCurtime: 保存当前时间地址。当前时间格式为: 秒 分 时 日 月 星期 年
***********************************************************************/
void DS1302_Get1302(unsigned char ucCurtime[])
{
unsigned char i;
unsigned char ucAddr = 0x81;
for (i=0;i<7;i++)
{
ucCurtime[i] = DS1302_R1302(ucAddr);/*格式为: 秒 分 时 日 月 星期 年 */
ucAddr += 2;
}
}
void delay(uint i)
{
uint k;
while(i--)
{
for(k=0;k<120;k++){;}
}
}
/********************************************************************
* 名称: DS1302_Set1302()
* 功能: 设置时间
初始时间格式为: 秒 分 时 日 月 星期 年
***********************************************************************/
void DS1302_Set1302(void) interrupt 0
{
uchar b[7];
uchar *p;
uint k;
unsigned char Addr = 0x80;
DS1302_Get1302(b);
p=b;
DS1302_W1302(0x8e,0x00); /* 控制命令,WP=0,允许写操作*/
while(k4==1)
{
if(k1==0)
{
delay(10);
while(k1==0);
p++;
}
else if(k2==0)
{
delay(10);
while(k2==0);
*p=*p++;
}
else if(k3==0)
{
delay(10);
while(k3==0);
*p=*p--;
}
if(*p=='\0')
p=b;
}
p=b;
for(k =7;k>0;k--)
{
DS1302_W1302(Addr,*p); /* 秒 分 时 日 月 星期 年 */
p++;
Addr +=2;
}
DS1302_W1302(0x8e,0x80); /* 控制命令,WP=1,写保护*/
}
用这个驱动试试。如果不行就是你数码管出问题了
Ⅶ 既然单片机本身有定时器,为什么还需要采用DS1302来定时呢,DS1302的优点是什么呢
单片机的定时器用的是它自己的晶振,不是专门用来做电子钟的,因其精度不高,而且操作麻烦!而且更正一点,DS1302不是用来定时的,它是一种时钟芯片,内部有专用的寄存器用于存年月日时分秒,用的晶振也是另接的,高精度。当秒改变到一定量是,分会自动加一,写程序比较简单,而单片机要写程序让它加一。
Ⅷ 51单片机 外接DS1302
一个是单片机外接晶体,提供单片机工作频率用,多是4M-20M的频率。
一个专门的时钟芯片DS1302专用外接晶体,这种晶体都比较准确稳定,来减少时钟误差。。
DS1302专用晶体频率是32.768kHz,无法和单片机晶体通用。
Ⅸ 51单片机中DS1302芯片的引脚配置原理是什么
CE和SCLK是DS1302芯片的信号线,但也是与单片机的PIO口连接的;
因此初始化CE和SCLK,也就是初始化单片机的PIO口了;
在代码中,你可以去看看 DS1302_CE、DS1302_SCLK 的定义就明白了;
Ⅹ 单片机 DS1302时钟读写问题
uchar read_Byte()
{
uchar i;
for(i = 8;i > 0;i--)
{
ACC = ACC >> 1;
ACC7 = ds1302_IO;
ds1302_SCLK = 1;
ds1302_SCLK = 0;
}
return(ACC);
}
是的,你要相信自己,然后多实践,网上的东西只做一个参考,对不对还要由你自己来验证。