[STM32CubeMX learning] 1WIRE bus to read DS18B20 temperature

1. Introduction to 1WIRE bus

        The 1WIRE bus can complete the read and write operations with only one wire. The following uses STM32 as the host and DS18B20 as the slave to introduce various timings of the 1WIRE bus.

①Reset pulse: The host outputs a low level and keeps the low level for at least 480us, then the host releases the bus, delays 15-60us, and enters the receiving mode.

②Response pulse: The slave finds that the bus has a rising edge, pulls the bus low and keeps it for 60~240us, indicating a response.

③Write timing (write low bit first):

        Write "1": the master output low level, delay 2us, then release the bus, delay 60us.

        Write "0": the host outputs a low level, with a delay of 60us, and then release the bus, with a delay of 2us.

④Read timing: the host outputs a low level with a delay of 2us, then the host enters the input mode and delays for 12us, then reads the current level of the single bus, and obtains one bit of data 1/0 (low bit first), and then delays for 50us .

2. Introduction to DS18B20

Temperature measurement range: -55℃~+125℃.
Communication protocol: 1WIRE bus, the data line is connected to a pull-up resistor, so that the bus is at a high level when it is idle.
Conversion precision: 9 to 12-bit resolution is adjustable, the default is 12-bit, that is, the resolution is 0.0625.
Conversion time: 200ms typical.

 

There are 64-bit ROM units and 9-byte high-speed temporary registers inside the DS18B20. The 64-bit ROM unit contains the unique serial number of the DS18B20, because only one DS18B20 is used here, so don't care about the contents of this ROM. What needs attention is the 9-byte high-speed scratchpad:

byte0: The lower 8 bits of temperature data.
byte1: high 8 bits of temperature data.
byte2: TH user byte, set the maximum value of alarm temperature.
byte3: TL user byte, set the minimum value of alarm temperature.
byte4: Reserved.
byte5: Reserved.
byte6, 7: configuration register, set the conversion precision, the default is 12 bits.
byte8: CRC code

The temperature data format of DS18B20 is as follows:

BIT0~3: decimal part.
BIT4~10: Integer part.
BIT11~15:00000 is positive temperature, 11111 is negative temperature.

If the temperature is positive, directly multiply this value by 0.0625, if the temperature is negative, then invert this value and add one, then multiply by 0.0625.

3. Code to read temperature

ds18b20.h

#ifndef __DS18B20_H
#define __DS18B20_H	

#include "main.h"

//IO方向设置
#define DS18B20_GPIO_MODE_Pos    GPIO_CRH_MODE9_Pos                           
#define DS18B20_IO_IN   {ONEWIRE_DQ_GPIO_Port->CRH&=0XFFFFFF0F;GPIOB->CRH|=8<<GPIO_CRH_MODE9_Pos;}
#define DS18B20_IO_OUT {ONEWIRE_DQ_GPIO_Port->CRH&=0XFFFFFF0F;GPIOB->CRH|=3<<GPIO_CRH_MODE9_Pos;}

//IO操作函数											   
#define DS18B20_DQ_LOW      HAL_GPIO_WritePin(ONEWIRE_DQ_GPIO_Port,ONEWIRE_DQ_Pin,GPIO_PIN_RESET)
#define DS18B20_DQ_HIGH     HAL_GPIO_WritePin(ONEWIRE_DQ_GPIO_Port,ONEWIRE_DQ_Pin,GPIO_PIN_SET)

#define DS18B20_DQ_READ     HAL_GPIO_ReadPin(ONEWIRE_DQ_GPIO_Port,ONEWIRE_DQ_Pin)

short DS18B20_Get_Temp(void);

#endif

ds18b20.c

Read steps: reset -> send SKIP ROM command (0XCC) -> send start conversion command (0X44) -> delay -> reset -> send SKIP ROM command (0XCC) -> send read memory command (0XBE) -> Continuously read two bytes of temperature data -> end.

#include "ds18b20.h"	

