STM32HAL库驱动DS18B20温度传感器

说明:控制器STM32L431RCT6  晶振12MHZ  配置时钟80MHZ

一、配置定时器(TIM6)

主要是用来做微秒级延时

相关微秒级延时函数

void DelayUs (uint16_t number)
{
	__HAL_TIM_SET_COUNTER(&TIM_Handle, 0);					//设置计数器的初值为0
	__HAL_TIM_ENABLE(&TIM_Handle);							//开启定时器
	while (__HAL_TIM_GET_COUNTER(&TIM_Handle) < number);	//比较计数器的值与要延时的时长
	__HAL_TIM_DISABLE(&TIM_Handle);							//关闭定时器
}

57abccd748e047feae61529cd47acde3.png

 二、作者采用的是串口打印温度数值,所以要配置一个串口(USART1)

相关的发送函数如下,串口不能直接发送数字,所以要采用sprintf转换,同时引用同文件“stdio.h”

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM6_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  float Tem = 0.0;
  char Data[20] = {0};

  /* USER CODE END 2 */

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

    /* USER CODE BEGIN 3 */
	 Tem = Data_TransFormation();
	 sprintf(Data,"%f",Tem);
	 HAL_Delay(300);
	 if(Tem >= 100)
	 {
		 HAL_UART_Transmit(&huart1, (uint8_t *)Data, 8, HAL_MAX_DELAY);  //串口发送函数
	 }
	 else
	 {
		 HAL_UART_Transmit(&huart1, (uint8_t *)Data, 7, HAL_MAX_DELAY);  
	 }

  }
  /* USER CODE END 3 */
}

dda2b6df401545c6a07e0993177f6083.png

 三、配置单总线的(DO)引脚;作者使用的是PA5引脚

只需要配置成推挽输出模式即可,初始电平为高电平

bbc9c2a835e5482f8ace7c301ff54689.png

 四、DS18B20.c和DS18B20.h文件如下:
 

/*
 * DS18B20.c
 *
 *  Created on: 2022年10月8日
 *      Author: LiangKeXue
 */
#include "DS18B20.h"

GPIO_InitTypeDef GPIO_Init;

/*
 * 	使用定时器延时1μS
 * 	时钟频率为80MHZ
 * 	预分频系数79
 * 	基本定时器为16位,最大延时65536μS
 */
extern TIM_HandleTypeDef htim6;		//引入定时器6
#define TIM_Handle htim6			//宏定义,方便更改定时器

void DelayUs (uint16_t number)
{
	__HAL_TIM_SET_COUNTER(&TIM_Handle, 0);					//设置计数器的初值为0
	__HAL_TIM_ENABLE(&TIM_Handle);							//开启定时器
	while (__HAL_TIM_GET_COUNTER(&TIM_Handle) < number);	//比较计数器的值与要延时的时长
	__HAL_TIM_DISABLE(&TIM_Handle);							//关闭定时器
}

/*
 * 	DS18B20初始化函数
 * 	向DS18B20发送ROM命令和功能性命令
 */
void DS18B20_Init(void)
{
	uint8_t counte = 0;
	GPIO_SET_OUT();									//DO引脚设置成输出模式
	DSDO_RESET();									//主机发送低电平信号
	DelayUs(750);
	DSDO_SET();										//主机释放总线,等待DS18B20回应
	GPIO_SET_IN();									//DO引脚设置成输入模式
	while(ReadPin() == GPIO_PIN_SET && counte<60)	//检测DS18B20是否回应低电平
	{
		counte++;
		DelayUs(1);
	}
	counte = 0;
	while(ReadPin() == GPIO_PIN_RESET && counte<240)//DS18B20回应脉冲信号
	{
		counte++;
		DelayUs(1);
	}
}

/*
 * 	向DS18B20写入数据
 * 	pData	要传入的8位数据
 */

void DS18B20_Write(uint8_t pData)
{
	GPIO_SET_OUT();							//DO引脚设置成输出模式
	uint8_t Bit = 0;
	for(Bit=0; Bit<8; Bit++)				//字节数据传输
	{
		if((pData & (0x01<<Bit)) != 0)		//按位写1
		{
			DSDO_RESET();					//DO引脚电平拉低
			DelayUs(2);
			DSDO_SET();						//DO引脚电平拉高
			DelayUs(60);
		}
		else								//按位写0
		{
			DSDO_RESET();					//DO引脚电平拉低
			DelayUs(60);
			DSDO_SET();						//DO引脚电平拉高
			DelayUs(2);
		}
	}
}

/*
 * 	读取DS18B20函数
 * 	pData	字节数据存放的位置
 */
