STM32 DS18B20温度采样 使用串口调试助手监控串口输出

 

   在Core/Src下创建ds18b20.c

#include "tim.h"
#include "gpio.h"
#include "main.h"

typedef struct w1_gpio_s
{
	GPIO_TypeDef    *group;
	uint16_t        pin;
}w1_gpio_t;

static w1_gpio_t W1Dat=
{
		.group=GPIOA,
		.pin=GPIO_PIN_12,
};

#define W1DQ_Input() \
{\
	GPIO_InitTypeDef GPIO_InitStruct={0};\
	GPIO_InitStruct.Pin=W1Dat.pin;\
	GPIO_InitStruct.Mode=GPIO_MODE_INPUT;\
	GPIO_InitStruct.Pull=GPIO_PULLUP;\
	GPIO_InitStruct.Speed=GPIO_SPEED_FREQ_HIGH;\
	HAL_GPIO_Init(W1Dat.group,&GPIO_InitStruct);\
}

#define W1DQ_Output() \
{\
	GPIO_InitTypeDef GPIO_InitStruct={0};\
	GPIO_InitStruct.Pin=W1Dat.pin;\
	GPIO_InitStruct.Mode=GPIO_MODE_OUTPUT_PP;\
	GPIO_InitStruct.Pull=GPIO_NOPULL;\
	GPIO_InitStruct.Speed=GPIO_SPEED_FREQ_HIGH;\
	HAL_GPIO_Init(W1Dat.group,&GPIO_InitStruct);\
}

#define W1DQ_Write(x)  HAL_GPIO_WritePin(W1Dat.group,W1Dat.pin,(x==1)?GPIO_PIN_SET:GPIO_PIN_RESET)
#define W1DQ_Read()    HAL_GPIO_ReadPin(W1Dat.group,W1Dat.pin)

uint8_t DS18B20_Reset(void)
{
	uint8_t rv=0;
	uint8_t retry;

	W1DQ_Output();
	W1DQ_Write(1);
	delay_us(2);

	W1DQ_Write(0);
	delay_us(480);

	W1DQ_Write(1);
	delay_us(60);

	while(W1DQ_Read()&&retry<240)
	{
		retry++;
		delay_us(1);
	}

	if(retry>=240)
	{
		rv=1;//异常退出return 1;
	}

	delay_us(240);

	W1DQ_Output();
	W1DQ_Write(1);
	delay_us(240);

	return rv;
}
void DS18B20_WriteByte(uint8_t byte)
{
	uint8_t i=0;

	W1DQ_Output();

	for(i=0;i<8;i++)
	{
		W1DQ_Write(0);
		delay_us(2);

		if(byte&0x1)
			W1DQ_Write(1);
		else
			W1DQ_Write(0);

		delay_us(60);

		W1DQ_Write(1);
		delay_us(2);

		byte>>=1;
	}

}

uint8_t DS18B20_ReadByte(void)
{
	uint8_t i=0;
	uint8_t byte=0;

	for(i=0;i<8;i++)
	{
		W1DQ_Output();
		W1DQ_Write(0);
		delay_us(2);
		W1DQ_Write(1);
		delay_us(2);

		W1DQ_Input();

		if(W1DQ_Read())
		{
			byte |= 1<<i;
		}

		delay_us(60);

		W1DQ_Output();
		W1DQ_Write(1);
		delay_us(2);

	}
	return byte;
}

static inline int DS18B20_Start_Convert(void)
{
	if( 0!=DS18B20_Reset() )
		return -1;

	DS18B20_WriteByte(0xCC);

	DS18B20_WriteByte(0x44);

	return 0;
}

static inline int DS18B20_Start_Read(uint8_t *buf,int bytes)
{
	if( 0!=DS18B20_Reset() )
		return -1;

	DS18B20_WriteByte(0xCC);

	DS18B20_WriteByte(0xBE);

	buf[0] = DS18B20_ReadByte();//LSB
	buf[1] = DS18B20_ReadByte();//MSB

	return 0;
}

int DS18B20_SampleData(float *temperature)
{
	uint8_t  byte[2];
	uint8_t  sign;
	uint16_t temp;

	if(!temperature)
		return -1;
	if(0!=DS18B20_Start_Convert())
		return -2;
	if(0!=DS18B20_Start_Read(byte,2))
		return -3;

/*
 * Temperature byte[0] is LSB,byte[1] is MSB,total 16 bit:
 * byte[0]:  bit[3:0]:decimal bits,   bit[7:4]:integer bits
 * byte[1]:  bit[2:0]:integer bits,   bit[7:3]:sign bits
 */
	if(byte[1]>0x7) /*bit[7:3] is 1*/
	{
		temp= ~(byte[1]<<8|byte[0]) +1;//补码
		sign=0;//温度为负
	}
	else
	{
		sign=1;//温度为正
		temp= byte[1]<<8 | byte[0];
	}

	/* byte[1]是大端字节序MSB(先输出高位),byte[0]是小端字节序LSB(先输出低位)
	 * byte[1]的低三位和byte[0]的高四位组成温度值的整数部分
	 * byte[0]的低四位为小数精度部分,且精度系数为0.0625
	 */
	*temperature = (temp>>4) + (temp&0xF)*0.0625;
	if(!sign)
	{
		*temperature=-*temperature;
	}

	return 0;
}

在Core/Inc下创建ds18b20.h

#ifndef INC_DS18B20_H_
#define INC_DS18B20_H_

extern int DS18B20_SampleData(float *temperature);

#endif  /*INC_DS18B20_H_*/

在main.c中,实现每隔3s采样当前温度值并打印输出

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "ds18b20.h"
/* USER CODE END Includes */

int main(void)
{
  /* USER CODE BEGIN 1 */
	float temperature;
  /* USER CODE END 1 */

  while (1)
  {

	if(DS18B20_SampleData(&temperature)<0)
	  {
		  printf("ERROR:DS18B20 Sample Data failure\r\n");
	  }
	  else
	  {
		  printf("DS18B20 Sample Temperature:%.3f \r\n",temperature);
	  }
	  HAL_Delay(3000);
    }    
}

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值