深圳市航顺芯片技术研发有限公司
直播中

1123127317

8年用户 1012经验值
擅长:制造/封装 接口/总线/驱动
私信 关注
[问答]

怎样向DS1302时钟芯片写入数据和读取数据呢

怎样向DS1302时钟芯片写入数据和读取数据呢?

回帖(1)

任莉虹

2021-10-27 11:59:27
  前言
  小编在校工作室无聊,参加了篮桥杯中的51单片机,看到资料的时候,那个写法,都是大神写法,主要我是看不懂啊,幸好工作室有大牛林峰在,许多问题他都能生动的描述给我听,外加小编天生聪明,还是勉强看懂了,为了加深印象,也为了一些网上像我这样的苦逼,小编决定用自己的语言说一遍,看的懂就看 ,看不懂我也没办法啦。(大神忽略这文章)
  给大家看一个截图:
  以上截图只是让你明白 时钟芯片只有三个引脚操作 ,就这么简单。
  在篮桥板给的资料中 定义了这三个引脚 就是对应上面截图三个引脚 ,只要你一开始理解了三个引脚,接下来什么都好办了,你也知道的,三个引脚再难也难不了哪里去吧?
  接下来我贴出篮桥杯的资料程序 // 注释就是 对应上面截图的信息
  #define SCK P17 //对应上面截图的SCLK
  #define RST P13 //对应上面截图的使能端CE
  #define SDA P23 //对应上面截图的I/O口
  然后,因为时钟芯片只有三个引脚,所以总是会有些电平置高或置低, 再为了方便一些:
  #define SCK_SET SCK=1
  #define SCK_CLR SCK=0
  #define RST_SET RST=1
  #define RST_CLR RST=0
  #define SDA_SET SDA=1
  #define SDA_CLR SDA=0
  接下来,就是向DS1302时钟芯片写入数据和读取数据,(在这里我想说一些自己理解的题外话, 就是我们在写程序的时候,特别要注意的是,要有意识的向程序模块这个方向写,怎么这样说呢,大家都知道在写一些功能程序时,程序量几百行,你我花一点时间还是能看懂的,但是你写了几千行几万行呢,到时别说 别人看不懂 自己可能也会看不懂吧?所以为了以后发展,写程序的时候要注意懂得这个思想,程序模块最重要的一点:写一个方法或者类的时候,方法头要留一个像电脑u***一样的接口出来,供自己使用,而且这个方法不能与其他的的方法有耦合性,得啦 不废话了)
  接下来,就是DS1302时钟芯片写入数据和读取数据:
  怎么写呢 其实我第一次看到上面的截图时,心里明了,但是就是写不出啊,呜呜,
  所以我来先给大家演示一遍:
  一开始我们先按照上面给出的截图用c语言描述出一个方法先:
  写入数据的方法:
  /*单字节写入一字节数据*/
  void Write_Ds1302_Byte(unsigned char dat)
  {
  unsigned char i;
  SCK = 0;
  for (i=0;i《8;i++)
  {
  if (dat & 0x01) // 等价于if((addr & 0x01) ==1)
  {
  SDA_SET; //#define SDA_SET SDA=1 /*电平置高*/
  }
  else
  {
  SDA_CLR; //#define SDA_CLR SDA=0 /*电平置低*/
  }
  SCK_SET;
  SCK_CLR;
  dat = dat 》》 1;
  }
  }
  解析:用一个for循环8次 也就是基本的一个字节的位数,然后用if语句展示出一个功能:你输入一个8位数的二进制时,是 1 那就SDA_SET(I/O高电平),是0那就SDA_CLR(I/O低电平)。然后判断dat下一位,判断完就收工。
  读入数据的方法:
  /*单字节读出一字节数据*/
  unsigned char Read_Ds1302_Byte(void)
  {
  unsigned char i, dat=0;
  for (i=0;i《8;i++)
  {
  dat = dat 》》 1;
  if (SDA == 1) //等价于if(SDA_R==1) #define SDA_R SDA /*电平读取*/
  {
  dat |= 0x80;
  }
  else
  {
  dat &= 0x7F;
  }
  SCK_SET;
  SCK_CLR;
  }
  return dat;
  }
  解析:用一个for循环8次,进入会有个if语句,判断读取到的数据 ,这个语句拼成的功能很有趣,像发电报一样,SDA就是时钟芯片的I/O口,SDA会高低电平的换,然后我在SDA口设置一个if检测,高低电平就用dat这个数桶装起来,刚刚好8位 ,一个char字节。至于为什么有dat |= 0x80 和dat &= 0x7F,这两个功能就是为了在dat数桶上刻数字的 ,是高电平就刻dat |= 0x80,低电平就刻dat &= 0x7F。懂了吧?
  以上我把截图里面的图片用C语言描述了出来 ,但是这样还不行啊,我知道时钟芯片原理了,也知道了下一步就是向DS1302单字节读出或写入一字节数据,但是具体怎么写不知道啊 ,放心 ,老铁 我接下来会一 一说明的。
  /*向DS1302 单字节写入一字节数据*/
  void Ds1302_Single_Byte_Write(unsigned char addr, unsigned char dat)
  {
  RST_CLR; /*RST脚置低,实现DS1302的初始化*/
  SCK_CLR; /*SCK脚置低,实现DS1302的初始化*/
  RST_SET; /*启动DS1302总线,RST=1电平置高 */
  addr = addr & 0xFE;
  Write_Ds1302_Byte(addr); /*写入目标地址:addr,保证是写操作,写之前将最低位置零*/
  Write_Ds1302_Byte(dat); /*写入数据:dat*/
  RST_CLR; /*停止DS1302总线*/
  SDA_CLR;
  }
  上面的addr = addr & 0xFE 这语句是为了更稳定的环境而写的 可写可不写
  /*从DS1302单字节读出一字节数据*/
  unsigned char Ds1302_Single_Byte_Read(unsigned char addr)
  {
  unsigned char temp;
  RST_CLR; /*RST脚置低,实现DS1302的初始化*/
  SCK_CLR; /*SCK脚置低,实现DS1302的初始化*/
  RST_SET; /*启动DS1302总线,RST=1电平置高 */
  addr = addr | 0x01;
  Write_Ds1302_Byte(addr); /*写入目标地址:addr,保证是读操作,写之前将最低位置高*/
  temp=Read_Ds1302_Byte(); /*从DS1302中读出一个字节的数据*/
  RST_CLR; /*停止DS1302总线*/
  SDA_CLR;
  return temp;
  }
  上面的addr = addr | 0x01 这语句是为了更稳定的环境而写的 可写可不写
  以上两段程序只是充当一个管道,单片机和时钟芯片之间的管道,而最最上面两段写入和读取的方法就充当车站,数据就是路上的车子,为什么要这样写呢,又管道又车站的,不麻烦? 不麻烦!!为什么呢,因为只有这样泾渭分明,到时出了问题,只要查看现象,大概可以猜出哪里的问题,不然你程序写成一团,出了问题,你也凉了吧?懂?
  来来来 ,现在咱们开始写出个车子(数据)
  void DS1302_Init()
  {
  Ds1302_Single_Byte_Write(0x8e,0x00);//关掉写保护
  Ds1302_Single_Byte_Write(0x80,0x05);// 秒
  Ds1302_Single_Byte_Write(0x82,0x27);// 分
  Ds1302_Single_Byte_Write(0x84,0x09);// 时
  Ds1302_Single_Byte_Write(0x86,0x25);// 日
  Ds1302_Single_Byte_Write(0x88,0x12);// 月
  Ds1302_Single_Byte_Write(0x8a,0x06);// 周一
  Ds1302_Single_Byte_Write(0x8c,0x10);// 年
  Ds1302_Single_Byte_Write(0x8e,0x80);//打开写保护
  }
  在main方法中要写:
  #include 《15.h》
  #include “define.h”
  unsigned char a;
  unsigned char b;
  int main()
  {
  DS1302_Init();
  while(1)
  {
  a=Ds1302_Single_Byte_Read(0x81);
  displayseg2(a);
  b=Ds1302_Single_Byte_Read(0x83);
  displayseg3(b);
  }
  return 0;
  }
  写到这里 基本结束了,还有很多个细节我没说 。
举报

更多回帖

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