uint16_t DS18B20_Read(void)
{
	uint16_t pData = 0;
	for(uint8_t Bit=0; Bit<16; Bit++)
	{
		GPIO_SET_OUT();											//DO引脚设置成输出模式
		DSDO_RESET();											//DO引脚电平拉低
		DelayUs(2);
		DSDO_SET();												//DO引脚电平拉高
		GPIO_SET_IN();											//DO引脚设置成输入模式
		DelayUs(12);
		if(ReadPin() == GPIO_PIN_SET)							//读DO引脚的电平
		{
			pData = pData | (0x0001<<Bit);						//按位置1
		}
		else
		{
			pData = pData & ((0xFFFE<<(16-Bit))|(0xFFFE>>Bit));	//按位清零
		}
		DelayUs(50);
	}
	return pData;
}

float Data_TransFormation(void)
{
	float Tem;
	uint16_t pData = 0;

	DS18B20_Init();							//DS18B20初始化
	DS18B20_Write(ROM_Skip);				//发送ROM命令(ROM跳过)
	DS18B20_Write(Temperature_Conversion);	//发送功能性指令(温度转换)

	HAL_Delay(750);							//温度转换时间

	DS18B20_Init();
	DS18B20_Write(ROM_Skip);
	DS18B20_Write(Read_Scratch_Reg);		//读取暂存寄存器

	pData = DS18B20_Read();					//读取温度的16位值
	if((pData & 0xF000) == 0)				//温度为零上时
	{
		Tem = pData*0.0625;					//补码等于原码,计算温度,12位精度为0.0625
		pData = 0;
		return Tem;
	}
	else									//温度为零下时
	{
		Tem = (65536-pData)*0.0625;			//补码转换成原码,计算温度
		pData = 0;
		return -Tem;
	}
}

/*
 * 	DO(PA5)引脚设置成输入模式,接上拉电阻
 */
void GPIO_SET_IN(void)
{
	GPIO_Init.Pin = GPIO_PIN_DO;
	GPIO_Init.Mode = GPIO_MODE_INPUT;
	GPIO_Init.Pull = GPIO_PULLUP;
	GPIO_Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

	HAL_GPIO_Init(GPIO_DO,&GPIO_Init);
}

/*
 * 	DO(PA5)引脚设置成推挽输出模式,初始高电平
 */
void GPIO_SET_OUT(void)
{
	GPIO_Init.Pin = GPIO_PIN_DO;
	GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_Init.Pull = GPIO_NOPULL;
	GPIO_Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	HAL_GPIO_WritePin(GPIO_DO, GPIO_PIN_DO, GPIO_PIN_SET);
	HAL_GPIO_Init(GPIO_DO,&GPIO_Init);
}

 

/*
 * DS18B20.h
 *
 *  Created on: 2022年10月8日
 *      Author: 79482
 */

#ifndef INC_DS18B20_H_
#define INC_DS18B20_H_

#include "main.h"

#define GPIO_PIN_DO GPIO_PIN_5		//设置DO引脚
#define GPIO_DO	 GPIOA

#define DSDO_SET()		HAL_GPIO_WritePin(GPIO_DO, GPIO_PIN_DO, GPIO_PIN_SET)		//DO引脚置1
#define DSDO_RESET()	HAL_GPIO_WritePin(GPIO_DO, GPIO_PIN_DO, GPIO_PIN_RESET)		//DO引脚清零
#define ReadPin()		HAL_GPIO_ReadPin(GPIO_DO, GPIO_PIN_DO)						//读取DO引脚

/*
 * 	ROM命令
 */
#define ROM_Search 		0xF0    //ROM搜索
#define ROM_Read 		0x33	//ROM读取
#define ROM_Matching 	0x55	//ROM匹配
#define ROM_Skip 		0xCC	//ROM跳过
#define Alert_Search	0xEC	//警报搜索

/*
 * 	DS18B20功能命令
 */
#define Temperature_Conversion	0x44	//温度转换
#define Write_Scratch_Reg		0x4E	//写入暂存寄存器
#define Read_Scratch_Reg		0xBE	//读取暂存寄存器
#define Copy_Scrath_Reg			0x48	//拷贝暂存寄存器
#define Recall_EEPROM			0xB8	//召回EEPROM
#define Read_Power_Mode			0xB4	//读取供电模式

void DelayUs (uint16_t number);

void GPIO_SET_IN(void);
void GPIO_SET_OUT(void);
void DS18B20_Init(void);
void DS18B20_Write(uint8_t pData);
uint16_t DS18B20_Read(void);
float Data_TransFormation(void);

#endif /* INC_DS18B20_H_ */

 

 

  • 14
    点赞
  • 87
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值