单片机学习小组
直播中

苹果派派

11年用户 629经验值
私信 关注

DS1302时钟模块具有哪些参数?

DS1302时钟模块具有哪些参数?

回帖(1)

朱利华

2022-2-9 14:47:53
前言

关于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));
}
举报

更多回帖

发帖
×
20
完善资料,
赚取积分