你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32的DS18B20的问题  

[复制链接]
H_JEN 提问时间:2016-5-2 17:21 /
本人现在在做基于STM32的DS18B20的测温,但是一直不成功。就拿初始化来说,按照时序图是先给低电平480us或以上,再给15us的高电平,然后就放开总线,18B20就开始复位。我的初始化程序时要看18B20有没有复位完成。但是我用示波器来看的时候前面给的开始信号是正确的,但是后面读18B20的复位输出的时候,18B20一直处于高电平.......为什么呢?
  1. char ds18b20_Reset(void)
  2. {
  3.         uint8_t count = 0,i = 0;        

  4.         GPIO_Out_Config();

  5.         DQ_L;
  6.         Delay_us(480);

  7.         DQ_H;
  8.         Delay_us(15);

  9.         GPIO_In_Config();//IPU模式能读数,但是一直为1,18b20可能坏了        
  10.         Delay_us(10);

  11.         while(count < 100)
  12.         {
  13.                 i = DQ_Read;
  14.                 if(i == 1)
  15.                 {
  16.                 NOP();
  17.                 count++;
  18.                 }
  19.                 else
  20.                         break;
  21.         }

  22.         if(count >= 100)
  23.                 return 0;
  24.         else
  25.                 count = 0;
  26.         while(count <240)
  27.         {
  28.                 i = DQ_Read;
  29.                 if(i ==0)
  30.                 {
  31.                 NOP();
  32.                 count++;
  33.                 }
  34.                 break;
  35.         }
  36.         if(count >= 240)
  37.                 return 0;
  38.         else
  39.                 return 1;
  40. }
复制代码
以上是初始化的,GPIO的输出模式是PP推挽,GPIO的输入模式是IPU上拉输入;
求大神指点一二啊

单片机是STM32F103ZET的,现在经过修改后,能读出数据,但是高八位要么全0,要么全1;低八位总是全0。而且18b20复位完成后,不发送任何指令,直接读数据口,读出来的有时是1,有时是0。根据时序图,复位完成后,数据口应该是一直高电平才对。
完整的程序如下:
  1. #include "stm32_18b20.h"

  2. void ds18b20_Config(void)
  3. {
  4.         unsigned char Init_Flag;

  5.         Init_Flag = ds18b20_Reset();
  6.         if(Init_Flag)
  7.                 printf("\r\n 1 \r\n");//复位成功
  8.         else
  9.         {
  10.                 printf("\r\n -1 \r\n");//复位失败
  11.                 while(1);
  12.         }               
  13. }

  14. void ds18b20_WriteCmd(uint8_t cmd)
  15. {
  16.         uint8_t i, ch;        

  17.         GPIO_Out_Config();

  18.         for(i = 0; i < 8; i++)
  19.         {
  20.                 ch = cmd;
  21.                 ch = ch & 0x01;
  22.                 cmd = cmd >> 1;
  23.                
  24.                 DQ_L;
  25.                 Delay_us(15);//起始15us低电平

  26.                 if(ch)//写入1                                
  27.                 {                                       
  28.                         DQ_H;
  29.                         NOP();NOP();NOP();NOP();NOP();
  30.                         DQ_L;                        
  31.                         Delay_us(65);        
  32.                 }                                       
  33.                 else//写入0                                
  34.                 {                                       
  35.                         DQ_L;
  36.                         Delay_us(65);
  37.                         DQ_H;
  38.                         NOP();NOP();NOP();NOP();NOP();               
  39.                 }                                
  40.         }
  41. }

  42. uint8_t ds18b20_ReadData(void)
  43. {
  44.         uint8_t i,s = 0, dat = 0, data = 0;

  45.         ds18b20_Config();        

  46.         for(i = 0; i < 8; i++)
  47.         {
  48.                 data = data >> 1;

  49.                 DQ_L;
  50.                 NOP();
  51.                 DQ_H;
  52.                 Delay_us(12);//放开总线
  53.                 s = DQ_Read;
  54.                 if(s)
  55.                         dat = 1;
  56.                 else
  57.                         dat = 0;
  58.                 Delay_us(45);
  59.                 s = 0;
  60.                 data = data | (dat << 7);               
  61.         }
  62.         return data;        
  63. }

  64. char ds18b20_Reset(void)
  65. {
  66.         uint8_t count = 0,i = 0;        

  67.         GPIO_Out_Config();

  68.         DQ_L;
  69.         Delay_us(480);//复位信号

  70.         DQ_H;
  71.         Delay_us(15);//释放总线

  72.         while(count < 100)
  73.         {
  74.                 i = DQ_Read;
  75.                 if(i == 1)
  76.                 {
  77.                 Delay_us(1);
  78.                 count++;
  79.                 }
  80.                 else
  81.                         break;
  82.         }

  83.         if(count >= 100)
  84.                 return 0;
  85.         else
  86.                 count = 0;
  87.         while(count <240)
  88.         {
  89.                 i = DQ_Read;
  90.                 if(i ==0)
  91.                 {
  92.                 Delay_us(1);
  93.                 count++;
  94.                 }
  95.                 break;
  96.         }
  97.         
  98.         if(count >= 240)
  99.                 return 0;
  100.         else
  101.                 {
  102.                         Delay_us(750);
  103.                         i = DQ_Read;
  104.                         printf("\r\n i = %d\r\n ",i);
  105.                         return 1;
  106.                 }               
  107. }

  108. void ds18b20_TransCmd(void)
  109. {
  110.         ds18b20_Config();

  111.         ds18b20_WriteCmd(0xcc);//1100 1100
  112.         ds18b20_WriteCmd(0x44);//0100 0100
  113. }

  114. void ds18b20_ReadCmd(void)
  115. {
  116.         ds18b20_Config();

  117.         ds18b20_WriteCmd(0xcc);//1100 1100
  118.         ds18b20_WriteCmd(0xbe);//1011 1110
  119. }

  120. float ds18b20_GetTemp(void)
  121. {
  122.         uint8_t tempH = 0, tempL = 0, temp = 0;
  123.         float tem = 0;

  124.         ds18b20_TransCmd();
  125.         Delay_ms(1000);
  126.         
  127.         ds18b20_ReadCmd();

  128.         tempL = ds18b20_ReadData();
  129.         tempH = ds18b20_ReadData();

  130. //        printf("\r\n 0x%d \r\n", tempH);
  131. //        printf("\r\n 0x%d \r\n", tempL);
  132.         
  133.         temp = (tempH << 8) + tempL;
  134.         tem =temp * 0.0625;
  135.         printf("\r\n tem %f \r\n", tem);

  136.         return tem;
  137. }

  138. void NOP(void)
  139. {
  140.         uint8_t i = 1;
  141.         i--;
  142. }
