新手求教:Ds18b20的测温程序

[复制链接]
5579|38
NE5532 发表于 2012-8-16 14:14 | 显示全部楼层
只有一个18B20没必要读序列号啊~
雷影少年 发表于 2012-8-16 11:46


这就是会写程序的人和不会写程序的人之间的本质区别,度序列号是用一个必然存在的东西来验证自己程序的正确性,序列号能读了,时序就基本正确了,才有资本去调其他的。
njaplid 发表于 2012-8-16 14:37 | 显示全部楼层
从程序上看,应该是时序的问题,DS18B20是单总线,时序要求较为苛刻。init初始化:需要拉低480us~960us,再释放总线。delay(80)应该不够。需要仔细看一下手册,可以下中文版的看。
jlass 发表于 2012-8-16 14:56 | 显示全部楼层
接示波器看时序啊,老大
你是不是干硬件的啊
zsyf0918 发表于 2012-8-16 14:57 | 显示全部楼层
找个成功的例子吧,
 楼主| Mr.Darcy 发表于 2012-8-16 15:06 | 显示全部楼层
To 18楼:
        18楼慧眼。第一次写这种程序,网上有借鉴+18b20的datasheet。
雷影少年 发表于 2012-8-16 22:02 | 显示全部楼层
这就是会写程序的人和不会写程序的人之间的本质区别,度序列号是用一个必然存在的东西来验证自己程序的正确性,序列号能读了,时序就基本正确了,才有资本去调其他的。 ...
NE5532 发表于 2012-8-16 14:14

是这样吗?难道不读序列号直接读出正确的温度不能说明时序是正确的?不明白你为什么会这么说?
雷影少年 发表于 2012-8-16 22:10 | 显示全部楼层
本帖最后由 雷影少年 于 2012-8-16 22:23 编辑

