单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 178|回复: 6
收起左侧

求助!stm32F4驱动DS18B20温度传感器温度变化缓慢的问题

[复制链接]
lzjino 发表于 2019-8-1 10:56 | 显示全部楼层 |阅读模式
我用的是stm32F407VET6板子,接传感器ds18b20和dht11测温湿度,在lcd12864显示数据,lcd上湿度数据可以正常刷新,但温度数据隔很久才刷新一次,而且温度数据延迟很久,给ds18b20加热过四十多秒温度才变化一次,请问有大神帮帮我看一下代码吗?谢谢!
  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "led.h"
  5. #include "lcd.h"
  6. #include "dht11.h"
  7. #include "ds18b20.h"

  8. __align(4) u8 dtbuf[50];                                                                   //字符串缓存数组  

  9. int main(void)
  10. {
  11.        
  12.         u8 tmp,humi;                                //dht11温湿度
  13.         short temp;                                //ds18b20温度
  14.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //éèÖÃÏμí3ÖD¶ÏóÅÏ輶·Ö×é2
  15.         delay_init(168);  /
  16.         uart_init(38400);                /
  17.         InitDis();                                //LCD初始化
  18.        
  19.         DS18B20_Init();

  20.         while(DHT11_Init())
  21.         {
  22.                 lcd_DisStr(1,0,"DHT11 Error    ");
  23.                 delay_ms(200);
  24.                 lcd_clear();
  25.                 delay_ms(200);
  26.         }
  27.        
  28.         while(1)
  29.         {       
  30.                 temp = DS18B20_Get_Temp();        //读取ds18b20温度
  31.                 DHT11_Read_Data(&tmp,&humi);        //读取dht11湿度
  32.        
  33.                 //printf("温度: %3.1f C  湿度: %2d %%\r\n",temp,humi);  //串口调试用

  34.                         lcd_DisStr(1,0," Temp Humi is OK");
  35.                         lcd_DisStr(2,0,"                     ");
  36.                         sprintf((char *)dtbuf,"温度: %3.1f C     ",(double)temp/10);        //格式化字符串缓存
  37.                         lcd_DisStr(3,0,dtbuf);    //LCD显示
  38.                         sprintf((char *)dtbuf,"湿度: %2d %%      ",humi);        //格式化字符串缓存
  39.                         lcd_DisStr(4,0,dtbuf);    //LCD显示
  40.         }        
  41. }
复制代码
ds18b20.h

  1. #ifndef __DS18B20_H
  2. #define __DS18B20_H
  3. #include "sys.h"
复制代码
ds18b20.c
#include "ds18b20.h"
#include "delay.h"       

void DS18B20_Rst(void)          
{                 
        DS18B20_IO_OUT(); //SET PG11 OUTPUT
  DS18B20_DQ_OUT=0; //à-μíDQ
  delay_us(750);    //à-μí750us
  DS18B20_DQ_OUT=1; //DQ=1
        delay_us(15);     //15US
}


u8 DS18B20_Check(void)           
{   
        u8 retry=0;
        DS18B20_IO_IN();//SET PG11 INPUT         
    while (DS18B20_DQ_IN&&retry<200)
        {
                retry++;
                delay_us(1);
        };         
        if(retry>=200)return 1;
        else retry=0;
    while (!DS18B20_DQ_IN&&retry<240)
        {
                retry++;
                delay_us(1);
        };
        if(retry>=240)return 1;            
        return 0;
}


u8 DS18B20_Read_Bit(void)                          // read one bit
{
  u8 data;
        DS18B20_IO_OUT();//SET PG11 OUTPUT
  DS18B20_DQ_OUT=0;
        delay_us(2);
  DS18B20_DQ_OUT=1;
        DS18B20_IO_IN();//SET PG11 INPUT
        delay_us(12);
        if(DS18B20_DQ_IN)data=1;
  else data=0;         
  delay_us(50);           
  return data;
}


u8 DS18B20_Read_Byte(void)    // read one byte
{        
    u8 i,j,dat;
    dat=0;
        for (i=1;i<=8;i++)
        {
        j=DS18B20_Read_Bit();
        dat=(j<<7)|(dat>>1);
    }                                                    
    return dat;
}