复制代码
用示波器看过延时程序的实现是正确的。复位函数里的复位信号给的也是正确的。
电路图里左边是电源线,中间是数据线,右边是地线
IMG_20160508_161413.jpg
捕获.PNG
<
收藏 3 评论55 发布时间:2016-5-2 17:21

举报

55个回答
aszrf 回答时间:2016-5-4 13:23:37
dsjsjf 回答时间:2016-5-4 13:25:54
设置成开漏输出,外接上拉电阻,使用时不需要切换输入输出,试试

评分

参与人数 1ST金币 +2 收起 理由
沐紫 + 2

查看全部评分

a6552918 回答时间:2016-5-4 13:26:10
应该配置为输入浮空。

评分

参与人数 1ST金币 +2 收起 理由
沐紫 + 2

查看全部评分

jinglixixi 回答时间:2016-5-4 13:27:41
DS18B20数据端是否加了上拉电阻。

评分

参与人数 1ST金币 +2 收起 理由
沐紫 + 2

查看全部评分

zhoupxa 回答时间:2016-5-4 13:32:37
GPIO应设置为漏极开路

评分

参与人数 1ST金币 +2 收起 理由
沐紫 + 2

查看全部评分

huaiqiao 回答时间:2016-5-4 13:37:57
其实这种Onewire的,要注意时序问题

评分

参与人数 1ST金币 +2 收起 理由
沐紫 + 2

查看全部评分

power568 回答时间:2016-5-4 13:41:29
确定总线时间和手册给出的时间是否严格匹配,最好留有余量。。。

评分

参与人数 1ST金币 +2 收起 理由
沐紫 + 2

查看全部评分

wolfgang2015 回答时间:2016-5-4 13:44:23
检查电路,DQ是否做了上拉

评分

参与人数 1ST金币 +2 收起 理由
沐紫 + 2

查看全部评分

风子 回答时间:2016-5-4 14:42:16
帮顶      
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版