蓝桥杯模块DS1302时钟芯片Part_2
2020年国信长天组织的模拟测试中给出延时2ms,似乎有点过分?! 2020模拟测试最后比以前多出来一行,写的更乱;其他地方的缩进,函数名都是极具个性的。
发布日期:2021-07-01 03:12:43
浏览次数:2
分类:技术文章
本文共 4893 字,大约阅读时间需要 16 分钟。
九层妖塔 起于垒土
蓝桥杯模块DS1302时钟芯片Part_2
一、Notes
●同步串行通信
●三线通信 ●内含一个实时时钟/日历和31字节静态RAM ●时钟/RAM的读/写数据以一个字节或多达31个字节的字符组方式通信。二、写时序
1、时序图
2、官方底层驱动代码:
//-------第十届资料包,日期:2011-8-9,应该是针对12T单片机void Write_Ds1302(unsigned char temp) { unsigned char i; for (i=0;i<8;i++) { SCK=0; SDA=temp&0x01; temp>>=1; SCK=1; }} //------2020年国信长天组织的模拟测试-------//void Write_Ds1302_Byte(unsigned char temp) { unsigned char i; for (i=0;i<8;i++) { SCK=0; SDA=temp&0x01; temp>>=1; SCK=1; Delay2ms(); }}
3、Template:
void DS1302_Write(uchar temp) { uchar i; for (i=0;i<8;i++) { SCK=0; SDA=temp&0x01; temp>>=1; //移位兼延时 SCK=1; //上升沿写入数据 Delay1us();//稳定电平 }}
4、Notes:
●在SCLK周期的上升沿输入字节。DS1302每检测到一个SCLK上升沿就从I/O引脚(SDA)接收1位数据。
●先将SCK=0;
再送数据,因为min( t D C t_{DC} tDC)=50ns,因此将移位temp>>=1;
放于此移位兼延时。 ●再使SCK=1;
产生上升沿,写入一位数据。 ●Delay1us();
min( t C H t_{CH} tCH)=250ns和min( t C L t_{CL} tCL)=250ns。即串行时钟信号SCK高低电平至少各为250ns。12T单片机12MHz主时钟,一个空指令_nop_();
=一个机器周期=1个时钟周期=1/ f o s c f_{osc} fosc=1/12MHz=1/12us,不够250ns,直接延时1us来稳定电平。 ●至于min( t C L t_{CL} tCL)=250ns,由SCK=0;
与SCK=1;
之间的执行代码充当延时。 ●三、写字节
1、官方底层驱动代码:
//------两个版本的驱动除了子函数名不一样外,完全相同----//void Write_Ds1302_Byte( unsigned char address,unsigned char dat ) { RST=0; _nop_(); SCK=0; _nop_(); RST=1; _nop_(); Write_Ds1302(address); Write_Ds1302(dat); RST=0; }
2、Template:
//仅改了函数名,添加了注释//------------------------------------------------DS1302写字节-----------------//void DS1302_Write_Byte(uchar address,uchar dat) { RST=0; _nop_(); //复位 SCK=0; _nop_(); //复位 RST=1; _nop_(); //开始数据传输 DS1302_Write(address);//地址字节 DS1302_Write(dat); //数据字节 RST=0; //复位,关闭数据传输 }
四、读字节
1、时序图
2、官方底层驱动代码:
//-------第十届资料包,日期:2011-8-9,应该是针对12T单片机unsigned char Read_Ds1302_Byte ( unsigned char address ){ unsigned char i,temp=0x00; RST=0; _nop_(); SCK=0; _nop_(); RST=1; _nop_(); Write_Ds1302(address); for (i=0;i<8;i++) { SCK=0; temp>>=1; if(SDA) temp|=0x80; SCK=1; } RST=0; _nop_(); SCK=0; _nop_(); SCK=1; _nop_(); SDA=0; _nop_(); SDA=1; _nop_(); return (temp); }//------2020年国信长天组织的模拟测试-------//unsigned char Read_Ds1302 ( unsigned char address ){ unsigned char i,temp=0x00; RST=0; _nop_(); SCK=0; _nop_(); RST=1; _nop_(); Write_Ds1302_Byte(address); for (i=0;i<8;i++) { SCK=0; temp>>=1; Delay2ms(); if(SDA) temp|=0x80; SCK=1; } RST=0; _nop_(); RST=0; SCK=0; _nop_(); SCK=1; _nop_(); SDA=0; _nop_(); SDA=1; return (temp); }
3、Template:
//------------------------------------------------DS1302读字节-----------------//uchar DS1302_Read_Byte(uchar address){ uchar i,temp=0x00; RST=0; _nop_(); SCK=0; _nop_(); RST=1; _nop_(); DS1302_Write(address); //地址字节 for (i=0;i<8;i++) { SCK=0; //开始读数据字节 temp>>=1; //延时+移位 Delay1us();//延时稳定电平 if(SDA) temp|=0x80; SCK=1; } RST=0; _nop_(); SCK=0; _nop_(); SCK=1; _nop_(); SDA=0; _nop_(); SDA=1; _nop_(); return (temp); }
4、Notes:
●Template与官方驱动没有实质性的变化。只是为了便于查找修改了子函数名,增加1us延时来稳定电平。
●还有最后的五行操作不知为啥,其他地方也没找到。 ●五、时钟设置
1、RCT寄存器:
2、Template:
uchar DS1302_Init_time[3]={ 23,59,50}; //DS1302初始化时间//------------------------------------------------DS1302时钟设置-----------------//void DS1302_Set_RCT(uchar *DS1302_Init_time){ uchar RCT; DS1302_Write_Byte(0X8E,0); //WP=0,允许写操作 RCT = ((DS1302_Init_time[0]/10)<<4)+(DS1302_Init_time[0]%10); DS1302_Write_Byte(0X84,RCT); //设置时 RCT = ((DS1302_Init_time[1]/10)<<4)+(DS1302_Init_time[1]%10); DS1302_Write_Byte(0X82,RCT); //设置分 RCT = ((DS1302_Init_time[2]/10)<<4)+(DS1302_Init_time[2]%10); DS1302_Write_Byte(0X80,RCT); //设置秒 DS1302_Write_Byte(0X8E,0X80); //WP=1,禁止写操作}
3、Notes:
●数组名是数组首元素的地址。数组表示法其实是在变相地使用指针。
●子函数定义了无符号指针型地形参,虽然形参名为数组名,但并不指向数组,形参名只是一个代表。 ●输入的shi实参为数组名,指向数组首元素的地址,用实参来代替符号式的形参。 ●允许写操作→写操作→关闭写操作 ●时钟设置子函数DS1302_Set_RCT()
将数据写入RCT寄存器组,来初始化时间,只需执行一遍。 ●时间信息(秒,分,时,日,月,年)是将十进制的十位和个位分开分别转化为8421BCD码存储在相关寄存器中的。 六、读取时钟
1、Template:
uchar DS1302_time[3]; //从DS1302读取到的实时时间 //------------------------------------------------DS1302读取时钟-----------------//void DS1302_Read_RCT(uchar *DS1302_time){ uchar RCT; RCT = DS1302_Read_Byte(0X85); //读取时 DS1302_time[0] = (RCT>>4)*10+(RCT&0X0F); RCT = DS1302_Read_Byte(0X83); //读取分 DS1302_time[1] = (RCT>>4)*10+(RCT&0X0F); RCT = DS1302_Read_Byte(0X81); //读取秒 DS1302_time[2] = (RCT>>4)*10+(RCT&0X0F); }
七、主函数
void main(void){ All_Init(); //开发板初始化 DS1302_Set_RCT(DS1302_Init_time); //设置初始时钟 while(1) { DS1302_Read_RCT(DS1302_time); //DS1302读取时钟 yi=DS1302_time[0]/10; er=DS1302_time[0]%10; san=23; si=DS1302_time[1]/10; wu=DS1302_time[1]%10; liu=23; qi=DS1302_time[2]/10; ba=DS1302_time[2]%10; SEG_1_2(yi,er); SEG_3_4(san,si); SEG_5_6(wu,liu); SEG_7_8(qi,ba); SEG_Init(); }}
转载地址:https://methadone-no1.blog.csdn.net/article/details/108060793 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
初次前来,多多关照!
[***.217.46.12]2024年05月01日 21时55分23秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Ant内置任务之whichresource
2019-05-01
Ant内置任务之symlink
2019-05-01
jface databinding:部分实现POJO对象的监测
2019-05-01
深入理解python--线程、进程与协程(1)
2019-05-01
Java--流重点总结初稿
2019-05-01
ImageView scaleType
2019-05-01
字符串的排序
2019-05-01
内存分配(mallloc,calloc,realloc,new)
2019-05-01
使用 Minidumps 和 Visual Studio .NET 进行崩溃后调试
2019-05-01
struts返回xml数据例子
2019-05-01
内存对齐详解
2019-05-01
秋招总结(一)-C++归纳
2019-05-01
秋招总结(三)-操作系统归纳
2019-05-01
带缓冲I/O 和不带缓冲I/O的区别与联系
2019-05-01
LINUX CP命令详解
2019-05-01
source insight快捷键及使用技巧
2019-05-01
映 射 ALT 键
2019-05-01
vim使用快捷键F4生成文件头注释、F5生成main函数模板、F6生成.h文件框架模板
2019-05-01