视频讲解
简介
DS1302 可慢速充电实时时钟芯片包含实时时钟/日历和31字节的非易失性静态RAM。它经过一个简单的串行接口与微处理器通信。实时时钟/日历可对秒,分,时,日,周,月,和年进行计数,对于小于31 天的月,月末的日期自动进行调整,还具有闰年校正的功能。
时钟可以采用24小时格式或带AM(上午)/PM(下午)的12小时格式。31字节的RAM可以用来临时保存一些重要数据。使用同步串行通信,简化了DS1302与微处理器的通信。与时钟/RAM通信仅需3根线:(1)RST(复位),(2)I/O(数据线)和(3)SCLK(串行时钟)。数据可以以每次一个字节的单字节形式或多达31字节的多字节形式传输。DS1302能在非常低的功耗下工作,消耗小于1µW的功率便能保存数据和时钟信息
软件流程图
DS1302读一个字节
DS1302写一个字节
程序分析
ds1302.c
/**********************************
作者:特纳斯电子
网站:https://www.mcude.com
联系方式:46580829(QQ)
淘宝店铺:特纳斯电子
**********************************/
/**********************************
包含头文件
**********************************/
#include "ds1302.h"
/**********************************
变量定义
**********************************/
char time_buf[8] = {0x20,0x24,0x12,0x04,0x11,0x42,0x00,0x03};//初始时间2020年12月6号14点53分00秒 星期日
/****
*******向DS1302写入一字节数据
*****/
void ds1302_write_byte(uchar addr, uchar d)
{
uchar i;
DS1302_RST=0;
_nop_();
DS1302_SCK=0;//CLK低电平
_nop_();
DS1302_RST=1;//RST由低到高变化
_nop_();
//写入目标地址:addr
addr = addr & 0xFE; //最低位置零,寄存器0位为0时写,为1时读
for(i = 0; i < 8; i ++)
{
if (addr & 0x01)
{
DS1302_DAT=1;
}
else
{
DS1302_DAT=0;
}
DS1302_SCK=1; //产生时钟
DS1302_SCK=0;
addr = addr >> 1;
}
//写入数据:d
for(i = 0; i < 8; i ++)
{
if (d & 0x01)
{
DS1302_DAT=1;
}
else
{
DS1302_DAT=0;
}
DS1302_SCK=1; //产生时钟
DS1302_SCK=0;
d = d >> 1;
}
DS1302_RST=0; //停止DS1302总线
_nop_();
}
/****
*******从DS1302读出一字节数据
*****/
uchar ds1302_read_byte(uchar addr)
{
uchar i,temp;
DS1302_RST=0;
_nop_();
DS1302_SCK=0;//CLK低电平
_nop_();
DS1302_RST=1;//RST由低到高变化
_nop_();
//写入目标地址:addr
addr = addr | 0x01; //最低位置高,寄存器0位为0时写,为1时读
for (i = 0; i < 8; i ++)
{
if (addr & 0x01)
{
DS1302_DAT=1;
}
else
{
DS1302_DAT=0;
}
DS1302_SCK=1;
DS1302_SCK=0;
addr = addr >> 1;
}
//输出数据:temp
for (i = 0; i < 8; i ++)
{
temp = temp >> 1;
if (DS1302_DAT)
{
temp |= 0x80;
}
else
{
temp &= 0x7F;
}
DS1302_SCK=1;
DS1302_SCK=0;
}
DS1302_RST=0; //停止DS1302总线
_nop_();
DS1302_SCK=1;
return temp;
}
/****
*******向DS302写入时钟数据
*****/
void ds1302_write_time(void)
{
ds1302_write_byte(ds1302_control_add,0x00); //关闭写保护
ds1302_write_byte(ds1302_sec_add,0x80); //暂停时钟
ds1302_write_byte(ds1302_charger_add,0xa9); //涓流充电
ds1302_write_byte(ds1302_year_add,time_buf[1]); //年
ds1302_write_byte(ds1302_month_add,time_buf[2]); //月
ds1302_write_byte(ds1302_date_add,time_buf[3]); //日
ds1302_write_byte(ds1302_hr_add,time_buf[4]); //时
ds1302_write_byte(ds1302_min_add,time_buf[5]); //分
ds1302_write_byte(ds1302_sec_add,time_buf[6]); //秒
ds1302_write_byte(ds1302_day_add,time_buf[7]); //周
ds1302_write_byte(ds1302_control_add,0x80); //打开写保护
}
/****
*******从DS302读出时钟数据
*****/
void ds1302_read_time(void)
{
time_buf[1]=ds1302_read_byte(ds1302_year_add); //年
time_buf[2]=ds1302_read_byte(ds1302_month_add); //月
time_buf[3]=ds1302_read_byte(ds1302_date_add); //日
time_buf[4]=ds1302_read_byte(ds1302_hr_add); //时
time_buf[5]=ds1302_read_byte(ds1302_min_add); //分
time_buf[6]=(ds1302_read_byte(ds1302_sec_add))&0x7f; //秒,屏蔽秒的第7位,避免超出59
time_buf[7]=ds1302_read_byte(ds1302_day_add); //周
}
DS1302.h
/**********************************
作者:特纳斯电子
网站:https://www.mcude.com
联系方式:46580829(QQ)
淘宝店铺:特纳斯电子
**********************************/
#ifndef _DS1302_H_
#define _DS1302_H_
/**********************************
包含头文件
**********************************/
#include "main.h"
/**********************************
PIN口定义
**********************************/
sbit DS1302_RST=P1^4; //ds1302复位引脚P1.4
sbit DS1302_DAT=P1^3; //ds1302数据引脚P1.5
sbit DS1302_SCK=P1^2; //ds1302时钟引脚P1.6
/**********************************
重定义关键词
**********************************/
#define ds1302_sec_add 0x80 //秒数据地址
#define ds1302_min_add 0x82 //分数据地址
#define ds1302_hr_add 0x84 //时数据地址
#define ds1302_date_add 0x86 //日数据地址
#define ds1302_month_add 0x88 //月数据地址
#define ds1302_day_add 0x8a //星期数据地址
#define ds1302_year_add 0x8c //年数据地址
#define ds1302_control_add 0x8e //控制数据地址
#define ds1302_charger_add 0x90 //涓流充电地址
#define ds1302_clkburst_add 0xbe //分页地址
/**********************************
变量定义
**********************************/
extern char time_buf[8];
/**********************************
函数声明
**********************************/
void ds1302_write_time(void); //向DS302写入时钟数据
void ds1302_read_time(void); //从DS302读出时钟数据
#endif