DS1302结构原理图
DS1302涓流充电计时芯片实时时钟/日历和31字节的静态RAM,通过IO口与微机处理器通讯,该实时时钟/日历提供年月日和时分秒星期,还具备月份闰平年自动校正。其信息与外部的传输由CE、I/O和SCLk(串行时钟)决定。
51单片机中的DS1302模块
注:51单片机中的DS1302模块无备用电源,断电就停止运行,上电便开始运行,复位操作不会影响时钟的运行。
工作原理:
工作时序图
CE:读写使能开关,不论对DS1302进行读或写操作都需要将CE置1,若CE置0则相应的读写操作都无效
SCLK:时钟脉冲串
IO:前八位是对读写模式的选择和读写地址的配置(年月日,时分秒,星期都对应不同的地址),其触发方式为上升沿触发,即SCLK由0变为1时触发。
上图圈内左列自上往下对应的分别对应秒、分、时、日、月、星期、年和读保护,其对应的模式为从DS1302中读出相应数据并送至IO口。右列自上往下对应的分别对应秒、分、时、日、月、星期、年和写保护,其对应的模式为将IO口中的数据写入DS1302中,相当于设置DS1302的初始值。当读写保护开启(置1)时,数据无法写入DS1302或无法从DS1302中读出数据,即若要对相应数据进行操作就得关闭读写保护(令其为0x00)。
后八位(BT0~BT7)为数据位,当为单字节读时其触发方式为下降沿触发,即SCLK由1变为0时触发,当为单字节写时其触发方式为上升沿触发,即SCLK由0变为1时触发。需要注意的是该字节数据为两位BDS编码(两位BDS编码说明DS1302只能输出两位数,最大为99,若要显示年份只能显示后两位),即八个字节被分为前后各四个,前四个表示十位,后四个表示个位,当个位二进制对应的值等于10时需要向前四位进1,即前后四位最大值为均1001。例如 当 0000 1001(十进制为9)加一后变为 0001 0000,0001 0000 在十进制中表示16,但在BDS码中其表示10。 当我们需要写入的数据为十进制时需要先将该数据转为BDS码,再将对应的BDS码写入DS1302,当我们从DS1302中读出数据时得先将数据转化为十进制再进行相应操作,否则我们将无法得到预期数据。
BSD转十进制:DS1302直接读取值/16*10 + DS1302直接读取值%16
十进制转BDS:十进制数值/10*16 + 十进制数值%10文章来源:https://www.toymoban.com/news/detail-450000.html
例如:DS1302模块代码文章来源地址https://www.toymoban.com/news/detail-450000.html
#include <regx52.h>
sbit DS1302_SCLK=P3^6;
sbit DS1302_IO=P3^4;
sbit DS1302_CE=P3^5;
#define DS1302_WSec 0x80 //写秒 注:宏定义末尾不加分号!!!!!
#define DS1302_WMin 0x82 //写分
#define DS1302_WHou 0x84 //写时
#define DS1302_WDat 0x86 //写日
#define DS1302_WMon 0x88 //写月
#define DS1302_WYea 0x8C //写年
#define DS1302_WDay 0x8A //写星期
#define DS1302_WP 0x8E //写保护
#define DS1302_RSec 0x81 //读秒
#define DS1302_RMin 0x83 //读分
#define DS1302_RHou 0x85 //读时
#define DS1302_RDat 0x87 //读日
#define DS1302_RMon 0x89 //读月
#define DS1302_RYea 0x8D //读年
#define DS1302_RDay 0x8B //读星期
unsigned int DS1302_Time[]={23,1,31,6,20,45,4};
void DS1302_Init()
{
DS1302_CE=0;
DS1302_SCLK=0;
}
void DS1302_WriteByte(unsigned char command,date) //command用于配置DS1302,选择读或写,并指明位置,date为写入指定位置的值
{
unsigned char i;
DS1302_CE=1; //使单片机能够对DS1302芯片进行读写操作
for(i=0;i<8;i++) //将command通过移位寄存器送入DS1302
{
DS1302_IO=command&(0x01<<i);
DS1302_SCLK=1; //触发上升沿,将IO上的值写入DS1302
DS1302_SCLK=0; //将DS1302_SCLK置0,以便下次触发上升沿
}
for(i=0;i<8;i++) //按照配置DS1302的方法,将要写入的数据送入DS1302的指定地址
{
DS1302_IO=date&(0x01<<i);
DS1302_SCLK=1;
DS1302_SCLK=0;
}
DS1302_CE=0; //写入完毕后,关闭使能开关
}
unsigned char DS1302_ReadByte(unsigned char command) //输入读取数据的指令后返回读取到的数据
{
unsigned char i,date=0x00; //全局变量默认初始值为0,但局部变量默认初始值不一定为0,因此需要将date先初始时化,由于承接的是一个8为二进制数,所以初始化为0x00;
DS1302_CE=1;
for(i=0;i<8;i++)
{
DS1302_IO=command&(0x01<<i);
DS1302_SCLK=1;
if(i<7) //第8次触发上升沿后先不将DS1302置0,因为触发下降沿后便会将指定地址的数据送至IO口
{
DS1302_SCLK=0;
}
}
for(i=0;i<8;i++)
{
DS1302_SCLK=0; //触发下降沿,将指定地址的数据送至IO口
if(i<7)
{
DS1302_SCLK=1; //第8触发下降沿后不用将DS1302_SCLK置1,让其回到初始位置
}
if(DS1302_IO) //如果IO口输出的数为1
{
date=date>>1; //则将date右移1位后,把date的最高位置1
date|=0x80;
}
else //若IO口输出的数位0
{
date=date>>1; //则只需将date右移一位
}
}
DS1302_IO=0; //将IO口置0,起到初始化作用
DS1302_CE=0; //关闭使能开关
return date; //返回date
}
void DS1302_SetTime() //数组内的值,写入DS1302对应地址,相当于为时钟设置初始值
{
DS1302_WriteByte(DS1302_WP,0x00); //关闭DS1302写保护
DS1302_WriteByte(DS1302_WYea,DS1302_Time[0]/10*16+DS1302_Time[0]%10); //设置年初始值DS1302_Time[0]
DS1302_WriteByte(DS1302_WMon,DS1302_Time[1]/10*16+DS1302_Time[1]%10); //设置月初始值DS1302_Time[1]
DS1302_WriteByte(DS1302_WDat,DS1302_Time[2]/10*16+DS1302_Time[2]%10); //设置日初始值DS1302_Time[2]
DS1302_WriteByte(DS1302_WHou,DS1302_Time[3]/10*16+DS1302_Time[3]%10); //设置时初始值DS1302_Time[3]
DS1302_WriteByte(DS1302_WMin,DS1302_Time[4]/10*16+DS1302_Time[4]%10); //设置分初始值DS1302_Time[4]
DS1302_WriteByte(DS1302_WSec,DS1302_Time[5]/10*16+DS1302_Time[5]%10); //设置秒初始值DS1302_Time[5]
DS1302_WriteByte(DS1302_WDay,DS1302_Time[6]/10*16+DS1302_Time[6]%10); //设置星期初始值DS1302_Time[6]
DS1302_WriteByte(DS1302_WP,0x80); //打开DS1302写保护
}
void DS1302_ReadTime(void) //将DS1302中的年月日时分秒星期读出并存入数组DS1302_Time[],访问数组即可得到相应时间值
{
unsigned char Temp;
Temp=DS1302_ReadByte(DS1302_RYea); //读出DS1302中的年
DS1302_Time[0]=Temp/16*10+Temp%16; //将读出的年存入数组
Temp=DS1302_ReadByte(DS1302_RMon);
DS1302_Time[1]=Temp/16*10+Temp%16;
Temp=DS1302_ReadByte(DS1302_RDat);
DS1302_Time[2]=Temp/16*10+Temp%16;
Temp=DS1302_ReadByte(DS1302_RHou);
DS1302_Time[3]=Temp/16*10+Temp%16;
Temp=DS1302_ReadByte(DS1302_RMin);
DS1302_Time[4]=Temp/16*10+Temp%16;
Temp=DS1302_ReadByte(DS1302_RSec);
DS1302_Time[5]=Temp/16*10+Temp%16;
Temp=DS1302_ReadByte(DS1302_RDay);
DS1302_Time[6]=Temp/16*10+Temp%16;
}
到了这里,关于DS1302时钟模块的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!