搜索
bottom↓
回复: 27

18B20的时序是对的,为何读不出数据呢?

[复制链接]

出0入399汤圆

发表于 2014-10-23 15:38:54 | 显示全部楼层 |阅读模式
  1. uchar read_bit(void)  //读一位(bit)
  2. {
  3.         unsigned char i,j;
  4.         TRISC&=0xfd;//配置RC1为输出
  5.         RC1=0;       //将RC1拉低开始读时间隙
  6.         //RC1=1;  //then return high
  7.         for(i=0;i<1;i++);  // 延时
  8.         TRISC|=0x02;//配置RC1为输入
  9.         for(i=0;i<1;i++);
  10.         return(RC1);  // 返回RC1线上的电平值
  11. }

  12. uchar ReadOneChar(void) //读一个字节
  13. {
  14.         unsigned char i = 0;
  15.         unsigned char dat = 0;
  16.         for (i=0;i<8;i++)  
  17.         {   
  18.                 if(read_bit())
  19.                 dat|=(0x01<<i);    // 然后将其左移
  20.             Delay(4);
  21.         }
  22.     return (dat);
  23. }

  24. void write_bit(char bitval)        //写一位
  25. {
  26.         RC1=0;         // 将RC1拉低开始写时间隙
  27.         if(bitval==1)
  28.         RC1=1;   // 如果写1,RC1返回高电平
  29.         Delay(5);        // 在时间隙内保持电平值,
  30.         RC1=1;           // Delay函数每次循环延时16μs,因此delay(5) = 104μs
  31. }

  32. void WriteOneChar(unsigned char dat) //写一个字节
  33. {
  34.     unsigned char i = 0;
  35.     unsigned char temp;
  36.     for (i=0; i<8; i++)  // 写入字节, 每次写入一位  
  37.     {
  38.             temp=(dat>>i);  
  39.                    temp&=0x01;  
  40.                    write_bit(temp);
  41.     }
  42.     Delay(5);
  43. }
复制代码


在网上的找的51程序,移植到PIC的单片机上,主程序就这2句
WriteOneChar(0x33);       
a=ReadOneChar();
TXREG=a;
把18B20的序列号的第一位28h发生到串口;

出0入22汤圆

发表于 2014-10-23 15:42:51 | 显示全部楼层
没用过pic,看代码瞎猜,你读bit时候设置的输入端口,写bit的时候没看到设置为输出端口,不知道对不对

出0入399汤圆

 楼主| 发表于 2014-10-23 15:49:43 | 显示全部楼层
jiaowoxiaolu 发表于 2014-10-23 15:42
没用过pic,看代码瞎猜,你读bit时候设置的输入端口,写bit的时候没看到设置为输出端口,不知道对不对 ...

设置了。。你仔细看看你几行

出0入399汤圆

 楼主| 发表于 2014-10-23 15:50:33 | 显示全部楼层

时序图完全满足啊?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-10-23 15:53:09 | 显示全部楼层
真心觉得18B20难用,还容易受干扰,还不如用TC1047直接AD读,又便宜。

出0入0汤圆

发表于 2014-10-23 16:12:04 | 显示全部楼层
额,楼主是几个18B20啊?你这是想读取温度呢  还是读取序列号呢?

出0入0汤圆

发表于 2014-10-23 16:15:08 | 显示全部楼层
延时 对不对?

出0入399汤圆

 楼主| 发表于 2014-10-23 16:17:05 | 显示全部楼层
bi大痣 发表于 2014-10-23 16:12
额,楼主是几个18B20啊?你这是想读取温度呢  还是读取序列号呢?

1个,读序列号的第一个

出0入0汤圆

发表于 2014-10-23 16:29:55 | 显示全部楼层
额  一个的话没有必要直接读取温度就可以了,初始化的时候跳过序列号就可以了!不知道你为啥要读取序列号!要是想读取DS18B20的序列号的话,你主函数里有初始化DS18B20吗?

出0入399汤圆

 楼主| 发表于 2014-10-23 17:36:34 | 显示全部楼层
bi大痣 发表于 2014-10-23 16:29
额  一个的话没有必要直接读取温度就可以了,初始化的时候跳过序列号就可以了!不知道你为啥要读取序列号! ...

while1外面有读取,我看了下时序也是正确的:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-10-23 17:45:04 | 显示全部楼层
还是TC1047好用

出0入0汤圆

发表于 2014-10-23 17:56:02 | 显示全部楼层
1820并联没有试过,单个还是很好的,抗干扰,也很好,很温度,30米线寄生电源都很好的。

出0入42汤圆

发表于 2014-10-23 18:01:18 来自手机 | 显示全部楼层
貌似没给出复位脉冲!

出0入399汤圆

 楼主| 发表于 2014-10-23 18:12:01 | 显示全部楼层
n0831 发表于 2014-10-23 18:01
貌似没给出复位脉冲!

对应哪个时序图没有给复位脉冲??

出0入0汤圆

发表于 2014-10-23 18:32:18 | 显示全部楼层
温度转换时,需要的时间比较长,应该给足够延时

出0入42汤圆

发表于 2014-10-23 22:57:44 | 显示全部楼层
R88 发表于 2014-10-23 18:12
对应哪个时序图没有给复位脉冲??

18b20  的一个完整操作过程为 复位-rom操作指令-ram操作指令!
  你的程序里没见到有复位时序呢。

出0入42汤圆

发表于 2014-10-23 22:58:16 | 显示全部楼层
R88 发表于 2014-10-23 18:12
对应哪个时序图没有给复位脉冲??

