51单片机-DS1302时钟芯片(自己理解的

xiaoxiao2021-02-28  49

前言

      小编在校工作室无聊,参加了篮桥杯中的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时钟芯片写入数据和读取数据,(在这里我想说一些自己理解的题外话, 就是我们在写程序的时候,特别要注意的是,要有意识的向程序模块这个方向写,怎么这样说呢,大家都知道在写一些功能程序时,程序量几百行,你我花一点时间还是能看懂的,但是你写了几千行几万行呢,到时别说 别人看不懂 自己可能也会看不懂吧?所以为了以后发展,写程序的时候要注意懂得这个思想,程序模块最重要的一点:写一个方法或者类的时候,方法头要留一个像电脑usb一样的接口出来,供自己使用,而且这个方法不能与其他的的方法有耦合性,得啦 不废话了)

接下来,就是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; }

写到这里 基本结束了,还有很多个细节我没说 ,如果还不懂的话或者要源码,可以加QQ群 

712103438 希望大家一起交流。

转载请注明原文地址: https://www.6miu.com/read-2630976.html

最新回复(0)