前言
关于DS1302我学了好几天因为想从底层库文件把他学懂,然后发现网上资料比较混杂,我也走了很多错路,现在分享给大家我的学习经历,关于DS1302的 物理层面的数据大家可以参考:点击链接
1.官方文档
官方文档可以去淘宝找,我这里文末会给出。
首先是他的物理参数:
说明:VCC 5V 2V-5.5V都可工作
下面是我自己写的库文件,后面会讲怎么制作库文件
当然也可以使用别人编写的库文件在IDE界面搜索DS1302就好了,我这个也是根据人家的更改而来。
教学视频BiliBIli上UP主 MCU起航 讲的很清楚,但是用他的程序编写一直报错,可能是语法与IDE冲突,我也不知道为啥,一度浪费了我一天时间。
#define SCL D8
#define SDA D7
#define RST D0
enum Register
{
SecondReg=0,
MinuteReg=1,
HourReg= 2,
DateReg= 3,
MonthReg=4,
DayReg= 5,
YearReg= 6,
WriteProtectReg = 7
};
class Time
{
public:
uint8_t ksecond;
uint8_t kminute;
uint8_t khour;
uint8_t kdate;
uint8_t kmonth;
uint8_t kday;
uint16_t kyear;
uint8_t kwrite;
};
void setup()
{
Serial.begin(9600);
SetTime(2020,4,24,12,27,01,5);//将时间输入SD1302
}
void loop()
{
delay(1000);
Time time2;
time2=ReadTime();
uint8_t a=readReg(SecondReg);
Serial.print(time2.khour);
Serial.print("小时");
Serial.print(time2.kminute);
Serial.print("分");
Serial.print(time2.ksecond);
Serial.println("秒");
//串口测试用,自己可以更改
}
/*********************数据转换************************/
//将BCD码转换成十位数
uint8_t BcdToDec(const uint8_t bcd)
{
return (10 * ((bcd & 0xF0) >> 4) + (bcd & 0x0F));
}
//将十位数转换成BCD码
uint8_t DecToBcd(const uint8_t dec)
{
const uint8_t tens = dec / 10;
const uint8_t ones = dec % 10;
return (tens << 4) | ones;
}
/***************************写入读出DS1302***********************************/
void write1302(uint8_t value)//结束后SCL为低
{
uint8_t dect=0x01;
pinMode(SCL,OUTPUT);
pinMode(RST,OUTPUT);
pinMode(SDA,OUTPUT);
delayMicroseconds(1);
digitalWrite(SCL,LOW);
digitalWrite(RST,HIGH);
for(int i=0;i<8;i++)
{
digitalWrite(D7, (value >> i) & 1);
digitalWrite(SCL, HIGH);
digitalWrite(SCL, LOW);
delayMicroseconds(1);
}
}
uint8_t read1302()
{
pinMode(SDA,INPUT);
uint8_t value_byte=0;
uint8_t bit=0;
for(int i=0;i<8;i++)
{
bit = digitalRead(SDA);
value_byte |= (bit << i);
digitalWrite(SCL, HIGH);
digitalWrite(SCL, LOW);
}
digitalWrite(RST,LOW);
return value_byte; //将读取的1Byte返回
}
/***************************往寄存器写入读出************************************/
//在reg地址写入value
void writeReg(uint8_t reg,uint8_t value)
{
uint8_t addr=(0x80|(reg<<1));
write1302(addr);
write1302(value);
}
//读出reg寄存器中的数据并返回数据
uint8_t readReg(uint8_t reg)
{
uint8_t addr=(0x81|(reg<<1));
write1302(addr);
uint8_t value=read1302();
return BcdToDec(value);
}
/******************************读取时间***********************************/
Time ReadTime()
{
Time time1;
time1.ksecond=readReg(SecondReg);
time1.kminute=readReg(MinuteReg);
time1.khour=readReg(HourReg);
time1.kdate=readReg(DateReg);
time1.kmonth=readReg(MonthReg);
time1.kday=readReg(DayReg);
time1.kyear=readReg(YearReg);
time1.kwrite=readReg(WriteProtectReg);
return time1;
}
/*********************设置时间*******************************/
//输入年月日小时分钟秒 星期几
void SetTime(uint16_t year,uint8_t month,uint8_t data,uint8_t hour,
uint8_t minute,uint8_t second,uint8_t day)
{ //获取SD1302的CH位
writeprotect(false);
uint8_t ch =readReg(SecondReg)&0x80;//得到CH位(10000000或00000000)
writeReg(SecondReg,ch|DecToBcd(second));//输入秒参数
writeReg(MinuteReg,DecToBcd(minute));
writeReg(HourReg,DecToBcd(hour));
writeReg(DateReg,DecToBcd(data));
writeReg(MonthReg,DecToBcd(month));
writeReg(DayReg,DecToBcd(day));
writeReg(YearReg,DecToBcd(year-2000));
halt(false);
writeprotect(true);
}
/*******************写保护&秒针***********第七位控制****************************/
//输入年月日小时分钟秒 星期几
void halt(bool enable)//将秒暂停指针打开或关闭
{
uint8_t sec=readReg(SecondReg);
sec &= ~(1<<7);//sec&=(10111111)
sec |=(enable<<7);
writeReg(SecondReg,sec);//将秒暂停指针打开或关闭
}
//true:写保护开启
void writeprotect(bool enable)
{
writeReg(WriteProtectReg,(enable<<7));
}
前言
关于DS1302我学了好几天因为想从底层库文件把他学懂,然后发现网上资料比较混杂,我也走了很多错路,现在分享给大家我的学习经历,关于DS1302的 物理层面的数据大家可以参考:点击链接
1.官方文档
官方文档可以去淘宝找,我这里文末会给出。
首先是他的物理参数:
说明:VCC 5V 2V-5.5V都可工作
下面是我自己写的库文件,后面会讲怎么制作库文件
当然也可以使用别人编写的库文件在IDE界面搜索DS1302就好了,我这个也是根据人家的更改而来。
教学视频BiliBIli上UP主 MCU起航 讲的很清楚,但是用他的程序编写一直报错,可能是语法与IDE冲突,我也不知道为啥,一度浪费了我一天时间。
#define SCL D8
#define SDA D7
#define RST D0
enum Register
{
SecondReg=0,
MinuteReg=1,
HourReg= 2,
DateReg= 3,
MonthReg=4,
DayReg= 5,
YearReg= 6,
WriteProtectReg = 7
};
class Time
{
public:
uint8_t ksecond;
uint8_t kminute;
uint8_t khour;
uint8_t kdate;
uint8_t kmonth;
uint8_t kday;
uint16_t kyear;
uint8_t kwrite;
};
void setup()
{
Serial.begin(9600);
SetTime(2020,4,24,12,27,01,5);//将时间输入SD1302
}
void loop()
{
delay(1000);
Time time2;
time2=ReadTime();
uint8_t a=readReg(SecondReg);
Serial.print(time2.khour);
Serial.print("小时");
Serial.print(time2.kminute);
Serial.print("分");
Serial.print(time2.ksecond);
Serial.println("秒");
//串口测试用,自己可以更改
}
/*********************数据转换************************/
//将BCD码转换成十位数
uint8_t BcdToDec(const uint8_t bcd)
{
return (10 * ((bcd & 0xF0) >> 4) + (bcd & 0x0F));
}
//将十位数转换成BCD码
uint8_t DecToBcd(const uint8_t dec)
{
const uint8_t tens = dec / 10;
const uint8_t ones = dec % 10;
return (tens << 4) | ones;
}
/***************************写入读出DS1302***********************************/
void write1302(uint8_t value)//结束后SCL为低
{
uint8_t dect=0x01;
pinMode(SCL,OUTPUT);
pinMode(RST,OUTPUT);
pinMode(SDA,OUTPUT);
delayMicroseconds(1);
digitalWrite(SCL,LOW);
digitalWrite(RST,HIGH);
for(int i=0;i<8;i++)
{
digitalWrite(D7, (value >> i) & 1);
digitalWrite(SCL, HIGH);
digitalWrite(SCL, LOW);
delayMicroseconds(1);
}
}
uint8_t read1302()
{
pinMode(SDA,INPUT);
uint8_t value_byte=0;
uint8_t bit=0;
for(int i=0;i<8;i++)
{
bit = digitalRead(SDA);
value_byte |= (bit << i);
digitalWrite(SCL, HIGH);
digitalWrite(SCL, LOW);
}
digitalWrite(RST,LOW);
return value_byte; //将读取的1Byte返回
}
/***************************往寄存器写入读出************************************/
//在reg地址写入value
void writeReg(uint8_t reg,uint8_t value)
{
uint8_t addr=(0x80|(reg<<1));
write1302(addr);
write1302(value);
}
//读出reg寄存器中的数据并返回数据
uint8_t readReg(uint8_t reg)
{
uint8_t addr=(0x81|(reg<<1));
write1302(addr);
uint8_t value=read1302();
return BcdToDec(value);
}
/******************************读取时间***********************************/
Time ReadTime()
{
Time time1;
time1.ksecond=readReg(SecondReg);
time1.kminute=readReg(MinuteReg);
time1.khour=readReg(HourReg);
time1.kdate=readReg(DateReg);
time1.kmonth=readReg(MonthReg);
time1.kday=readReg(DayReg);
time1.kyear=readReg(YearReg);
time1.kwrite=readReg(WriteProtectReg);
return time1;
}
/*********************设置时间*******************************/
//输入年月日小时分钟秒 星期几
void SetTime(uint16_t year,uint8_t month,uint8_t data,uint8_t hour,
uint8_t minute,uint8_t second,uint8_t day)
{ //获取SD1302的CH位
writeprotect(false);
uint8_t ch =readReg(SecondReg)&0x80;//得到CH位(10000000或00000000)
writeReg(SecondReg,ch|DecToBcd(second));//输入秒参数
writeReg(MinuteReg,DecToBcd(minute));
writeReg(HourReg,DecToBcd(hour));
writeReg(DateReg,DecToBcd(data));
writeReg(MonthReg,DecToBcd(month));
writeReg(DayReg,DecToBcd(day));
writeReg(YearReg,DecToBcd(year-2000));
halt(false);
writeprotect(true);
}
/*******************写保护&秒针***********第七位控制****************************/
//输入年月日小时分钟秒 星期几
void halt(bool enable)//将秒暂停指针打开或关闭
{
uint8_t sec=readReg(SecondReg);
sec &= ~(1<<7);//sec&=(10111111)
sec |=(enable<<7);
writeReg(SecondReg,sec);//将秒暂停指针打开或关闭
}
//true:写保护开启
void writeprotect(bool enable)
{
writeReg(WriteProtectReg,(enable<<7));
}
举报