前言
小编在校工作室无聊,参加了篮桥杯中的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;
}
写到这里 基本结束了,还有很多个细节我没说 。
前言
小编在校工作室无聊,参加了篮桥杯中的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;
}
写到这里 基本结束了,还有很多个细节我没说 。
举报