引脚 | 说明 |
---|---|
Vcc2 | 主电源 |
Vcc1 | 后备电源(断电后保证时钟正常运行) |
x1,x2 | 外接32.768KHZ晶振 |
GND | 接地 |
RST | 复位引脚(低电平有效) |
I/O | 数据输入/输出引脚 |
SCLK | 串行时钟输入引脚 |
如果是直接买的时钟模块的话,会直接引出VCC,GND,CLK,DAT,RST这四个引脚
DS1302内部含有8位控制寄存器用于存放DS1302控制命令字,例:如果为0x81就是读秒寄存器,如果为0x80就是对秒寄存写入数据,初始化时需要令wp为0,才可以写入初始时间。
1.DS1302是通过串行总线跟单片机通信的,当进行一次读写操作是最少得读写两个字节,第一个字节就是控制字节,就是一个命令,告诉DS1302是读还是写操作,是对RAM还对CLOK寄存器操作。第二个字节就是要读写的数据了。
2.单字节读写:只有在SCLK为低电平时才能将RST置为高电平。所以在进行操作之前先将SCLK置低电平,然后将RST置为高电平,接着开始在IO上面放入要传输的电平信号,然后跳变SCLK。数据在SCLK上升沿时,DS1302读写数据,在SCLK下降沿时,DS1302放在数据到IO上
完整程序已附带在最后。
//执行写操作的地址 秒 分 时 日 月 周 年
u8 code write_addr[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
//2020年10月16日 周5 23时59分55秒;
u8 timer[]={0x55,0x59,0x23,0x16,0x10,0x05,0x20};
void ds1302_init()
{
u8 i;
Write_Ds1302_Byte(0x8e,0x00);//0x8e是写的地址,0x00是写入的数据
for(i=0;i<7;i++)
{
Write_Ds1302_Byte( write_addr[i],timer[i]);
}
}
初始化函数的功能开启对时钟寄存器的写操作,写入初始时间。
//执行读操作的地址 秒 分 时 日 月 周 年
u8 code read_addr[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
void ds1302_read()
{
u8 i;
for(i=0;i<7;i++)
{
timer[i] = Read_Ds1302_Byte(read_addr[i]);
}
}
通过for循环分别读取秒,分,时等寄存器的值存放在timer[]中,如果要用数码管显示的话十位是除以16,个位是对16取余
ds1302.c文件
#include <reg52.h>
#include <intrins.h>
sbit SCK=P1^7;//CLK
sbit SDA=P2^3;//DAT
sbit RST = P1^3; // DS1302¸´Î»
void Write_Ds1302(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++)
{
SCK=0;
SDA=temp&0x01;
temp>>=1;
SCK=1;
}
}
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )
{
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
Write_Ds1302(dat);
RST=0;
}
unsigned char Read_Ds1302_Byte ( unsigned char address )
{
unsigned char i,temp=0x00;
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
for (i=0;i<8;i++)
{
SCK=0;
temp>>=1;
if(SDA)
temp|=0x80;
SCK=1;
}
RST=0; _nop_();
SCK=0; _nop_();
SCK=1; _nop_();
SDA=0; _nop_();
SDA=1; _nop_();
return (temp);
}
ds1302.h文件
#ifndef __DS1302_H
#define __DS1302_H
void Write_Ds1302(unsigned char temp);
void Write_Ds1302_Byte( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302_Byte( unsigned char address );
#endif
主程序
#include "stc15f2k60s2.h"
#include "ds1302.h"
#define A P25
#define B P26
#define C P27
typedef unsigned char u8;
typedef unsigned char u16;
void hc138_init(u8 n);
void delay(u16 n);
void smg_display(u8 n, u8 num);
void ds1302_init();
void ds1302_read();
void diplay();
u8 code read_addr[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
u8 code write_addr[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
//2020年10月16日 周5 23时59分55秒;
u8 timer[]={0x55,0x59,0x23,0x16,0x10,0x05,0x20};
u8 smg[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
void main()
{
ds1302_init();
while(1)
{
ds1302_read();
diplay();
}
}
void delay(u16 n)
{
u16 i,j;
for(i=n;i>0;i--)
for(j=110;j>0;j--);
}
void smg_display(u8 n, u8 num)
{
//在第n个数码管上显示num
}
void ds1302_init()
{
u8 i;
Write_Ds1302_Byte(0x8e,0x00);//0x8eÊÇдµÄµØÖ·,0x00ÊÇдµÄÊý¾Ý
for(i=0;i<7;i++)
{
Write_Ds1302_Byte( write_addr[i],timer[i]);
}
}
void ds1302_read()
{
u8 i;
for(i=0;i<7;i++)
{
timer[i] = Read_Ds1302_Byte(read_addr[i]);
}
}
void diplay()
{
smg_display(1, timer[2]/16);
delay(10);
smg_display(2, timer[2]%16);
delay(10);
smg_display(3, timer[1]/16);
delay(10);
smg_display(4, timer[1]%16);
delay(10);
smg_display(5, timer[6]/16);
delay(10);
smg_display(6, timer[6]%16);
delay(10);
smg_display(7, timer[0]/16);
delay(10);
smg_display(8, timer[0]%16);
delay(10);
}