//复位DS18B20
void DS18B20_Rst(void)	   
{                 
	DS18B20_IO_OUT;//设置为输出
	DS18B20_DQ_LOW;//拉低DQ
	Delay_Us(500);//拉低500us
	DS18B20_DQ_HIGH;//拉高DQ
	Delay_Us(20);//20us
}

//等待DS18B20的应答,返回值:0-非应答,1-应答
uint8_t Wait_DS18B20_ACK(void) 	   
{   
	uint8_t retry=0;
	DS18B20_IO_IN;//设置为输入
  while(DS18B20_DQ_READ&&(retry<200))
	{
		retry++;
		Delay_Us(1);
	}	 
	if(retry>=200)return 0;//超过200us未读到低电平,无应答
	else retry=1;//200us内转为低电平
  while ((!DS18B20_DQ_READ)&&(retry<240))
	{
		retry++;
		Delay_Us(1);
	}
	if(retry>=240)return 0;//低电平超过240us,无应答	    
	return 1;//低电平在240以内,有应答
}

//从DS18B20读取一位,返回值:1/0
uint8_t DS18B20_Read_Bit(void) 
{
	uint8_t data;
	DS18B20_IO_OUT;//设置为输出
	DS18B20_DQ_LOW; 
	Delay_Us(2);
	DS18B20_DQ_HIGH; 
	DS18B20_IO_IN;//设置为输入
	Delay_Us(12);
	if(DS18B20_DQ_READ)data=1;
	else data=0;	 
	Delay_Us(50);           
	return data;
}

//从DS18B20读取一个字节,返回值:读到的数据
uint8_t DS18B20_Read_Byte(void)   
{        
	uint8_t i,j,dat;
	dat=0;
	for(i=0;i<8;i++) 
	{
        j=DS18B20_Read_Bit();
        dat=(j<<7)|(dat>>1);
  }						    
	return dat;
}

//写一个字节到DS18B20,dat:要写入的字节
void DS18B20_Write_Byte(uint8_t dat)     
{             
  uint8_t j;
  uint8_t testb;
  DS18B20_IO_OUT;//设置为输出
  for (j=0;j<8;j++) 
	{
     testb=dat&0x01;
     dat=dat>>1;
     if(testb)//写1
     {
        DS18B20_DQ_LOW;
        Delay_Us(2);                            
        DS18B20_DQ_HIGH;
        Delay_Us(60);             
     }
     else//写0
     {
        DS18B20_DQ_LOW;
        Delay_Us(60);             
        DS18B20_DQ_HIGH;
        Delay_Us(2);                          
     }
  }
}
 
//开始温度转换
void DS18B20_Start(void)
{   						               
    DS18B20_Rst();	   
    Wait_DS18B20_ACK();	 
    DS18B20_Write_Byte(0xcc);//跳过64位ROM地址
    DS18B20_Write_Byte(0x44);//启动温度转换
}

//从ds18b20得到温度值,精度:0.1℃,返回值:温度值 (-550~1250) 
short DS18B20_Get_Temp(void)
{
    uint8_t TL,TH;
    short temp;
    DS18B20_Start ();//开始转换
    Delay_Ms(200); 
    DS18B20_Rst();
    Wait_DS18B20_ACK();	 
    DS18B20_Write_Byte(0xcc);  //跳过64位ROM地址
    DS18B20_Write_Byte(0xbe);  //读取暂存器数据	    
    TL=DS18B20_Read_Byte();  //LSB   
    TH=DS18B20_Read_Byte();  //MSB 
    
    temp = TH;//获得高八位
    temp<<=8;    
    temp+=TL;//获得底八位

    //分辨率为0.0625,这里比实际值大十倍
    if(TH>7)//温度为负 
        temp = -((~temp+1)*0.625); 
    else//温度为正
      temp = temp*0.625;  
    return temp;    
}

define global variables

short temperature;//温度值

Query in the main function

/* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

    temperature=DS18B20_Get_Temp();//获取温度值
    printf("temperature=%d.%d\r\n",temperature/10,temperature%10);
    Delay_Ms(1000);


  }
  /* USER CODE END 3 */

operation result

 

Guess you like

Origin blog.csdn.net/weixin_46183891/article/details/123466677