51单片机驱动DS1302学习笔记
程序员文章站
2022-06-24 18:57:18
DS1302简介DS1302是DALLAS(达拉斯)公司出的一款涓流充电时钟芯片,2001年DALLAS被MAXIM(美信)收购,因此我们看到的DS1302的数据手册既有DALLAS的标志,又有MAXIM的标志;DS1302实时时钟芯片广泛应用于电话、传真、便携式仪器等产品领域,他的主要性能指标如下:1、DS1302是一个实时时钟芯片,可以提供秒、分、小时、日期、月、年等信息,并且还有软年自动调整的能力,可以通过配置AM/PM来决定采用24小时格式还是12小时格式。2、拥有31字节数据存储RAM。...
DS1302简介
DS1302是DALLAS(达拉斯)公司出的一款涓流充电时钟芯片,2001年DALLAS被MAXIM(美信)收购,因此我们看到的DS1302的数据手册既有DALLAS的标志,又有MAXIM的标志;
DS1302实时时钟芯片广泛应用于电话、传真、便携式仪器等产品领域,他的主要性能指标如下:
1、DS1302是一个实时时钟芯片,可以提供秒、分、小时、日期、月、年等信息,并且还有软年自动调整的能力,可以通过配置AM/PM来决定采用24小时格式还是12小时格式。
2、拥有31字节数据存储RAM。
3、串行I/O通信方式,相对并行来说比较节省IO口的使用。
4、DS1302的工作电压比较宽,大概是2.0V~5.5V都可以正常工作。采用双电源供电,当主电源比备用电源高0.2V时,由主电源供电,否则采用备用电源,一般是一个纽扣电池。
5、DS1302这种时钟芯片功耗一般都很低,它在工作电压2.0V的时候,工作电流小于300nA。
6、DS1302共有8个引脚,有两种封装形式,一种是DIP-8封装,芯片宽度(不含引脚)是300mil,一种是SOP-8封装,有两种宽度,一种是150mil,一种是208mil。
1、DS1302的引脚图
读写时序图
根据其时序图来编写其驱动
写数据的驱动
注:sfr(Special Function Register特殊功能寄存器的缩写),sbit(特殊功能寄存器位),
void DS1302InputByte(unsigned char d)
{
//ACC 为 sfr ACC = 0xE0; 芯片内部的寄存器
//ACC0 sbit ACC0 = ACC^0; 取第一位数据
unsigned char i;
ACC = d;
DS1302_CLK = 0; //先拉低时钟
for(i=8; i>0; i--)
{
DS1302_IO = ACC0; //将发送的位写入IO引脚
DS1302_CLK = 1; //上拉时钟引脚,形成高电平
nop(); //小延时
DS1302_CLK = 0; //拉低时钟
nop();//小延时
ACC = ACC >> 1; //数据位右移
}
}
读数据驱动程序
//从时序图可以看出,写入地址之后,下降沿就可以读出数据
unsigned char DS1302OutputByte(void)
{
unsigned char i;
DS1302_CLK = 0;
for(i=8; i>0; i--)
{
ACC = ACC >>1;
ACC7 = DS1302_IO;
DS1302_CLK = 1;
DS1302_CLK = 0;
}
return(ACC);
}
基于上面两个函数,就可以得到
void Write1302(unsigned char ucAddr, unsigned char ucDa)//往一个地址写一个数据
{
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte((ucAddr|0x80)&0xFE); // 写地址 第7比特为为0,表示写
DS1302InputByte(ucDa); // 写数据
DS1302_CLK = 1;
DS1302_RST = 0;
}
unsigned char Read1302(unsigned char ucAddr) //指定一个地址读取数据
{
unsigned char ucData;
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr|0x81); // 写地址 第7比特为为1,表示读
ucData = DS1302OutputByte(); // 读出数据
DS1302_CLK = 1;
DS1302_RST = 0;
return(ucData);
}
DS1302命令如下:
#define AM(X) X
#define PM(X) (X+12)
#define DS1302_SECOND 0x80
#define DS1302_MINUTE 0x82
#define DS1302_HOUR 0x84
#define DS1302_WEEK 0x8A
#define DS1302_DAY 0x86
#define DS1302_MONTH 0x88
#define DS1302_YEAR 0x8C
#define DS1302_RAM(X) (0xC0+(X)*2)
typedef struct __SYSTEMTIME__
{
unsigned char Second;
unsigned char Minute;
unsigned char Hour;
unsigned char Week;
unsigned char Day;
unsigned char Month;
unsigned char Year;
unsigned char DateString[9];
unsigned char TimeString[9];
}SYSTEMTIME; //结构体
获取时间函数
void DS1302_GetTime(SYSTEMTIME *Time)
{
unsigned char ReadValue;
ReadValue = Read1302(DS1302_SECOND);
Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_MINUTE);
Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_HOUR);
Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_DAY);
Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_WEEK);
Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_MONTH);
Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_YEAR);
Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
}
初始化函数
void Initial_DS1302(void)
{
unsigned char Second=Read1302(DS1302_SECOND); //如果CH位是0的话,那就进行时间复位
if((Second& 0x80 != 0)){
ds1302_writedata(0X8E,0x00); //撤销写保护,允许写入数据
for(i = 0;i<7;i++){
ds1302_writedata(i,init_time[i]);
}
}
}
本文地址:https://blog.csdn.net/LiJinGang6/article/details/109261206