void DS18B20_Write_Byte(u8 dat)     
{            
    u8 j;
    u8 testb;
          DS18B20_IO_OUT();//SET PG11 OUTPUT;
    for (j=1;j<=8;j++)
        {
        testb=dat&0x01;
        dat=dat>>1;
        if (testb)
        {
            DS18B20_DQ_OUT=0;// Write 1
            delay_us(2);                           
            DS18B20_DQ_OUT=1;
            delay_us(60);            
        }
        else
        {
            DS18B20_DQ_OUT=0;// Write 0
            delay_us(60);            
            DS18B20_DQ_OUT=1;
            delay_us(2);                          
        }
    }
}


void DS18B20_Start(void)// ds1820 start convert
{                                                                 
    DS18B20_Rst();          
          DS18B20_Check();         
    DS18B20_Write_Byte(0xcc);// skip rom
    DS18B20_Write_Byte(0x44);// convert
}
u8 DS18B20_Init(void)
{
        GPIO_InitTypeDef  GPIO_InitStructure;

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE)

  //GPIOC3
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//50MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP
  GPIO_Init(GPIOC, &GPIO_InitStructure)

        DS18B20_Rst();
        return DS18B20_Check();
}

short DS18B20_Get_Temp(void)
{
    u8 temp;
    u8 TL,TH;
          short tem;
    DS18B20_Start ();                    // ds1820 start convert
    DS18B20_Rst();
    DS18B20_Check();         
    DS18B20_Write_Byte(0xcc);// skip rom
    DS18B20_Write_Byte(0xbe);// convert            
    TL=DS18B20_Read_Byte(); // LSB   
    TH=DS18B20_Read_Byte(); // MSB   
    if(TH>7)
    {
        TH=~TH;
        TL=~TL;
        temp=0;/ 温度为负
    }else temp=1;//温度为正
    tem=TH; //获取高八位
    tem<<=8;   
    tem+=TL;//低八位
    tem=(double)tem*0.625;//转换
        if(temp)return tem; //返回温度值
        else return -tem;   
}







没有你 发表于 2019-8-1 13:39 | 显示全部楼层
对while(1)里面程序单步仿真一下,看看哪一条语句执行费时间。DS18B20_Check(void)  里面有超时退出,你看看是否多次出现超时情况
 楼主| lzjino 发表于 2019-8-1 17:35 | 显示全部楼层
没有你 发表于 2019-8-1 13:39
对while(1)里面程序单步仿真一下,看看哪一条语句执行费时间。DS18B20_Check(void)  里面有超时退出,你 ...

谢谢大佬的提示,发现问题了,是我用sprintf函数存字符串缓存太耗时间了,主程序执行时间明显变长,不知道为什么相同刷新频率下ds18b20的温度变化时间比dht11湿度变化时间久,难道是ds18b20读取很多次失败了?
 楼主| lzjino 发表于 2019-8-1 22:47 | 显示全部楼层
没有你 发表于 2019-8-1 13:39
对while(1)里面程序单步仿真一下,看看哪一条语句执行费时间。DS18B20_Check(void)  里面有超时退出,你 ...

谢谢提示!查了一下发现加入 lcd_DisStr()输出字符串会使串口调试时温度的刷新时间明显变长,湿度刷新三四次就可以让它变化,不知道为什么温度刷新十几次才变化一次数据?
这一生只为你 发表于 2019-8-2 09:39 | 显示全部楼层
我前阵子用OLED做显示也用到过类似的情况,刷新太慢,后来仔细查找问题,发现就是显示函数拖时间了,但是怎么修改OLED驱动程序也不行。后来解决问题了,就是固定不变的显示内容提前输出,并且在while循坏外,不参与刷新显示,只有变量在while内参与实时刷新,速度一下子就提上来了。
没有你 发表于 2019-8-2 11:04 | 显示全部楼层
lzjino 发表于 2019-8-1 22:47
谢谢提示!查了一下发现加入 lcd_DisStr()输出字符串会使串口调试时温度的刷新时间明显变长,湿度刷新 ...

能解决问题就好
aaaaaa。 发表于 2019-8-2 14:06 | 显示全部楼层
一般程序遇到问题,你最先做的事就是仿真,看看哪里出问题了
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

|手机版|小黑屋|单片机论坛 |51Hei单片机16群 联系QQ:125739409;技术交流QQ群7344883

Powered by 单片机教程网

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