uint Get_temp()//读取温度
{
        uint a,b;
        init_ds18b20();
        write_ds18b20(0xcc);
        write_ds18b20(0x44);
       delay(20);  
      init_ds18b20();
和郭天翔书上的程序很像,没仔细看你程序,不过你好像温度转换的时间比较短,12位的转换时间是750ms以内,建议转换时间设的略长一些,
我有中文的资料需要的话留下邮箱
NE5532 发表于 2012-8-16 23:05 | 显示全部楼层
是这样吗?难道不读序列号直接读出正确的温度不能说明时序是正确的?不明白你为什么会这么说?
雷影少年 发表于 2012-8-16 22:02


先会走,才会跑,直接会跑的,是因为看了别人的例程,世界上不是所有的事情都有例程可寻,学会方法,从已知推未知,而不是靠运气去碰。学会这个,在真正的困难面前才能“硬”起来。
无名蚂蚁 发表于 2012-8-16 23:19 | 显示全部楼层
先会走,才会跑,直接会跑的,是因为看了别人的例程,世界上不是所有的事情都有例程可寻,学会方法,从已知推未知,而不是靠运气去碰。学会这个,在真正的困难面前才能“硬”起来

雷影少年 发表于 2012-8-16 23:29 | 显示全部楼层
本帖最后由 雷影少年 于 2012-8-16 23:38 编辑
先会走,才会跑,直接会跑的,是因为看了别人的例程,世界上不是所有的事情都有例程可寻,学会方法,从已知推未知,而不是靠运气去碰。学会这个,在真正的困难面前才能“硬”起来。 ...
NE5532 发表于 2012-8-16 23:05

您说的没错,凡事应该循序渐进,这是事物发展的客观规律。
但是在使用DS18B20的时候,如果是多点测试,为了确认采集温度时使用的是哪个探测器需要读取序列号,如果是单点采集的话就没必要来读取序列号了吧~读取温度和读取序列号的区别只是写入的功能指令不一样吧!
读取温度和读取序列号都需要对DS18B20进行初始化、写、读操作~如果需要验证初始化、读操作、写操作的时序是否正确,读取温度和读取操作数都可以
个人觉得验证时序只需要用软件仿真就行,软件仿真的时候将温度设为0~99度,只需要两个7segBCD就能够直接显示出当前温度,比起显示序列号要简单的多
没有太多的经历,新手往往会因为经验等原因往往会做出错误的判断却又不知自己错在哪儿,但是本菜鸟却又是不撞南墙不回头,还请多多指点
雷影少年 发表于 2012-8-16 23:42 | 显示全部楼层
下面是我写的DS18B20读取温度的程序
  1. /************************************************
  2. *名称: DS18B20温度传感器设计子程序
  3. *说明: 外部电源供电,温度值为整数值,无报警功能
  4. ***************************************************/
  5. #include<reg51.h>
  6. #include"typedef.h"
  7. #include"DS18B20.h"

  8. sbit        DQ=P1^5;          //温度传感器信号线

  9. //延时函数
  10. /*void delay(u8 x)
  11. {
  12.         u8        a;
  13.         for(x;x>0;x--)
  14.                 for(a=100;a>0;a--);
  15. }
  16. */

  17. void rest()                   //DS18B20复位函数
  18. {
  19.          u8        i;
  20.          DQ=1;
  21.          DQ=0;
  22.          i=250;
  23.          while(--i);                   //约500周期
  24.          DQ=1;
  25.          i=30;
  26.          while(--i);                   //30周期
  27.          while(DQ);                           //等待总线应答--拉低
  28.          i=100;                                   //200周期
  29.          while(--i);
  30. }




  31. bit        tempreadbit()                  //读一位数据
  32. {
  33.         u8        i;
  34.         bit        dat;
  35.         DQ=1;
  36.         DQ=0;
  37.         i++;                                  //延时1个周期
  38.         DQ=1;
  39.         i=4;
  40.         while(--i);                          //延时9周期
  41.         dat=DQ;
  42.         i=25;
  43.         while(--i);                          //延时50个周期
  44.         return        dat;
  45. }

  46. u8        tempread()                                //读一个字节的数据
  47. {
  48.           u8        i,j,dat;
  49.         dat=0;
  50.         for(i=0;i<8;i++)
  51.         {
  52.                 j=tempreadbit()&0x01;
  53.                 dat=(j<<7)|(dat>>1);
  54.         }
  55.         return        dat;
  56. }

  57. void tempwrite(u8        dat)                //写一个字节数据
  58. {
  59.         u8        i,j;
  60.         for(i=0;i<8;i++)
  61.         {
  62.                 DQ=1;
  63.                 DQ=0;
  64.                 j++;
  65.                 DQ=dat&0x01;
  66.                 j=30;
  67.                 while(j--);
  68.                 DQ=1;
  69.                 dat>>=1;
  70.         }       
  71.        
  72. }


  73. void tempchang()                          //开始获取温度并转换
  74. {
  75.            rest();
  76.         tempwrite(0xcc);
  77.         tempwrite(0x44);
  78. }

  79. u16 RDtemp()                                //开始读取温度
  80. {
  81.         u8        Th,Tl,temp;
  82.         u16        Temp;
  83. //        float        F_temp;
  84.         rest();
  85.         tempwrite(0xcc);
  86.         tempwrite(0xbe);
  87.         Tl=tempread();
  88.         Th=tempread();
  89.         Temp=Th;
  90.         Temp<<=8;
  91.         Temp=Temp|Tl;
  92.         Temp>>=4;
  93. //        F_temp=Temp*0.0625;
  94. //        Temp=F_temp*8+0.5;
  95.         temp=Temp;
  96.         return        temp;
  97. }
本菜鸟脸皮比较厚,大家尽管批,有则改之无则加勉~:lol
NE5532 发表于 2012-8-17 08:18 | 显示全部楼层
您说的没错,凡事应该循序渐进,这是事物发展的客观规律。
但是在使用DS18B20的时候,如果是多点测试,为了确认采集温度时使用的是哪个探测器需要读取序列号,如果是单点采集的话就没必要来读取序列号了吧~读取温度 ...
雷影少年 发表于 2012-8-16 23:29


你能直接读温度,是因为有仿真软件帮你,如果我只给你个万用表,你还能写出DS18B20的驱动程序不?单个温度计确实不需要读ROM,但是复位以后ROM将自动送出,是一个必然的现象,我们抓住这个必然的现象可以完成基本的字节读取函数的编写,确保读是对的,就可以调写,读写都对了,就可以操作寄存器了。

虽然你凭仿真解决了一个18B20的问题,但是你没有学到基本的探索未知世界的原理,当更复杂的问题摆在你面前的时候(比如你要调试RF通讯),这时候没有仿真,没有资料,甚至网上都没有人给你说怎么做,这时候除了靠你自己之外别无选择,你就知道思路和方法的宝贵了。
ocon 发表于 2012-8-17 10:13 | 显示全部楼层
对新手来说,没人会付费让你写这么简单的测温程序,学习方法才是主要目的。

评分

参与人数 1威望 +3 收起 理由
poren + 3 赞一个!

查看全部评分

wznpmm 发表于 2012-8-17 11:29 | 显示全部楼层
晶振不对哦!
雷影少年 发表于 2012-8-17 11:43 | 显示全部楼层
32# NE5532
我好像找到我们出现分歧的原因了:我的观点是立足于验证DS18B20时序的正确性,您是根据多年来工作的经验来说明应该解决类似问题的思路
NE5532 发表于 2012-8-17 17:02 | 显示全部楼层
对,当更复杂的问题摆在你面前的时候,特别是没有人能帮助你的时候,方法就很重要了,其中最基本的方法就是——从已知推未知
雷影少年 发表于 2012-8-17 18:14 | 显示全部楼层
对,当更复杂的问题摆在你面前的时候,特别是没有人能帮助你的时候,方法就很重要了,其中最基本的方法就是——从已知推未知
NE5532 发表于 2012-8-17 17:02

是啊~
alaic123 发表于 2013-3-1 10:55 | 显示全部楼层
学习 LS各位说的很有理 菜鸟在这学习了
poren 发表于 2013-3-3 19:22 | 显示全部楼层
我也是一个老大个的菜鸟,但33楼版主说的好:“对新手来说,没人会付费让你写这么简单的测温程序,学习方法才是主要目的”
试想现在哪个公司需要这样的测温。
当在工作岗位时,最重要的还是解决问题的方法,调试是很难得,通过闭上眼几秒制定的调试方案是高手和菜鸟的最大区别。
但楼主是个好学生。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部