玩转DS1302和DS18B20.doc

上传人:豆**** 文档编号:28481871 上传时间:2022-07-28 格式:DOC 页数:50 大小:437KB
返回 下载 相关 举报
玩转DS1302和DS18B20.doc_第1页
第1页 / 共50页
玩转DS1302和DS18B20.doc_第2页
第2页 / 共50页
点击查看更多>>
资源描述

《玩转DS1302和DS18B20.doc》由会员分享,可在线阅读,更多相关《玩转DS1302和DS18B20.doc(50页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、Four short words sum up what has lifted most successful individuals above the crowd: a little bit more.-author-date玩转DS1302和DS18B20玩转DS1302和DS18B20对于市面上的大多数51单片机开发板来说。ds1302和ds18b20应该是比较常见的两种外围芯片。ds1302是具有SPI总线接口的时钟芯片。ds18b20则是具有单总线接口的数字温度传感器。下面让我们分别来认识并学会应用这两种芯片。 首先依旧是看DS1302的datasheet中的相关介绍。 上面是它的

2、一些基本的应用介绍。 下面是它的引脚的描述。 下面是DS1302的时钟寄存器。我们要读取的时间数据就是从下面这些数据寄存器中读取出来的。当我们要想调整时间时,可以把时间数据写入到相应的寄存器中就可以了。 这是DS1302内部的31个RAM寄存器。在某些应用场合我们可以应用到。如我们想要做一个带定时功能的闹钟。则可以把闹钟的时间写入到31个RAM寄存器中的任意几个。当单片机掉电时,只要我们的DS1302的备用电池还能工作,那么保存在其中的闹钟数据就不会丢失 由于对于这些器件的操作基本上按照数据手册上面提供的时序图和相关命令字来进行操作就可以了。因此在我们应用这些器件的时候一定要对照着手册上面的要

3、求来进行操作。如果觉得还不够放心的话。可以到网上下载一些参考程序。对着手册看别人的程序,看别人的思路是怎么样的。 DS1302和单片机的连接很简单。只需一根复位线,一根时钟线,一根数据线即可。同时它本身还需要接一个32.768KHz的晶振来提供时钟源。对于晶振的两端可以分别接一个6PF左右的电容以提高晶振的精确度。同时可以在第8脚接上一个3.6V的可充电的电池。当系统正常工作时可以对电池进行涓流充电。当系统掉电时,DS1302由这个电池提供的能量继续工作。 下面让我们来驱动它。 sbit io_DS1302_RST = P20 ; sbit io_DS1302_IO = P21 ; sbit

4、io_DS1302_SCLK = P22 ; /-常数宏-/ #define DS1302_SECOND_WRITE 0x80 /写时钟芯片的寄存器位置 #define DS1302_MINUTE_WRITE 0x82 #define DS1302_HOUR_WRITE 0x84 #define DS1302_WEEK_WRITE 0x8A #define DS1302_DAY_WRITE 0x86 #define DS1302_MONTH_WRITE 0x88 #define DS1302_YEAR_WRITE 0x8C #define DS1302_SECOND_READ 0x81 /读时

5、钟芯片的寄存器位置 #define DS1302_MINUTE_READ 0x83 #define DS1302_HOUR_READ 0x85 #define DS1302_WEEK_READ 0x8B #define DS1302_DAY_READ 0x87 #define DS1302_MONTH_READ 0x89 #define DS1302_YEAR_READ 0x8D /-操作宏-/ #define DS1302_SCLK_HIGH io_DS1302_SCLK = 1 ; #define DS1302_SCLK_LOW io_DS1302_SCLK = 0 ; #define D

6、S1302_IO_HIGH io_DS1302_IO = 1 ; #define DS1302_IO_LOW io_DS1302_IO = 0 ; #define DS1302_IO_READ io_DS1302_IO #define DS1302_RST_HIGH io_DS1302_RST = 1 ; #define DS1302_RST_LOW io_DS1302_RST = 0 ; /* * 保存时间数据的结构体 * */ struct uint8 Second ; uint8 Minute ; uint8 Hour ; uint8 Day ; uint8 Week ; uint8 M

7、onth ; uint8 Year ; CurrentTime ; /* * Function: static void v_DS1302Write_f( uint8 Content ) * * Description:向DS1302写一个字节的内容 * * Parameter:uint8 Content : 要写的字节 * * * */ static void v_DS1302Write_f( uint8 Content ) uint8 i ; for( i = 8 ; i 0 ; i- ) if( Content & 0x01 ) DS1302_IO_HIGH else DS1302_IO

8、_LOW Content = 1 ; DS1302_SCLK_HIGH DS1302_SCLK_LOW /* * Function: static uint8 v_DS1302Read_f( void ) * * Description: 从DS1302当前设定的地址读取一个字节的内容 * * Parameter: * * Return: 返回读出来的值(uint8) * */ static uint8 v_DS1302Read_f( void ) uint8 i, ReadValue ; DS1302_IO_HIGH for( i = 8 ; i 0 ; i- ) ReadValue = 1

9、 ; if( DS1302_IO_READ ) ReadValue |= 0x80 ; else ReadValue &= 0x7f ; DS1302_SCLK_HIGH DS1302_SCLK_LOW return ReadValue ; /* * Function: void v_DS1302WriteByte_f( uint8 Address, uint8 Content ) * * Description: 从DS1302指定的地址写入一个字节的内容 * * Parameter: Address: 要写入数据的地址 * * Content: 写入数据的具体值 * * Return: *

10、 */ void v_DS1302WriteByte_f( uint8 Address, uint8 Content ) DS1302_RST_LOW DS1302_SCLK_LOW DS1302_RST_HIGH v_DS1302Write_f( Address ) ; v_DS1302Write_f( Content ) ; DS1302_RST_LOW DS1302_SCLK_HIGH /* * Function: uint8 v_DS1302ReadByte_f( uint8 Address ) * * Description:从DS1302指定的地址读出一个字节的内容 * * Par

11、ameter:Address: 要读出数据的地址 * * * * Return: 指定地址读出的值(uint8) * */ uint8 v_DS1302ReadByte_f( uint8 Address ) uint8 ReadValue ; DS1302_RST_LOW DS1302_SCLK_LOW DS1302_RST_HIGH v_DS1302Write_f( Address ) ; ReadValue = v_DS1302Read_f() ; DS1302_RST_LOW DS1302_SCLK_HIGH return ReadValue ; /* * Function: void

12、v_ClockInit_f( void ) * * Description:初始化写入DS1302时钟寄存器的值(主程序中只需调用一次即可) * * Parameter: * * * * Return: * */ void v_ClockInit_f( void ) if( v_DS1302ReadByte_f( 0xc1) != 0xf0 ) v_DS1302WriteByte_f( 0x8e, 0x00 ) ; /允许写操作 v_DS1302WriteByte_f( DS1302_YEAR_WRITE, 0x08 ) ; /年 v_DS1302WriteByte_f( DS1302_WEE

13、K_WRITE, 0x04 ) ; /星期 v_DS1302WriteByte_f( DS1302_MONTH_WRITE, 0x12 ) ; /月 v_DS1302WriteByte_f( DS1302_DAY_WRITE, 0x11 ) ; /日 v_DS1302WriteByte_f( DS1302_HOUR_WRITE, 0x13 ) ; /小时 v_DS1302WriteByte_f( DS1302_MINUTE_WRITE, 0x06 ) ; /分钟 v_DS1302WriteByte_f( DS1302_SECOND_WRITE, 0x40 ) ; /秒 v_DS1302Writ

14、eByte_f( 0x90, 0xa5 ) ; /充电 v_DS1302WriteByte_f( 0xc0, 0xf0 ) ; /判断是否初始化一次标识写入 v_DS1302WriteByte_f( 0x8e, 0x80 ) ; /禁止写操作 /* * Function: void v_ClockUpdata_f( void ) * * Description:读取时间数据,并保存在结构体CurrentTime中 * * Parameter: * * * * Return: * */ void v_ClockUpdata_f( void ) CurrentTime.Second = v_DS1

15、302ReadByte_f( DS1302_SECOND_READ ) ; CurrentTime.Minute = v_DS1302ReadByte_f( DS1302_MINUTE_READ ) ; CurrentTime.Hour = v_DS1302ReadByte_f( DS1302_HOUR_READ ) ; CurrentTime.Day = v_DS1302ReadByte_f( DS1302_DAY_READ ) ; CurrentTime.Month = v_DS1302ReadByte_f( DS1302_MONTH_READ ) ; CurrentTime.Week =

16、 v_DS1302ReadByte_f( DS1302_WEEK_READ ) ; CurrentTime.Year = v_DS1302ReadByte_f( DS1302_YEAR_READ ) ; 有了上面的这些函数我们就可以对DS1302进行操作了。当我们想要获取当前时间时,只需要调用v_ClockUpdata_f( void )这个函数即可。读取到的时间数据保存在CurrentTime这个结构体中。至于如何把时间数据在数码管或者是液晶屏上显示出来我相信大家应该都会了吧_. 看看显示效果如何 下面再让我们看看DS18B20吧。 DS18B20是单总线的数字温度传感器。其与单片机的接口只

17、需要一根数据线即可。当然连线简单意味着软件处理上可能要麻烦一点。下面来看看它的优点: 看看它的靓照。外形和我们常用的三极管没有什么两样哦。 DS18B20的内部存储器分为以下几部分 ROM:存放该器件的编码。前8位为单线系列的编码(DS18B20的编码是19H)后面48位为芯片的唯一序列号。在出场的时候就已经设置好,用户无法更改。最后8位是以上56位的CRC码。 RAM:DS18B20的内部暂存器共9个字节。其中第一个和第二个字节存放转换后的温度值。第二个和第三个字节分别存放高温和低温告警值。(可以用RAM指令将其拷贝到EEPROM中)第四个字节为配置寄存器。第57个字节保留。第9个字节为前8

18、个字节的CRC码。 DS18B20的温度存放如上图所示。其中S位符号位。当温度值为负值时,S = 1 ,反之则S = 0 。我们把得到的温度数据乘上对应的分辨率即可以得到转换后的温度值。 DS18B20的通讯协议: 在对DS18B20进行读写编程时,必须严格保证读写的时序。否则将无法读取测温结果。根据DS18B20的通讯协议,主机控制DS18B20完成温度转换必须经过3个步骤:每一次读写之前都要对DS18B20进行复位,复位成功后发送一条ROM指令,最后发送RAM指令。这样才能对DS18B20进行预定的操作。 复位要求主机将数据线下拉500us,然后释放,DS18B20收到信号后等待16160

19、us然后发出60240us的存在低脉冲,主机收到此信号表示复位成功。 上图即DS18B20的复位时序图。 下面是读操作的时序图 这是写操作的时序图 下面让我们来看看它的驱动程序如何写吧。 sbit io_DS18B20_DQ = P23 ; #define DS18B20_DQ_HIGH io_DS18B20_DQ = 1 ; #define DS18B20_DQ_LOW io_DS18B20_DQ = 0 ; #define DS18B20_DQ_READ io_DS18B20_DQ /* * 保存温度值的数组.依次存放正负标志,温度值十位,个位,和小数位 * */ uint8 Temper

20、ature 4 ; void v_Delay10Us_f( uint16 Count ) while( -Count ) _nop_(); /* * Function: uint8 v_Ds18b20Init_f( void ) * * Description: 初始化DS18B20 * * Parameter: * * * * Return: 返回初始化的结果(0:复位成功 1:复位失败) * */ uint8 v_Ds18b20Init_f( void ) uint8 Flag ; DS18B20_DQ_HIGH /稍作延时 v_Delay10Us_f( 3 ) ; DS18B20_DQ_

21、LOW /总线拉低 v_Delay10Us_f( 80 ) ; /延时大于480us DS18B20_DQ_HIGH /总线释放 v_Delay10Us_f( 15 ) ; Flag = DS18B20_DQ_READ ; /如果Flag为0,则复位成功,否则复位失败 return Flag ; /* * Function: void v_Ds18b20Write_f( uint8 Cmd ) * * Description: 向DS18B20写命令 * * Parameter: Cmd: 所要写的命令 * * * * Return: * */ void v_Ds18b20Write_f( u

22、int8 Cmd ) uint8 i ; for( i = 8 ; i 0 ; i- ) DS18B20_DQ_LOW /拉低总线,开始写时序 DS18B20_DQ_READ = Cmd & 0x01 ; /控制字的最低位先送到总线 v_Delay10Us_f( 5 ) ; /稍作延时,让DS18B20读取总线上的数据 DS18B20_DQ_HIGH /拉高总线,1bit写周期结束 Cmd = 1 ; /* * Function: uint8 v_Ds18b20Read_f( void ) * * Description: 向DS18B20读取一个字节的内容 * * Parameter: *

23、* * * Return: 读取到的数据 * */ uint8 v_Ds18b20Read_f( void ) uint8 ReadValue, i ; for( i = 8 ; i 0 ; i- ) DS18B20_DQ_LOW ReadValue = 1 ; DS18B20_DQ_HIGH if( DS18B20_DQ_READ = 1 ) ReadValue |= 0x80 ; v_Delay10Us_f( 3 ) ; return ReadValue ; /* * Function: uint16 v_Ds18b20ReadTemp_f( void ) * * Description:

24、 读取当前的温度数据(只保留了一位小数) * * Parameter: * * * * Return: 读取到的温度值 * */ uint16 v_Ds18b20ReadTemp_f( void ) uint8 TempH, TempL ; uint16 ReturnTemp ; /* if( v_Ds18b20Init_() ) return ; /复位失败,在这里添加错误处理的代码 */ v_Ds18b20Init_f() ; /复位DS18B20 v_Ds18b20Write_f( 0xcc ) ; /跳过ROM v_Ds18b20Write_f( 0x44 ) ; /启动温度转换 v_

25、Ds18b20Init_f() ; v_Ds18b20Write_f( 0xcc ) ; /跳过ROM v_Ds18b20Write_f( 0xbe ) ; /读取DS18B20内部的寄存器内容 TempL = v_Ds18b20Read_f() ; /读温度值低位(内部RAM的第0个字节) TempH = v_Ds18b20Read_f() ; /读温度值高位(内部RAM的第1个字节) ReturnTemp = TempH ; ReturnTemp = 8 ; ReturnTemp |= TempL ; /温度值放在变量ReturnTemp中 return ReturnTemp ; /* *

26、 Function: void v_TemperatureUpdate_f( void ) * * Description:读取当前的温度数据并转化存放在数组Temperature(只保留了一位小数) * * Parameter: * * * * Return: * */ void v_TemperatureUpdate_f( void ) uint8 Tflag = 0 ; uint16 TempDat ; float Temp ; TempDat = v_Ds18b20ReadTemp_f() ; if( TempDat & 0xf000 ) Tflag = 1 ; TempDat = T

27、empDat + 1 ; Temp = TempDat * 0.0625 ; TempDat = Temp * 10 ; Temperature 0 = Tflag ; /温度正负标志 Temperature 1 = TempDat / 100 + 0 ; /温度十位值 Temperature 2 = TempDat % 100 / 10 + 0 ; /温度个位值 Temperature 3 = TempDat % 10 + 0 ;/温度小数位 如果想获取当前的温度数据,在主函数中调用v_TemperatureUpdate_f( void )就可以了。温度数据就保存到Temperature中去了。至于如何显示,就不用多说了吧_ 时间和温度一起显示出来看看 OK,至此ds18b20和ds1302的应用告一段落。如果有不懂的,记得多看datasheet,多交流。-

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 小学资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com