DS1302时钟比起DS18B20而言要简单的多。
需要注意的大概三点:
1. 写入时分秒
void set_time(unsigned char shi, unsigned char fen ,unsigned char miao)
{
Ds1302_Single_Byte_Write(0x8e, 0x00); //WP=0,写操作
Ds1302_Single_Byte_Write(0x80, (miao/10)*16+miao%10); //注意写入的时分秒要转化为16进制
Ds1302_Single_Byte_Write(0x82, (fen/10)*16+fen%10);
Ds1302_Single_Byte_Write(0x84, (shi/10)*16+shi%10);
Ds1302_Single_Byte_Write(0x8e, 0x80); //WP=1,写保护
}
2. 读出时分秒
void ShowTime()
{
if(time_flag == 1) //每隔一段时间扫描一次!
{
time_flag = 0;
miao = Ds1302_Single_Byte_Read(0x81); //读出时间
Ds1302_Single_Byte_Write(0x00, 0x00); //防止数据混乱,**必须写**
fen = Ds1302_Single_Byte_Read(0x83);
Ds1302_Single_Byte_Write(0x00, 0x00);
shi = Ds1302_Single_Byte_Read(0x85);
Ds1302_Single_Byte_Write(0x00, 0x00);
}
dispbuff[0] = shi/16; //读出的时分秒是十六进制,要转化为十进制
dispbuff[1] = shi%16;
dispbuff[2] = 11;
dispbuff[3] = fen/16;
dispbuff[4] = fen%16;
dispbuff[5] = 11;
dispbuff[6] = miao/16;
dispbuff[7] = miao%16;
}
代码
main.c
******************************************************************************
* 文件名:DS1302时钟
* 描 述:
* 作 者:思索与猫
* 日 期: 19/3/8
* 备 注:
*
******************************************************************************
#include<stc15f2k60s2.h>
#include<ds1302.h>
#define uchar unsigned char
#define uint unsigned int
uchar duan[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0x40}; //10black,11-
uchar dispbuff[8];
uchar shi, fen, miao;
void CloseFucker();
void Timer0Init();
void Display();
void ShowTime();
void main()
{
CloseFucker();
Timer0Init();
set_time(23, 59 ,50);
while(1)
{
ShowTime();
}
}
void ShowTime()
{
if(time_flag == 1)
{
time_flag = 0;
miao = Ds1302_Single_Byte_Read(0x81); //读出时间
Ds1302_Single_Byte_Write(0x00, 0x00); //防止数据混乱,**必须写**
fen = Ds1302_Single_Byte_Read(0x83);
Ds1302_Single_Byte_Write(0x00, 0x00);
shi = Ds1302_Single_Byte_Read(0x85);
Ds1302_Single_Byte_Write(0x00, 0x00);
}
dispbuff[0] = shi/16;
dispbuff[1] = shi%16;
dispbuff[2] = 11;
dispbuff[3] = fen/16;
dispbuff[4] = fen%16;
dispbuff[5] = 11;
dispbuff[6] = miao/16;
dispbuff[7] = miao%16;
}
void Display()
{
static uchar index = 0;
P2 = (P2&0x1f)|0xe0;
P0 = 0xff;
P2 = P2&0x1f;
P2 = (P2&0x1f)|0xc0;
P0 = 1<<index;
P2 = P2&0x1f;
P2 = (P2&0x1f)|0xe0;
P0 = ~duan[dispbuff[index]];
P2 = P2&0x1f;
index++;
index &= 0x07;
}
void T0_time() interrupt 1
{
static uchar time_count = 0;
TL0 = 0x40;
TH0 = 0xA2;
Display();
if(++time_count >= 200)
{
time_count = 0
time_flag = 1;;
}
}
void Timer0Init() //12.000MHz 2ms
{
AUXR |= 0x80;
TMOD &= 0xF0;
TL0 = 0x40;
TH0 = 0xA2;
TF0 = 0;
TR0 = 1;
ET0 = 1;
EA = 1;
}
void CloseFucker()
{
P2 = (P2&0x1f)|0xa0;
P0 = 0xaf;
P2 = P2&0x1f;
}
ds1302.h
#ifndef __DS1302_H__
#define __DS1302_H__
#include<stc15f2k60s2.h>
#include<intrins.h>
/********************************************************************/
sbit SCK=P1^7;
sbit SD=P2^3;
sbit RST=P1^3;
/********************************************************************/
#define RST_CLR RST=0
#define RST_SET RST=1
#define SDA_CLR SD=0
#define SDA_SET SD=1
#define SDA_R SD
#define SCK_CLR SCK=0
#define SCK_SET SCK=1
/********************************************************************/
#define ds1302_sec_addr 0x80 //秒
#define ds1302_min_addr 0x82 //分
#define ds1302_hr_addr 0x84 //时
#define ds1302_date_addr 0x86 //日
#define ds1302_month_addr 0x88 //月
#define ds1302_day_addr 0x8A //星
#define ds1302_year_addr 0x8C //年
#define ds1302_control_addr 0x8E //写保护
#define ds1302_charger_addr 0x90 //涓电流充电命令字地址
#define ds1302_clkburst_addr 0xBE //日历,时钟突发模式命令字地址
extern void Write_Ds1302_Byte(unsigned char dat);
extern unsigned char Read_Ds1302_Byte(void);
extern void Ds1302_Single_Byte_Write(unsigned char addr, unsigned char dat);
extern unsigned char Ds1302_Single_Byte_Read(unsigned char addr);
void set_time(unsigned char shi, unsigned char fen ,unsigned char miao);
#endif
/********************************************************************/
//END FILE
/********************************************************************/
ds1302.c
#include "ds1302.h"
/********************************************************************/
void Write_Ds1302_Byte(unsigned char dat)
{
unsigned char i;
SCK = 0;
for (i=0;i<8;i++)
{
if (dat & 0x01)
{
SDA_SET;
}
else
{
SDA_CLR;
}
SCK_SET;
SCK_CLR;
dat = dat >> 1;
}
}
/********************************************************************/
unsigned char Read_Ds1302_Byte(void)
{
unsigned char i, dat=0;
for (i=0;i<8;i++)
{
dat = dat >> 1;
if (SDA_R)
{
dat |= 0x80;
}
else
{
dat &= 0x7F;
}
SCK_SET;
SCK_CLR;
}
return dat;
}
/********************************************************************/
void Ds1302_Single_Byte_Write(unsigned char addr, unsigned char dat)
{
RST_CLR;
SCK_CLR;
RST_SET;
addr = addr & 0xFE;
Write_Ds1302_Byte(addr);
Write_Ds1302_Byte(dat);
RST_CLR;
}
/********************************************************************/
unsigned char Ds1302_Single_Byte_Read(unsigned char addr)
{
unsigned char temp;
RST_CLR;
SCK_CLR;
RST_SET;
addr = addr | 0x01;
Write_Ds1302_Byte(addr);
temp=Read_Ds1302_Byte();
return temp;
}
void set_time(unsigned char shi, unsigned char fen ,unsigned char miao)
{
Ds1302_Single_Byte_Write(0x8e, 0x00);
Ds1302_Single_Byte_Write(0x80, (miao/10)*16+miao%10);
Ds1302_Single_Byte_Write(0x82, (fen/10)*16+fen%10);
Ds1302_Single_Byte_Write(0x84, (shi/10)*16+shi%10);
Ds1302_Single_Byte_Write(0x8e, 0x80);
}