18b20  的一个完整操作过程为 复位-rom操作指令-ram操作指令!
  你的程序里没见到有复位时序呢。

出0入0汤圆

发表于 2014-10-23 23:02:34 | 显示全部楼层
某个上啦没写···我曾经就是这样 在示波器上看了2天的温度显示····但单片机就是读不出来

出0入399汤圆

 楼主| 发表于 2014-10-24 08:54:59 | 显示全部楼层
n0831 发表于 2014-10-23 22:58
18b20  的一个完整操作过程为 复位-rom操作指令-ram操作指令!
  你的程序里没见到有复位时序呢。 ...

有啊,上面不是贴出来时序波形了么

出0入0汤圆

发表于 2014-10-24 09:17:15 | 显示全部楼层
R88 发表于 2014-10-23 17:36
while1外面有读取,我看了下时序也是正确的:

初始化多次?

出0入0汤圆

发表于 2014-10-24 09:53:25 | 显示全部楼层
线有几米长,长的话要用屏蔽线

还有就是要多复位,每次读都复位一下

出0入0汤圆

发表于 2014-10-24 10:05:24 | 显示全部楼层
检查电路,可以还一个传感器试试

出0入0汤圆

发表于 2014-10-24 10:09:57 | 显示全部楼层
也认为这个TC1047好用点。。。

出0入0汤圆

发表于 2014-10-24 10:11:50 | 显示全部楼层
480us 一定要够

出0入0汤圆

发表于 2014-10-24 10:15:21 | 显示全部楼层
曾做过 10来米线上IO口取电并30来个,通讯稳定可靠。
数据手册上写的很详细,记得大约步骤如下
先复位总线 -> 跳过ROM -> 启动温度转换 -> 延时 ->匹配ROM(总线上单个器件可跳过)-> 读数据->获取温度

出0入0汤圆

发表于 2014-10-24 10:51:21 | 显示全部楼层
产品中用到,一直不错,没出过问题

出0入399汤圆

 楼主| 发表于 2014-10-24 11:01:13 | 显示全部楼层
codeman 发表于 2014-10-24 10:15
曾做过 10来米线上IO口取电并30来个,通讯稳定可靠。
数据手册上写的很详细,记得大约步骤如下
先复位总线 ...
  1. uchar RomCode[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

  2. void Delay(uint num)
  3. {
  4.   while( --num );
  5. }

  6. uchar Init_DS18B20(void)  //初始化ds1820,RC1作为单总线通信口
  7. {   
  8.            uchar presence=1;
  9.            TRISC|=0x02;//配置RC1为输入
  10.     Delay(8);    //稍做延时
  11.     TRISC&=0xfd;//配置RC1为输出
  12.     RC1=0;      //将RC1拉低
  13.     Delay(150);   //精确延时 大于 480us
  14.     TRISC|=0x02;//配置RC1为输入
  15.     Delay(20);
  16.     presence=RC1;    //读取存在信号
  17.     Delay(8);  
  18.     return(presence); //返回信号,0=presence,1= no presence
  19. }

  20. bit read_bit(void)  //读一位(bit)
  21. {
  22.         unsigned char i;
  23.         TRISC&=0xfd;//配置RC1为输出
  24.         RC1=0;       //将RC1拉低开始读时间隙
  25.         TRISC|=0x02;//配置RC1为输入
  26.         return(RC1);  // 返回RC1线上的电平值
  27. }

  28. uchar ReadOneChar(void) //读一个字节
  29. {
  30.         unsigned char i = 0;
  31.         unsigned char dat = 0;
  32.         for (i=0;i<8;i++)  
  33.         {   
  34.                 if(read_bit())
  35.                 dat|=(0x01<<i);    // 然后将其左移
  36.             Delay(4);
  37.         }
  38.     return (dat);
  39. }

  40. void write_bit(uchar bitval)        //写一位
  41. {
  42.         TRISC&=0xfd;//配置RC1为输出
  43.         RC1=0;         // 将RC1拉低开始写时间隙
  44.         Delay(1);
  45.         if(bitval==1)
  46.         TRISC|=0x02;//配置RC1为输入   // 如果写1,RC1返回高电平
  47.         Delay(10);        // 在时间隙内保持电平值,
  48.         TRISC|=0x02;
  49. }

  50. void WriteOneChar(unsigned char dat) //写一个字节
  51. {
  52.     unsigned char i = 0;
  53.     unsigned char temp;
  54.     for (i=0; i<8; i++)  // 写入字节, 每次写入一位  
  55.     {
  56.             temp=(dat>>i);  
  57.                    temp&=0x01;  
  58.                    write_bit(temp);
  59.     }
  60.     Delay(5);
  61. }

  62. uchar Read_RomCord(void) //读取64位序列码
  63. {
  64.     unsigned char j;
  65.     Init_DS18B20();
  66.     WriteOneChar(0x33);  // 读序列码的操作
  67.     for (j = 0; j < 8; j++)
  68.         {
  69.                   RomCode[j] = ReadOneChar() ;  
  70.         }
  71.         return (RomCode[0]);
  72. }
  73.        
复制代码


while(1)里面就这三句:       
a=Read_RomCord();
TXREG=a;
delay_1ms();
我看过时序,波形完全对的,但是读得都是FF。
下面是时序图,完全跟Read_RomCord的时序一样:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入399汤圆

 楼主| 发表于 2014-10-24 12:13:34 | 显示全部楼层
搞定了,跟上次调AD一样,就差点延时。。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-5 05:14

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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