📄 ds1302.c
字号:
/*sbit T_CLK = P2^7; //实时时钟时钟线引脚
sbit T_IO = P1^4; //实时时钟数据线引脚
sbit T_RST = P1^5; //实时时钟复位线引脚
void v_RTInputByte(uchar ucDa)
{
uchar i;
ACC = ucDa;
for(i=8; i>0; i--)
{
T_IO = ACC0; //相当于汇编中的 RRC
T_CLK = 1;
T_CLK = 0;
ACC = ACC >> 1;
}
}
uchar uc_RTOutputByte(void)
{
uchar i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; //相当于汇编中的 RRC
ACC7 = T_IO;
T_CLK = 1;
T_CLK = 0;
}
return(ACC);
}
void v_W1302(uchar ucAddr, uchar ucDa)
{
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(ucAddr); // 地址,命令
v_RTInputByte(ucDa); // 写1Byte数据
T_CLK = 1;
T_RST =0;
}
uchar uc_R1302(uchar ucAddr)
{
uchar ucDa;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(ucAddr); // 地址,命令
ucDa = uc_RTOutputByte(); // 读1Byte数据
T_CLK = 1;
T_RST =0;
return(ucDa);
}
void v_BurstW1302T(uchar *pSecDa)
{
uchar i;
v_W1302(0x8e,0x00); // 控制命令,WP=0,写操作?
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(0xbe); // 0xbe:时钟多字节写命令
for (i=8;i>0;i--) //8Byte = 7Byte 时钟数据 + 1Byte 控制
{
v_RTInputByte(*pSecDa);// 写1Byte数据
pSecDa++;
}
T_CLK = 1;
T_RST =0;
}
void v_BurstR1302T(uchar *pSecDa)
{
uchar i;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(0xbf); // 0xbf:时钟多字节读命令
for (i=8; i>0; i--)
{
*pSecDa = uc_RTOutputByte(); // 读1Byte数据
pSecDa++;
}
T_CLK = 1;
T_RST =0;
}
void v_BurstW1302R(uchar *pReDa)
{
uchar i;
v_W1302(0x8e,0x00); // 控制命令,WP=0,写操作?
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(0xfe); // 0xbe:时钟多字节写命令
for (i=31;i>0;i--) //31Byte 寄存器数据
{
v_RTInputByte(*pReDa); // 写1Byte数据
pReDa++;
}
T_CLK = 1;
T_RST =0;
}
void v_BurstR1302R(uchar *pReDa)
{
uchar i;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(0xff); // 0xbf:时钟多字节读命令
for (i=31; i>0; i--) //31Byte 寄存器数据
{
*pReDa = uc_RTOutputByte(); // 读1Byte数据
pReDa++;
}
T_CLK = 1;
T_RST =0;
}
void v_Set1302(uchar *pSecDa)
{
uchar i;
uchar ucAddr = 0x80;
v_W1302(0x8e,0x00); // 控制命令,WP=0,写操作?
for(i =7;i>0;i--)
{
v_W1302(ucAddr,*pSecDa); // 秒 分 时 日 月 星期 年
pSecDa++;
ucAddr +=2;
}
v_W1302(0x8e,0x80); // 控制命令,WP=1,写保护
}
void v_Get1302(uchar ucCurtime[])
{
uchar i;
uchar ucAddr = 0x81;
for (i=0;i<7;i++)
{
ucCurtime[i] = uc_R1302(ucAddr);//格式为: 秒 分 时 日 月 星期 年
ucAddr += 2;
}
}
*/
#ifndef _DS1302_H
#define _DS1302_H
#endif
sbit DSRST = P2 ^ 7; //时钟复位信号线
sbit DSDIO = P2 ^ 6; //时钟数据线
sbit DSCLK = P2 ^ 5; //时钟时钟线
#define SEC_WRI 0x80
#define SEC_READ 0x81
#define MIN_WRI 0x82
#define MIN_READ 0x83
#define HR_WRI 0x84
#define HR_READ 0x85
#define DATE_WRI 0x86
#define DATE_READ 0x87
#define MON_WRI 0x88
#define MON_READ 0x89
#define WEEK_WRI 0x8A
#define WEEK_READ 0x8B
#define YEAR_WRI 0x8C
#define YEAR_READ 0x8D
#define WRI_PROTECT_WRI 0x8E
#define WRI_PROTECT_READ 0x8F
#define CLOCK_MULTI_BYTE_WRI 0xBE
#define CLOCK_MULTI_BYTE_READ 0xBF
#define RAM_MULTI_BYTE_WRI 0xFE
#define RAM_MULTI_BYTE_READ 0xFF
#define DSRSTLOW() DSRST = 0; _nop_(); _nop_(); _nop_(); _nop_();\
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); \
_nop_(); _nop_(); _nop_(); _nop_(); _nop_()
#define DSRSTHIGH() DSRST = 1; _nop_(); _nop_(); _nop_(); _nop_();\
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); \
_nop_(); _nop_(); _nop_(); _nop_(); _nop_()
#define DSCLKLOW() DSCLK = 0; _nop_(); _nop_(); _nop_(); _nop_();\
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); \
_nop_(); _nop_(); _nop_(); _nop_(); _nop_()
#define DSCLKHIGH() DSCLK = 1; _nop_(); _nop_(); _nop_(); _nop_();\
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); \
_nop_(); _nop_(); _nop_(); _nop_(); _nop_()
void WriDs(unsigned char addr, unsigned char dat);
unsigned char ReadDs(unsigned char addr);
void SetTimer(unsigned char *pSetTimer);
void GetTimer(unsigned char *pGetTimer);
void OscEnable();
void Osc24();
void ChargeEnable();
void DsInit();
#endif
#include "DS1302.h"
void OscEnable()
{
WriDs(0x80,0);
}
void Osc24()
{
WriDs(0x84,0);
}
void ChargeEnable()
{
WriDs(0x90,0xa5); //涓流充电,一个二极管,一个2k的电阻
}
void DsInit()
{
//T_CLK = 0;
//T_RST = 0;
//_nop_();
//T_RST = 1;
DSCLKLOW();
DSRSTLOW();
DSRSTHIGH();
OscEnable(); // 时钟停止位使能
WriDs(0x8e,0x0); // 允许写入单个数据字节
ChargeEnable(); // 充电使能
Osc24();
}
void WriDs(uchar addr, uchar dat)
{
//uchar dsWriDsI;
//uchar dsWriCh = 0x01;
dsWriDsI = 0;
dsWriCh = 0x01;
EA = 0;
DSCLKLOW();
DSRSTLOW();
DSRSTHIGH();
for(dsWriDsI = 0; dsWriDsI < 8; dsWriDsI ++)
{
if(addr & dsWriCh)
{
DSDIO = 1;
}
else
{
DSDIO = 0;
}
dsWriCh = dsWriCh << 1;
DSCLKHIGH();
DSCLKLOW();
}
dsWriCh = 0x01;
for(dsWriDsI = 0; dsWriDsI < 8; dsWriDsI ++)
{
if(dat & dsWriCh)
{
DSDIO = 1;
}
else
{
DSDIO = 0;
}
dsWriCh = dsWriCh << 1;
DSCLKHIGH();
DSCLKLOW();
}
DSRSTLOW();
EA = 1;
}
uchar ReadDs(uchar addr)
{
//uchar dsReadDsK;
//uchar dsReadCl;
dsReadDsK = 0;
dsReadCl = 0;
DSRSTLOW();
DSCLKLOW();
DSRSTHIGH();
dsReadCl = 0x01;
for(dsReadDsK = 0; dsReadDsK < 8; dsReadDsK ++)
{
if(addr & dsReadCl)
{
DSDIO = 1;
}
else
{
DSDIO = 0;
}
dsReadCl = dsReadCl << 1;
DSCLKHIGH();
DSCLKLOW();
}
dsReadCl = 0;
for(dsReadDsK = 0; dsReadDsK < 8; dsReadDsK ++)
{
dsReadCl = dsReadCl >> 1;
if(DSDIO)
{
dsReadCl = dsReadCl + 0x80;
}
DSCLKHIGH();
DSCLKLOW();
}
DSRSTLOW();
return(dsReadCl);
}
void SetTimer(uchar *pSetTimer)
{
WriDs(YEAR_WRI, *(pSetTimer + 0));
WriDs(MON_WRI , *(pSetTimer + 1));
WriDs(DATE_WRI, *(pSetTimer + 2));
WriDs(HR_WRI , *(pSetTimer + 3));
WriDs(MIN_WRI , *(pSetTimer + 4));
WriDs(SEC_WRI , *(pSetTimer + 5));
}
void GetTimer(uchar *pGetTimer)
{
*(pGetTimer + 0) = ReadDs(YEAR_READ);
*(pGetTimer + 1) = ReadDs(MON_READ);
*(pGetTimer + 2) = ReadDs(DATE_READ);
*(pGetTimer + 3) = ReadDs(HR_READ);
*(pGetTimer + 4) = ReadDs(MIN_READ);
*(pGetTimer + 5) = ReadDs(SEC_READ);
}
void main(void)
{
unsigned char address,d;
SCON = 0x50;
TMOD = 0x21; //Timer0 - 16bit timer mode
TL1 = 253;
TH1 = 253;
TR1 = 1;
TI = 1;
IE = 0x83;
printf("printf ok!\n");
}
/*
//DS1302时钟芯片驱动程序
#include <reg51.h>
#include <stdio.h>
//下面是引脚连接关系
sbit clock_clk=P1^2;
sbit clock_dat=P1^3;
sbit clock_rst=P1^4;
sbit a0=ACC^0;
sbit a1=ACC^1;
sbit a2=ACC^2;
sbit a3=ACC^3;
sbit a4=ACC^4;
sbit a5=ACC^5;
sbit a6=ACC^6;
sbit a7=ACC^7;
void clock_out(unsigned char dd)
{
ACC=dd;
clock_dat=a0;clock_clk=1;clock_clk=0;
clock_dat=a1;clock_clk=1;clock_clk=0;
clock_dat=a2;clock_clk=1;clock_clk=0;
clock_dat=a3;clock_clk=1;clock_clk=0;
clock_dat=a4;clock_clk=1;clock_clk=0;
clock_dat=a5;clock_clk=1;clock_clk=0;
clock_dat=a6;clock_clk=1;clock_clk=0;
clock_dat=a7;clock_clk=1;clock_clk=0;
}
unsigned char clock_in(void) {
clock_dat=1;
a0=clock_dat;
clock_clk=1;clock_clk=0;a1=clock_dat;
clock_clk=1;clock_clk=0;a2=clock_dat;
clock_clk=1;clock_clk=0;a3=clock_dat;
clock_clk=1;clock_clk=0;a4=clock_dat;
clock_clk=1;clock_clk=0;a5=clock_dat;
clock_clk=1;clock_clk=0;a6=clock_dat;
clock_clk=1;clock_clk=0;a7=clock_dat;
return(ACC);
}
unsigned char read_clock(unsigned char ord) {
unsigned char dd=0;
clock_clk=0;
clock_rst=0;
clock_rst=1;
clock_out(ord);
dd=clock_in();
clock_rst=0;
clock_clk=1;
return(dd);
}
void write_clock(unsigned char ord,unsigned char dd) {
clock_clk=0;
clock_rst=0;
clock_rst=1;
clock_out(ord);
clock_out(dd);
clock_rst=0;
clock_clk=1;
}
void main(void)
{
unsigned char address,d;
SCON = 0x50;
TMOD = 0x21; //Timer0 - 16bit timer mode
TL1 = 253;
TH1 = 253;
TR1 = 1;
TI = 1;
IE = 0x83;
printf("printf ok!\n");
//调用方法:
//DS1302内部分为32字节RAM和8字节时钟日历数据
//读内部RAM 0:
address=0;
d=read_clock(0xc0|address);
printf("RAM 0 = %d\n", (unsigned int)d);
//读内部RAM 1:
address=1;
d=read_clock(0xc0|address);
printf("RAM 1 = %d\n", (unsigned int)d);
//写内部RAM 0,写入5:
address=0;d=5;
write_clock(0xc1|address,d);
//读内部RAM 1,写入123:
address=1;d=123;
d=read_clock(0xc1|address);
//=================================
//读内部时钟日历数据0:秒:
address=0;
d=read_clock(0x80|address);
printf("second = %d\n", (unsigned int)d);
//读内部时钟日历数据1:分:
address=1;
d=read_clock(0x80|address);
printf("minute = %d\n", (unsigned int)d);
//写内部时钟日历数据0:秒,写入03秒
address=0;d=3;
write_clock(0x80|address,d);
while(1);
}
内部时钟日历地址图,始终日历用BCD码储存
0:秒
1:分
2:小时
3:日期
4:月份
5:星期
6:年
7:写保护寄存器
8:慢速充电寄存器
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -