3555|8

17

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

急需请教DS18B20的程序问题-----非常感谢! [复制链接]

请各位不吝赐教,刚学DSP2812。在读取温度值,单步测试时发现返回值是-1,不知怎么处理。采集这块是参考单片机的程序。谢谢!
  1. /*******************************************************************************
  2. * 函 数 名         : Ds18b20Init
  3. * 函数功能                   : 初始化
  4. * 输    入         : 无
  5. * 输    出         : 初始化成功返回1,失败返回0
  6. *******************************************************************************/

  7. uchar Ds18b20Init()
  8. {
  9.         uchar FLAG;
  10.         EALLOW;
  11.         DQ_DIR=1;     //设置为输出状态
  12.         EDIS;
  13.         DQ_DAT = 0;                         //将总线拉低480us~960us
  14.         DELAY_US(500);//延时642us
  15.         DQ_DAT= 1;                        //然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
  16.         DELAY_US(60);
  17.     EALLOW;
  18.         DQ_DIR=0;   //设置为输入状态
  19.         EDIS;
  20.         FLAG=DQ_DAT;   //读数据
  21.     DELAY_US(420);

  22.         return (FLAG);//初始化成功
  23. }

  24. /*******************************************************************************
  25. * 函 数 名         : Ds18b20WriteByte
  26. * 函数功能                   : 向18B20写入一个字节
  27. * 输    入         : com
  28. * 输    出         : 无
  29. *******************************************************************************/

  30. void Ds18b20WriteByte(uchar dat)
  31. {
  32.         uchar j;
  33.         EALLOW;
  34.         DQ_DIR=1;
  35.         EDIS;

  36.         for(j=0; j<8; j++)
  37.         {
  38.                 DQ_DAT= 0;
  39.                 DELAY_US(14);
  40.                 if(dat&0x01==1)          //写入一位数据
  41.             DQ_DAT= 1;
  42.                 else
  43.                 DQ_DAT= 0;
  44.                 DELAY_US(40);
  45.         //        DQ_DAT= dat & 0x01;  //然后写入一个数据,从最低位开始
  46.         //        DELAY_US(80);
  47.                 DQ_DAT= 1;        //然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
  48.                 dat >>= 1;
  49.                 DELAY_US(1);
  50.      }


  51. }
  52. /*******************************************************************************
  53. * 函 数 名         : Ds18b20ReadByte
  54. * 函数功能                   : 读取一个字节
  55. * 输    入         : com
  56. * 输    出         : 无
  57. *******************************************************************************/


  58. uchar Ds18b20ReadByte()
  59. {
  60.         uchar i=0,dat=0;
  61.         for(i=8; i>0; i--)
  62.         {
  63.                 dat>>=1;//读到数据后右移一位
  64.                 EALLOW;
  65.                 DQ_DIR=1; //设置为输出状态
  66.                 EDIS;
  67.         DQ_DAT= 0;//先将总线拉低1us
  68.                 DELAY_US(6);
  69.                 DQ_DAT= 1;//然后释放总线
  70.                 DELAY_US(8);
  71.                 EALLOW;
  72.                 DQ_DIR=0; //设置为输入状态
  73.                 EDIS;
  74.                 if(DQ_DAT)  dat|=0x80;//取回最高位数据
  75.                 DELAY_US(30);
  76.                 EALLOW;
  77.                 DQ_DIR=1;
  78.                 EDIS;
  79.                 DQ_DAT=1;
  80.         //        bi =DQ_DAT;         //读取数据,从最低位开始读取
  81.                 /*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/
  82.         //        byte = (byte >> 1) | (bi << 7);
  83.         //        DELAY_US(480);
  84.                         //读取完之后等待48us再接着读取下一个数

  85.         }

  86.         return dat;
  87. }
  88. /*******************************************************************************
  89. * 函 数 名         : Ds18b20ChangTemp
  90. * 函数功能                   : 让18b20开始转换温度
  91. * 输    入         : com
  92. * 输    出         : 无
  93. *******************************************************************************/

  94. void  Ds18b20ChangTemp()
  95. {
  96.         Ds18b20Init();
  97. //        DELAY_US(1000);
  98.         Ds18b20WriteByte(0xcc);                //跳过ROM操作命令
  99.         Ds18b20WriteByte(0x44);           //温度转换命令
  100. }

  101. /*******************************************************************************
  102. * 函 数 名         : Ds18b20ReadTempCom
  103. * 函数功能                   : 发送读取温度命令
  104. * 输    入         : com
  105. * 输    出         : 无
  106. *******************************************************************************/

  107. void  Ds18b20ReadTempCom()
  108. {

  109.         Ds18b20Init();
  110. //        DELAY_US(1000);
  111.         Ds18b20WriteByte(0xcc);         //跳过ROM操作命令
  112.         Ds18b20WriteByte(0xbe);         //发送读取温度命令
  113. }

  114. /*******************************************************************************
  115. * 函 数 名         : Ds18b20ReadTemp
  116. * 函数功能                   : 读取温度
  117. * 输    入         : com
  118. * 输    出         : 无
  119. *******************************************************************************/

  120. int Ds18b20ReadTemp()
  121. {
  122.         int temp = 0;
  123.         uchar tmh, tml;
  124.         Ds18b20ChangTemp();
  125.         Ds18b20ReadTempCom();                //然后等待转换完后发送读取温度命令
  126.         tml = Ds18b20ReadByte();                //读取温度值共16位,先读低字节
  127.         tmh = Ds18b20ReadByte();                //再读高字节
  128.         temp = tmh;
  129.         temp <<= 8;
  130.         temp |= tml;

  131.         return temp;
  132. }
  133. void LcdDisplay(int temp)          //lcd显示
  134. {

  135.           unsigned char datas[] = {0, 0, 0, 0, 0}; //定义数组
  136.   //        uchar str[]={0,0,0,0,0,0,0};
  137.         float tp;

  138.         if(temp< 0)                                //当温度值为负数
  139.           {
  140.                 Write_order(0x98);                //写地址 80表示初始地址
  141.                 Write_data('-');                  //显示负
  142.                 //因为读取的温度是实际温度的补码,所以减1,再取反求出原码
  143.                 temp=temp-1;
  144.                 temp=~temp;
  145.                 tp=temp;
  146.                 temp=tp*0.0625*100+0.5;
  147.                 //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
  148.                 //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
  149.                 //算由?.5,还是在小数点后面。

  150.           }
  151.         else
  152.           {
  153.                 Write_order(0x98);                //写地址 80表示初始地址
  154.                 Write_data('+');                 //显示正
  155.                 tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
  156.                 //如果温度是正的那么,那么正数的原码就是补码它本身
  157.                 temp=tp*0.0625*100+0.5;
  158.                 //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
  159.                 //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
  160.                 //算加上0.5,还是在小数点后面。
  161.         }


  162.         datas[0] = temp / 10000;
  163.         datas[1] = temp % 10000 / 1000;
  164.         datas[2] = temp % 1000 / 100;
  165.         datas[3] = temp % 100 / 10;
  166.         datas[4] = temp % 10;

  167.         Write_order(0x99);                  //写地址 80表示初始地址
  168.         Write_data('0'+datas[0]); //百位


  169.         Write_order(0x9A);                 //写地址 80表示初始地址
  170.         Write_data('0'+datas[1]); //十位

  171.         Write_order(0x9B);                //写地址 80表示初始地址
  172.         Write_data('0'+datas[2]); //个位

  173.         Write_order(0x9C);                //写地址 80表示初始地址
  174.         Write_data('.');                 //显示 ‘.’

  175.         Write_order(0x9D);                 //写地址 80表示初始地址
  176.         Write_data('0'+datas[3]); //显示小数点

  177.         Write_order(0x9E);                 //写地址 80表示初始地址
  178.         Write_data('0'+datas[4]); //显示小数点
  179. }
复制代码


最新回复

单步无法测试,因为时序问题。需要把延时考虑进去。可以考虑成品模块或仪表   详情 回复 发表于 2019-7-9 12:53
点赞 关注
 

回复
举报

374

帖子

3

TA的资源

一粒金砂(高级)

推荐
 
本帖最后由 wenyangzeng 于 2015-9-19 17:40 编辑

楼主:18B20初始化时的时序很重要,不同厂家的芯片延时时间不尽相同,我花了几天时间才搞定。你的初始化代码中:

        DQ_DAT = 0;                         //将总线拉低480us~960us
        DELAY_US(500);                   //延时642us
        DQ_DAT= 1;                        //然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
        DELAY_US(60);
    采用DS18B20时第一个延时大约要750uS,采用RX18B20则只能在400-650uS,而第二个延时由于紧接着是一个读时序,你延时60uS好像太久了,读到的数据有可能不准确了。我只用了15uS.
所有成败关键都在初始化中。祝你成功

点评

非常感谢!我的18B20前面是DALLAS,我试一下。开始的驱动程序是下载的基于DSP282的18B20程序,没想那么多。在示波器上倒是看到芯片发给的数据,而DSP这边好像没接收。真的非常感谢。  详情 回复 发表于 2015-9-19 18:24

赞赏

1

查看全部赞赏

 
 

回复

17

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
小妹在此先谢过各位。麻烦回复
 
 
 

回复

17

帖子

0

TA的资源

一粒金砂(中级)

4
 
wenyangzeng 发表于 2015-9-19 16:05
楼主:18B20初始化时的时序很重要,不同厂家的芯片延时时间不尽相同,我花了几天时间才搞定。你的初始化代 ...

非常感谢!我的18B20前面是DALLAS,我试一下。开始的驱动程序是下载的基于DSP282的18B20程序,没想那么多。在示波器上倒是看到芯片发给的数据,而DSP这边好像没接收。真的非常感谢。
 
 
 

回复

1291

帖子

0

TA的资源

纯净的硅(中级)

5
 
建议用个逻辑仪看看比较好,接受不到数据基本都是时序出了问题

点评

哦!好的,谢谢!  详情 回复 发表于 2015-9-20 11:03
 
 
 

回复

17

帖子

0

TA的资源

一粒金砂(中级)

6
 
强仔00001 发表于 2015-9-19 23:00
建议用个逻辑仪看看比较好,接受不到数据基本都是时序出了问题

哦!好的,谢谢!

点评

不用刻客气  详情 回复 发表于 2015-9-23 22:01
 
 
 

回复

1291

帖子

0

TA的资源

纯净的硅(中级)

7
 
qingtenglei 发表于 2015-9-20 11:03
哦!好的,谢谢!

不用刻客气
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

8
 

请问,您的问题解决了吗?

 

 
 
 

回复

203

帖子

0

TA的资源

一粒金砂(高级)

9
 

单步无法测试,因为时序问题。需要把延时考虑进去。可以考虑成品模块或仪表

个人签名北京长信物联科技有限公司
专业的USB温湿度传感器、485温湿度传感器、气体传感器、64路DS18B20温度采集模块厂商。
www.lct2000.cn
QQ:1930227091
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表