极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 17252|回复: 0

18B20 温度传感器读写探讨(转)

[复制链接]
发表于 2011-5-26 21:10:55 | 显示全部楼层 |阅读模式
原文地址:http://www.embedream.com/bjzm/2009-05-16/81.html
一、背景
       三年前,因为辅导几个大学生做课程设计,首次接触到 18B20 温度传感器,虽说Dallas公司的单总线协议很早就有关注,但实质性的编程一直没有做过,那是第一次。
       课程设计的主题就是温度测量,程序是以 18B20 为核心,倒也没有遇到太大障碍,还辅导他们成功的尝试了一条总线上采集两个传感器。
       也正是那次的经验,使我觉得这个温度传感器还挺好用,精度不错,而且能通过设置在速度和精度之间取得平衡,从而满足不同场合的需要。
        在第一代超声波测距传感器面世时就有客户提出温度补偿问题,所以这次设计第二代超声波测距传感器就顺带将 18B20 加入。
        由于是顺带,没有用心,所以不但将 PCB 位置画反了,这两天准备启用时,又发现漏了一个上拉电阻。可见凡事只要投入不够,必然会有“报应”
二、问题的提出
       此次使用温度传感器的需求有所不同,因为在超声波传感器上,温度测量只是配角,是为了弥补不同温度下音速不同带来的误差,而测距、通讯才是主要任务。
       着手编程前,仔细研究了 18B20 的手册和一些相关的参考资料,才发现存在不小的麻烦。
       首先,它对时序要求很高,而持续的时间却很尴尬,几十us一位,一个字节需要约 0.5ms,必须的复位操作约为 1ms。
        按照最简单的需求,至少要做如下操作:
        复位  skiprom  读命令  读温度低字节  读温度高字节  复位  启动转换
        大约需要 4.5ms。

        如果要考虑模式设置,则需要如下操作:
        复位  skiprom  读命令  读温度低字节  读温度高字节  复位  skiprom  写命令  TH TL  配置  复位  skiprom  启动转换
        这个过程就需要约 8.5 ms。

        这个时间如果让程序只做这一件事情,那系统中的其它任务自然会受到影响。
        测距是主动事件,还容易调度。可串口通讯完全是被动事件,必须随时响应,否则就会造成通讯失败。
        我目前设计的波特率是 19200,约 0.5ms 一字节。如果按照 18B20 通常的读写要求,必须关闭中断,则会由于中断不响应而丢失接收数据。
        这类问题在多数嵌入系统都会遇到。
        不止是通讯,还有一些信号采集,如小车的码盘采样。这类事件均由于其实时性要求而需要使用中断机制,关闭中断那么长时间一定会带来麻烦。
        这就提出了一个问题:
        能否像串口一样通过中断实现 18B20 可靠读写,用定时中断保证时序,从而与其它任务“并行”处理,互不影响。

        我看了很多 18B20 的读写程序,几乎是清一色的基于关中断的顺序操作,通过循环实现延时,形成读写时序。
        这样的程序似乎无法嵌入一个实时处理系统中,尤其是那些需要对外界信号做出实时响应的系统。
三、解决的尝试
        如果不能解决这个问题,那就意味着 18B20 不适合作为嵌入式系统的辅助测温手段,所以必须尝试解决之。
        幸好第二代超声波测距传感器所用的单片机速度较快,为通过定时中断保证时序,并在定时中断服务中做出相应处理提供了可能。
        STC12LE5410AD 虽说也是51系列单片机,但速度上大有改进,平均约为经典 51 的 8倍,按所使用的 22.1184Mhz 晶振计算,平均指令周期约为 0.1us。
        同时,它还有目前新型单片机都有的 PCA(可编程计数器阵列),可以实现比传统 51 定时器更灵活的定时方式。
        此外,它的I/O口支持开漏输出模式,正好符合 18B20 读写需要。
        根据 18B20 数据手册以及厂家应用指南 AN126,读写操作的位处理时序归纳如下:
       1、复位操作:
             输出 0 ,持续 480us
             输出 1 ,持续 70us
             读数据位,延时 410us

        2、写操作:
              输出 0, 持续 2us
              输出数据位,持续 58us
              输出 1, 持续 12us

        3、读操作:
              输出 0, 持续 2us
              输出 1, 持续 12us
              读数据位,延时 58us

        从上述时序看,处理方式可以是:
        持续 2us  —— 不需要延时处理,相应指令产生的延时就可以形成,或许还要优化,否则将超过 2us。

        持续 12us —— 在中断服务中使用循环延时,不能使用定时处理,因为时间太短。12us 时间不至于影响实时性。
        持续 58、70、410、480us —— 均可使用 PCA 的定时模式产生。这样,既保证了时序的准确性,同时又腾出了时间让别的中断和任务得到处理。
        按照前述平均指令周期,58us 可以执行约 500条指令,应该可以处理不少事情,比 58us 长的延时更是如此。
        这样处理,18B20 的读写操作在主程序中启动,之后全部由 PCA 的定时中断服务完成。
        和串口的处理类似,差别只是串口的位处理是由硬件完成,中断服务只需要处理字节。可读写 18B20 全靠软件实现。
        由于不是顺序的连续执行,所以会耗费一些变量,以记忆读写进行的状态和进程。
        同时需要构思相应的数据结构,使得中断中的处理尽量简单、高速。

四、结语
       经过努力,上述想法在第二代超声波测距传感器上得以实现。不过在数据结构设计、处理上费了不少周折。
        因为是用C语言编写,需要尝试何种数据结构、处理方式效率最高,似乎看上去逻辑清晰的处理方式速度并不快。
        最后所选的位时序处理方式是通过比较反汇编代码才确定的,勉强实现了 2us 的延时,实际约为 2.8us。
        如有兴趣,需要源程序,请通过邮件([email protected]) 对以下问题提出你的见解:
         1) 这个问题是否存在?
         2) 你是否遇到过这个问题?如何解决的?
         3) 用目前常用的处理方式能否解决?如果可以,如何做?
         4) 你对我所提出的构思有何看法?
         5) 你有无更好的构思解决此问题?

       最好是自己尝试一下,哪怕不成功也比直接索取别人的程序有意义,因为直接看别人的程序很费力,但如果自己编写过,看起来就容易许多。
       如果编写成功,期待交换,共同研讨。
       实际上,在RTOS中实现18B20读写似乎也是个挑战。


南京嵌入之梦工作室   
2009年5月16日星期六
参考资料:
1、DS18B20 数据手册
2、Dallas 公司 AN126 应用指南

回复

使用道具 举报

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

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-20 22:08 , Processed in 0.043407 second(s), 19 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表