查看: 2802|回复: 2

关于51驱动DS18B20的一些看法

[复制链接]
  • TA的每日心情
    奋斗
    2017-2-23 17:29
  • 签到天数: 134 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2013-9-8 01:46:39 | 显示全部楼层 |阅读模式
    分享到:
    很多人用51第一次驱动DS18B20或多或少都会遇到一些问题。可能读出来是85.0,可能是e7.5(字符液晶显示),就是得不到正确值。而出现这些情况,基本上是时序错误导致(当然DS18B20损坏也会导致读出85)
    一般人喜欢直接把网上的驱动直接复制过来用,这也是导致时序出错的重要原因,因为对于DS18B20这种单总线操作的器件,其时序间隙是以微秒(us)计算的,而大部分都是使用一个While(x--)的方式来得到延时时间,这样对于不同系列的单片机,不同晶振都会导致延时时间发生变化,从而导致时序出错。使用STC系列单片机的,即使是同一个晶振下,不同系列(如12系列和89系列)也会导致该延时函数执行的时间不同,通常情况下该演示程序的执行时间会有几倍等级的变化。
    如何解决这个问题呢?以下是我的个人经验了。只提供大概思想,具体还是留给各位发挥吧
    首先,假定我有一个延时程序,延时时间就为1us*倍数(void Delay_us(unsigned char i)),最大为255 us。为什么不直接定义一个iunsigned nt型变量呢?这样不就可以延时65535us吗?实际上,DS18B20的时序间隙最大也就650us左右,如果使用unsigned int型变量一方面浪费内存,一方面增加延时时间确定的难易程度。
    按DS18B20的说明手册编写DS18B20的读写和复位时序。时序间隙时间都取要求时间间隙的中间值偏小一点。很多人认为自己写时序很困难,实际上,只有写过的人才清楚,DS18B20的时序真的很简单。
    最后写1us产生时间。我一般是这样确定的:写一个while(x--)的延时函数,如
    void Delay_Temp()  //?个机器周期*a  (标示执行一次的时钟周期方便以后不同频率时计算)
    {
    unsigned chat a=1;
    while(a--);
    }
    将a赋值为1,在main函数中调用该函数,编译后进入调试,单步执行,查看该子程序的汇编语句,查看单片机手册各汇编指令执行周期,将执行一次循环体的总时间周期标志在该函数名后注释。根据晶振计算一下执行一次的时间,用1us除去即得到a值,把a重新赋值,那么这个函数就是近似1us的程序了(对于1T单片机并且时钟大于10MHz,若是12T或6T时钟频率又较低的最好考虑进Call和RET指令的时间)。
    最后再编写一个
    Void Delay_us(unsigned char Set_us)
    {
      while(Set_us--)
       Delay_Temp();
    }
    以后换单片机(仅限于51)只要计算一下Delay_Temp的a值使该函数为1us即可。
    我使用以上的办法,在STC不同系列不同晶振的硬件中都完美驱动DS18B20,而且改动程序不超过5秒(只是计算一下a值而已)
    最后说一下为什么把DS18B20时间间隙设置为中间值偏小一点?很明显在之前延时函数时间的确定中,尤其是Delay_us中也是不断地循环调用Delay_Temp,会有额外的LCALL等指令时间。产生额外延时时间。若要计算得非常准确,可以在Delay_Temp的计算中加入进入该函数的LACLL等指令的值,以提高准确度。
    另外再提一下,有些人得到温度是使用浮点数计算,这是非常浪费资源的做法,通常我们都是使用乘法加移位的办法获得最终温度数据(定点小数,即获取的温度为整型值,显示时认为加小数点),这样代码量起码减少1KB。此外,温度是有符号数,这点很多人经常忽略了。
    还有,有人担心DS18B20自身发热会不会影响测量结果。经过实验对比,没什么影响
    DS18B20上电后第一次可能读出来是85,这是正常的,可通过软件方法屏蔽。
    使读出数据波动不大的办法,我采用的办法是连续读两次,若两次读取结果相同,则更新温度,而不是采用均值的办法。
    以上仅是个人一点经验,欢迎大家指正


    评分

    参与人数 1声望 +3 与非币 +5 收起 理由
    【小沫】 + 3 + 5

    查看全部评分

    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 09:14
  • 签到天数: 4023 天

    连续签到: 15 天

    [LV.Master]伴坛终老

    发表于 2013-9-8 09:58:26 | 显示全部楼层
    其实1-wire总线最主要的看懂其中的协议,Datasheet多看几遍就懂了。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2013-8-16 13:18
  • 签到天数: 5 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2013-9-18 21:10:08 | 显示全部楼层
    我一直没有写过时序,但是感觉这很重要,因为我在用STM32  的时候发现真的很需要时序的感觉
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-11-15 09:17 , Processed in 0.149147 second(s), 23 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.