esp32获取ds18b20温度,单总线

18b20.c

#include "ds18b20.h"

//复位DS18B20
//返回0为成功
uint8_t DS18B20_Rst(void)	   
{             
    gpio_set_direction(GPIO_PIN, GPIO_MODE_OUTPUT); 
	gpio_set_level(GPIO_PIN, 0); // 设置低电平
    esp_rom_delay_us(750);   	//拉低750us

    gpio_set_level(GPIO_PIN, 1); //DQ=1 
	esp_rom_delay_us(60);     	//60US

    gpio_set_direction(GPIO_PIN, GPIO_MODE_INPUT);
    uint8_t count=240;
    while (gpio_get_level(GPIO_PIN)&&count){
        count--;
    }
    gpio_set_direction(GPIO_PIN, GPIO_MODE_OUTPUT);
    gpio_set_level(GPIO_PIN, 1);
    esp_rom_delay_us(100);
    if (count)
    {
        return 0;
    }else{
        return 1;
    }
    
    
}
//从DS18B20读取一个位
//返回值:1/0
uint8_t DS18B20_Read_Bit(void) 	 
{
    gpio_set_direction(GPIO_PIN, GPIO_MODE_OUTPUT);
    uint8_t data;
    gpio_set_level(GPIO_PIN, 0);  
	esp_rom_delay_us(2);
    gpio_set_level(GPIO_PIN, 1); 

	gpio_set_direction(GPIO_PIN, GPIO_MODE_INPUT);
	esp_rom_delay_us(12);
	if(gpio_get_level(GPIO_PIN))data=1;
    else data=0;	 
    
    esp_rom_delay_us(50);     
    gpio_set_direction(GPIO_PIN, GPIO_MODE_OUTPUT);
    gpio_set_level(GPIO_PIN, 1);   
    return data;
}
//从DS18B20读取一个字节
//返回值:读到的数据
uint8_t DS18B20_Read_Byte(void)     
{        
    uint8_t i,j,dat;
    dat=0;
	for (i=1;i<=8;i++) 
	{
        j=DS18B20_Read_Bit();
        dat=(j<<7)|(dat>>1);
    }				    
    return dat;
}
//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_Write_Byte(uint8_t dat)     
 {             //1011 1110
    uint8_t j;
    uint8_t testb;
    gpio_set_direction(GPIO_PIN, GPIO_MODE_OUTPUT);
    gpio_set_level(GPIO_PIN, 1);     
    for (j=1;j<=8;j++) 
	{
        testb=dat&0x01;
        dat=dat>>1;
        if (testb) 
        {
            gpio_set_level(GPIO_PIN, 0); 	// Write 1
            esp_rom_delay_us(2);                         
            gpio_set_level(GPIO_PIN, 1);  
            esp_rom_delay_us(60);            
        }
        else 
        {
            gpio_set_level(GPIO_PIN, 0); 	// Write 0
            esp_rom_delay_us(60);                         
            gpio_set_level(GPIO_PIN, 1);  
            esp_rom_delay_us(2);                   
        }
    }
}
//开始温度转换
void DS18B20_Start(void) 
{   						               
    DS18B20_Rst();
    DS18B20_Write_Byte(0xcc);	// skip rom
    DS18B20_Write_Byte(0x44);	// convert
    
} 

//初始化DS18B20的IO口 DQ 同时检测DS的存在
//返回1:不存在
//返回0:存在    	 
uint8_t DS18B20_Init(void)
{
   // 配置GPIO引脚为推挽输出
    gpio_config_t io_conf = {
        .pin_bit_mask = (1ULL << GPIO_PIN),
        .mode = GPIO_MODE_OUTPUT,
        .intr_type = GPIO_INTR_DISABLE,
        .pull_down_en = GPIO_PULLDOWN_DISABLE,
        .pull_up_en = GPIO_PULLUP_DISABLE,
    };
    gpio_config(&io_conf);
    gpio_set_direction(GPIO_PIN, GPIO_MODE_OUTPUT);
    gpio_set_level(GPIO_PIN, 1);      //输出1


	return DS18B20_Rst();
}  
//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值 (-550~1250) 
short DS18B20_Get_Temp(void)
{
    uint8_t temp;
    uint8_t TL,TH;
	short tem;
    float f_t;
    DS18B20_Start ();  			// ds1820 start convert

    DS18B20_Rst(); 
    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;					//获得底八位
    
    f_t=(float)tem*0.0625;		//转换     
    printf("获取温度为:%f\n",f_t);
	if(temp)return tem; 		//返回温度值
	else return -tem;    
}



18b20.h

#ifndef __DS18B20_H
#define __DS18B20_H 

#include "ds18b20.h"
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp_rom_sys.h"
//IO方向设置


#define GPIO_PIN GPIO_NUM_26
   	
uint8_t DS18B20_Init(void); //初始化DS18B20
short DS18B20_Get_Temp(void);//获取温度
void DS18B20_Start(void);//开始温度转换
void DS18B20_Write_Byte(uint8_t dat);//写入一个字节
uint8_t DS18B20_Read_Byte(void);//读出一个字节
uint8_t DS18B20_Read_Bit(void);//读出一个位
uint8_t DS18B20_Rst(void);	  //复位DS18B20    
#endif


main.c

/* FreeRTOS Real Time Stats Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/

#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp_err.h"

#include "driver/gpio.h"
#include "ds18b20.h"

#define STATS_TASK_PRIO     3

/**
 * @brief   Function to print the CPU usage of tasks over a given duration.
 *
 * This function will measure and print the CPU usage of tasks over a specified
 * number of ticks (i.e. real time stats). This is implemented by simply calling
 * uxTaskGetSystemState() twice separated by a delay, then calculating the
 * differences of task run times before and after the delay.
 *
 * @note    If any tasks are added or removed during the delay, the stats of
 *          those tasks will not be printed.
 * @note    This function should be called from a high priority task to minimize
 *          inaccuracies with delays.
 * @note    When running in dual core mode, each core will correspond to 50% of
 *          the run time.
 *
 * @param   xTicksToWait    Period of stats measurement
 *
 * @return
 *  - ESP_OK                Success
 *  - ESP_ERR_NO_MEM        Insufficient memory to allocated internal arrays
 *  - ESP_ERR_INVALID_SIZE  Insufficient array size for uxTaskGetSystemState. Trying increasing ARRAY_SIZE_OFFSET
 *  - ESP_ERR_INVALID_STATE Delay duration too short
 */



static void stats_task(void *arg)
{


    while (1) {
        DS18B20_Get_Temp();
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}



void app_main(void)
{
    //Allow other core to finish initialization
    vTaskDelay(pdMS_TO_TICKS(100));


    while(DS18B20_Init()){
            printf("1:未检测到18b20\n");
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
    printf("18B20初始化成功\n");
    //Create and start stats task
    xTaskCreatePinnedToCore(stats_task, "stats", 4096, NULL, STATS_TASK_PRIO, NULL, tskNO_AFFINITY);



    

}

bug记录:
获取温度一直是0
解决:
DS18B20_Rst
复位函数中,最后加点延时