基于STM32F103C6T6的DS1302模块使用
目录
1.概述
2.硬件引脚图
3.模块图
二、直奔程序
1.DS1302的时钟寄存器
2.DS1302的通讯时序
写时序:
读时序:
3.DS1302的初始时间设定
4.读取时间
一、DS1302简介(简单看看)
1.概述
DS1302 是DALLAS 公司推出的涓流充电时钟芯片内含有一个实时时钟/日历和31 字节静态RAM 通过简单的串行接口与单片机进行通信实时时钟/日历电路提供秒分时日日期月年的信息每月的天数和闰年的天数可自动调整时钟操作可通过AM/PM 指示决定采用24 或12 小时格式DS1302 与单片机之间能简单地采用同步串行的方式进行通信仅需用到三个口线1 RES 复位2 I/O 数据线3 SCLK串行时钟时钟/RAM 的读/写数据以一个字节或多达31 个字节的字符组方式通信DS1302 工作时功耗很低保持数据和时钟信息时功率小于1mW
DS1302 是由DS1202 改进而来增加了以下的特性双电源管脚用于主电源和备份电源供应Vcc1 为可编程涓流充电电源附加七个字节存储器它广泛应用于电话传真便携式仪器以及电池供电的仪器仪表等
产品领域下面将主要的性能指标作一综合
实时时钟具有能计算2100 年之前的秒分时日日期星期月年的能力还有闰年调整的能力
31 8 位暂存数据存储RAM
串行 I/O 口方式使得管脚数量最少
宽范围工作电压2.0 5.5V
工作电流 2.0V 时,小于300nA
读/写时钟或RAM 数据时有两种传送方式单字节传送和多字节传送字符组方式
8 脚DIP 封装或可选的8 脚SOIC 封装根据表面装配
简单 3 线接口
与 TTL 兼容Vcc=5V
可选工业级温度范围-40 +85
与 DS1202 兼容
在 DS1202 基础上增加的特性
对Vcc1 有可选的涓流充电能力双电源管用于主电源和备份电源供应备份电源管脚可由电池或大容量电容输入附加的7 字节暂存存储器。
2.硬件引脚图
3.模块图
本文使用的事带电池模块
二、直奔程序
1.DS1302的时钟寄存器
首先先介绍下DS1302的时钟寄存器,DS1302简单的说就是时钟,开启后就会自己运行,然后我们用单片机去读一下时间就行,而时间就存在DS1302的寄存器中。这里主要介绍用到的寄存器分别是:秒-分-时-日-月-星期-年-写保护寄存器。如下图所示:
秒寄存器:CH的意思是时钟停止位,如果写1就停止时钟即DS1302停止计时,写0则开启时钟。也可以通过读取这位来判断DS1302是否在运行。这里是10seconds的意思是秒的十位,如图读上来的值是0x36,那么这个3就是十位,6是各位,那么时间就是36s,使用的时候需要转换一下:转换公式如下 :0x36/16*10+0x36%16。16的意思是右移4位。
分寄存器:和秒差不多,少了个CH位而已。
时寄存器:bit7 是 1 的话代表是 12 小时制,0 代表是 24 小时制;bit6 固定是 0,bit5 在 12 小时制下 0 代表的是上午,1 代表的是下午,在 24 小时制下和 bit4 一起代表了小时的十 位,低 4 位代表的是小时的个位。
日/月/星期/年寄存器:和分寄存器一样,个位值是低4位。
2.DS1302的通讯时序
写时序:
类似I2C一样,先写地址,然后写数据,低位先行 。在CLK上升沿的时候将DS1302采集I/O的数据。所以通过时序图简单写个写数据的程序:
#define DS1302CS PAout(2)//位带操作 CS使能线
#define DS1302DAT PAout(1)//数据线
#define DS1302CLK PAout(0)//时钟线
#define DAT_IO GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)//读取数据线的信号
void DS1302WriteCommand(uint8_t command,uint8_t data)
{
uint8_t i;
DS1302CS=0;
DS1302CLK=0;
DS1302CS=1; //CS给个上升沿,让DS1302使能
for(i=0;i<8;i++)//先写命令
{
DS1302CLK=0;
DS1302DAT=((command>>i)&0x01);//每次将最低位写入
DS1302CLK=1;
}
for(i=0;i<8;i++)//数据
{
DS1302CLK=0;
DS1302DAT=((data>>i)&0x01);
DS1302CLK=1;
}
DS1302CS=0;
}
读时序:
读的话需要先写寄存器地址,写完后DS1302会控制数据线 ,此时需要将数据线的模式改为输入模式。与写时序不同,读的话前8位是上升沿DS1302读取数据线数据,但是将这8位发完后,DS1302会立刻在CLK的下降沿把数据发出来。简单读程序如下:
uint8_t DS1302ReadData(uint8_t command)
{
uint8_t i;
uint8_t returndata=0x00;
DS1302CS=0;
DS1302CLK=0;
DS1302CS=1; //CS上升沿 DS1302运行
GPIOChange(1);//这个是改数据线的GPIO配置,1为将模式改为腿玩输出 0改为上来输入
for(i=0;i<8;i++)
{
DS1302CLK=0;
DS1302DAT=((command>>i)&0x01);
DS1302CLK=1;
}
GPIOChange(0);//这个是改数据线的配置,1为将模式改为腿玩输出 0改为上来输入
for(i=0;i<8;i++)
{
DS1302CLK=0;
returndata=returndata>>1;
if(DAT_IO)//定义在前面写时序那
returndata |=0x80;
DS1302CLK=1;
}
DS1302CS=0;//记得拉低
return returndata;//如果需要使用数据的进行打印的话 需要转化为十进制
}
/*********************************************/
/**************更改GPIO配置*******************/
void GPIOChange(uint8_t flag)//1写0读
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
if(flag)
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
else
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
3.DS1302的初始时间设定
第一次运行的时候先设定个时间,设定好之后后面就不需要再次设定了,所以设定一次就够。设定程序如下:
int main(void)
{
delay_init(); //延时函数初始化
DS1302GPIO_Init(); //初始化与LED连接的硬件接口
DS1302WriteCommand(0x8E,0x00);//写使能
DS1302WriteCommand(0x80,0x00);//设置0s
DS1302WriteCommand(0x82,0x50);//设置0分
DS1302WriteCommand(0x84,0x13);//设置13时
DS1302WriteCommand(0x86,0x31);//设置日期31号
DS1302WriteCommand(0x88,0x10);//设置12月
DS1302WriteCommand(0x8C,0x23);//设置23年
DS1302WriteCommand(0x8E,0x80);//关闭写功能
while(1)
{
}
}
4.读取时间
设置完成时间后就将设置时间的函数屏蔽掉(不屏蔽的话每次上电运行都会重新设定时间,所以设定完成后就别在设定了),然后在while里面不断的获取时间,程序如下:
int main(void)
{
delay_init(); //延时函数初始化
DS1302GPIO_Init(); //初始化与LED连接的硬件接口
/* DS1302WriteCommand(0x8E,0x00);//写使能
DS1302WriteCommand(0x80,0x00);//设置0s
DS1302WriteCommand(0x82,0x50);//设置50分
DS1302WriteCommand(0x84,0x13);//设置13时
DS1302WriteCommand(0x86,0x31);//设置日期31号
DS1302WriteCommand(0x88,0x10);//设置12月
DS1302WriteCommand(0x8C,0x23);//设置23年
DS1302WriteCommand(0x8E,0x80);//关闭写功能*/
while(1)
{
date[0]=DS1302ReadData(0x8D);//年
date[1]=DS1302ReadData(0x89);//月
date[2]=DS1302ReadData(0x87);//日
date[3]=DS1302ReadData(0x85);//时
date[4]=DS1302ReadData(0x83);//分
date[5]=DS1302ReadData(0x81);//秒
}
}
通过keil仿真显示时间视频如下:
DS1302读取时间
通过仿真后可以看出,秒在不断的加1,经过测试后我这快芯片每2个小时会快1秒。
好家伙!53: 链接里面的代码没有注释哩up主
Eden yu: 那你要对比一下哪里不一样了
qq_41726253: 你的可以驱动吗?我的不行
Eden yu: 显示函数一节,显示函数名未写,各位copy时记得自己加上去
CSDN-Ada助手: 恭喜您写了第8篇博客!标题《基于STM32F103C6T6的DS1302模块使用》非常吸引人。通过您的博客,我学到了如何使用这款模块。您的文章非常详细,对于初学者来说非常友好。希望您能继续分享更多关于STM32开发的经验和技巧。 在下一篇博客中,我建议您可以深入探讨DS1302模块的更多功能和应用场景。您可以介绍一些实际项目中使用该模块的案例,或是分享一些高级功能的编程技巧。我相信您的经验和知识一定能够帮助更多的读者解决问题。 再次感谢您的分享,期待您的下一篇博客!