STM32 DS18B20温度传感器实验(HAL库)

   日期:2021-02-11     浏览:161    评论:0    
核心提示:STM32学习记录:DS18B20温度传感器实验(HAL库)实验摘要DS18B20简述STMCubeMX引脚配置芯片选型引脚和时钟配置生成ARM-MDK工程编写DS18B20驱动文件新建工程项目组编写DS18B20.c写时序读时序读取温度编写DS18B20.h主程序实现功能重定向printf函数包含头文件路径编译项目并下载到硬件中连接硬件线路检验结果总结实验摘要本文主要关于如何用STM32系列单片机驱动DS18B20温度传感器实现温度的串口打印显示,本实验中STM32基于HAL库开发。本文全程记录实验过

STM32学习记录:DS18B20温度传感器实验(HAL库)

  • 实验摘要
    • DS18B20简述
    • STMCubeMX引脚配置
      • 芯片选型
      • 引脚和时钟配置
    • 生成ARM-MDK工程
    • 编写DS18B20驱动文件
      • 新建工程项目组
      • 编写DS18B20.c
        • 写时序
        • 读时序
        • 读取温度
      • 编写DS18B20.h
    • 主程序实现功能
    • 重定向printf函数
    • 包含头文件路径
    • 编译项目并下载到硬件中
    • 连接硬件线路
    • 检验结果
    • 总结

实验摘要

本文主要关于如何用STM32系列单片机驱动DS18B20温度传感器实现温度的串口打印显示,本实验中STM32基于HAL库开发。本文全程记录实验过程,手把手教大家基于STM32的DS18B20温度采集实验。

DS18B20简述

首先,我们拿到DS18B20之后进行观察。

该器件只有3个引脚,分别为电源端VCC,地GND和数据线DQ。只有一条数据线,说明该器件是单总线器件。单总线器件好处是只占用一个单片机的一个I/O口。
DS18B20通信协议通过查阅DS18B20中文资料获得,该部分将在驱动文件编写部分详细讲解。

STMCubeMX引脚配置

本文使用STMCubeMX软件进行引脚和时钟的配置

芯片选型


本文选择STM32L431RC系列,根据自己的芯片选择。

引脚和时钟配置


引脚主要配置外部时钟输入输出口,串口通信USART1用于打印温度数据,传感器数据DQ接口(此处使用PA5)。
将HCLK配置为80MHz。

工程管理,设置项目名称和保存路径,选择MDK-ARM V5。

Code Generator中建议勾选Generate peripheral initialization as a pair of ‘.c/.h’ files per peripheral,为每个外设生成独立的.c文件。

生成ARM-MDK工程

点击GENERATE CODE生成ARM-MDK工程。

编写DS18B20驱动文件

新建工程项目组


单击红圈出现
这里可以自行添加文件管理项目结构,清晰明了。这里我们可以在Group新建一个文件夹Hardware用于存放DS18B20的驱动文件。(DS18B20.CDS18B20.h
接着在文件夹Hardware中添加DS18B20.CDS18B20.h

编写DS18B20.c

DS18B20中文资料
链接: https://pan.baidu.com/s/1k060r4s_5XI1R9r00jDP2g 提取码: nmr4 .
首先写一个粗略的微秒延时函数,用于单线协议中的延时。


void delay_us(uint32_t time)
{ 
  time *= 10;
	while(time)
		time--;
}

主机首先发出一个480-960微秒的低电平脉冲,然后释放总线变为高电平,并在随后的480微秒时间内对总线进行检测,如果有低电平出现说明总线上有器件已做出应答。若无低电平出现一直都是高电平说明总线上无器件应答。

做为从器件的DS18B20在一上电后就一直在检测总线上是否有480-960微秒的低电平出现,如果有,在总线转为高电平后等待15-60微秒后将总线电平拉低60-240微秒做出响应存在脉冲,告诉主机本器件已做好准备。若没有检测到就一直在检测等待。

我们需要配置引脚为输入或输出模式,需要两个函数。
发送复位信号和检测存在脉冲两个函数。
引脚输入输出配置函数参考gpio.c中的void MX_GPIO_Init(void)函数编写。


void DS18B20_IO_IN(void){ 
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.Pin = GPIO_PIN_5;
	GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
	HAL_GPIO_Init(GPIOA,&GPIO_InitStructure);
}



void DS18B20_IO_OUT(void){ 
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.Pin = GPIO_PIN_5;
	GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOA,&GPIO_InitStructure);
}



void DS18B20_Rst(void){ 
	DS18B20_IO_OUT();//引脚输出模式
	
	//拉低总线并延时750us
	DS18B20_DQ_OUT_LOW;
	delay_us(750);     
	
	//释放总线为高电平并延时等待15~60us
	DS18B20_DQ_OUT_HIGH;
	delay_us(15);
}
	


uint8_t DS18B20_Check(void){ 
	//定义一个脉冲持续时间
	uint8_t retry = 0;
	//引脚设为输入模式
	DS18B20_IO_IN();
	while(DS18B20_DQ_IN && retry < 200){ 
		retry++;
		delay_us(1);
	}
	
	if(retry >= 200)
		return 1;
	else
		retry = 0;
	
	//判断DS18B20是否释放总线
	while(!DS18B20_DQ_IN && retry < 240){ 
		retry++;
		delay_us(1);
	}
	
	if(retry >= 240)
		return 2;
	
	return 0;
}

写时序

写周期最少为60微秒,最长不超过120微秒。写周期一开始做为主机先把总线拉低1微秒表示写周期开始。随后若主机想写0,则继续拉低电平最少60微秒直至写周期结束,然后释放总线为高电平。若主机想写1,在一开始拉低总线电平1微秒后就释放总线为高电平,一直到写周期结束。而做为从机的DS18B20则在检测到总线被拉底后等待15微秒然后从15us到45us开始对总线采样,在采样期内总线为高电平则为1,若采样期内总线为低电平则为0。


void DS18B20_Write_Byte(uint8_t data){ 
	uint8_t j;
	uint8_t databit;
	DS18B20_IO_OUT();
	for(j=1;j<=8;j++){ 
		databit=data&0x01;//取数据最低位
		data=data>>1;     //右移一位
		if(databit){       //当前位写1
			DS18B20_DQ_OUT_LOW;
			delay_us(2);
			DS18B20_DQ_OUT_HIGH;
			delay_us(60);
		}else{           //当前位写0
			DS18B20_DQ_OUT_LOW;
			delay_us(60);
			DS18B20_DQ_OUT_HIGH;
			delay_us(2);
		}
	}
}

读时序


uint8_t DS18B20_Read_Bit(void){ 
	uint8_t data;
	DS18B20_IO_OUT();
	DS18B20_DQ_OUT_LOW;
	delay_us(2);
	DS18B20_DQ_OUT_HIGH;
	DS18B20_IO_IN();
	delay_us(12);
	
	if(DS18B20_DQ_IN)
		data = 1;
	else
		data = 0;
	
	delay_us(50);
	return data;
}



uint8_t DS18B20_Read_Byte(void){ 
	uint8_t i,j,data;
	data = 0;
	for(i=1;i<=8;i++){ 
		j = DS18B20_Read_Bit();
		data = (j<<7)|(data>>1);
		

	}
	return data;
}

读取温度

基本时序操作已经完成,再根据资料中的ROM命令编写DS18B20的启动函数。由于我们只使用一个DS18B20,所以可以直接跳过ROM。

DS18B20的ROM指令集

存储器指令


用到的指令

指令名称 指令代码
跳过ROM 0xCC
温度变换 0x44
读暂存器 0xBE

void DS18B20_Start(void){ 
	DS18B20_Rst();
	DS18B20_Check();
	DS18B20_Write_Byte(0xcc);//跳过ROM
	DS18B20_Write_Byte(0x44);//温度变换命令
}



uint8_t DS18B20_Init(void){ 
	//引脚初始化
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.Pin = GPIO_PIN_5;
	GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStructure.Pull = GPIO_PULLUP;
	GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	DS18B20_Rst();
	return DS18B20_Check();
}


short DS18B20_Get_Temperature(uint8_t a){ 
	uint8_t temp;
	uint8_t TL,TH;
	short temperature;
	
	DS18B20_Start();
	DS18B20_Rst();
	DS18B20_Check();
  DS18B20_Write_Byte(0xcc);//跳过ROM
	DS18B20_Write_Byte(0xbe);//读暂存器
	TL = DS18B20_Read_Byte();//低八位
	TH = DS18B20_Read_Byte();//高八位
	
	//判断温度值是否为负数
	if(TH>0x70){ 
		TH = ~TH;
		TL = ~TL;
		temp = 0;
	}else
		temp = 1;
	
	temperature = TH;
	temperature <<= 8;
	temperature += TL;
	temperature = (float)temperature*0.625;
	if(temperature)
		return temperature;
	else
		return -temperature;
}

在DS18B20.c开头包含头文件#include "DS18B20.h"

#include "DS18B20.h"

编写DS18B20.h

#include "stm32l4xx_hal.h"
#include "main.h"
#define DS18B20_DQ_OUT_HIGH HAL_GPIO_WritePin(DQ_GPIO_Port, DQ_Pin, GPIO_PIN_SET)
#define DS18B20_DQ_OUT_LOW HAL_GPIO_WritePin(DQ_GPIO_Port, DQ_Pin, GPIO_PIN_RESET)
#define DS18B20_DQ_IN HAL_GPIO_ReadPin(DQ_GPIO_Port, DQ_Pin)

头文件中要包含hal库头文件#include "stm32l4xx_hal.h"#include "main.h"
定义三个引脚操作函数。

主程序实现功能

用户包含



#include "DS18B20.h"

函数声明


uint8_t DS18B20_Init(void);
short DS18B20_Get_Temperature(void);


 float temperature;


  while(DS18B20_Init()){ 
	printf("DS18B20 checked failed!!!\r\n");
	HAL_Delay(500);
	}
	printf("DS18B20 checked success!!!\r\n");
  

    temperature = DS18B20_Get_Temperature();
		if(temperature < 0)
		printf("temperature = -%.2f degree\r\n",temperature/10);
		else
		printf("temperature = %.2f degree\r\n",temperature/10);
		HAL_Delay(200);}
  

重定向printf函数

在usart.c中添加printf重定向函数,该函数在不同信号芯片可能有不同。

#if 1
#include <stdio.h>

int fputc(int ch, FILE *stream)
{ 
    
    while((USART1->ISR & 0x40) == 0);

    
    USART1->TDR = (uint8_t) ch;

    return ch;
}
#endif

包含头文件路径

单击魔法棒图标
选择C/C++,在include path中添加文件路径。
…>>New(Insert)>>

选择DS18B20.c和DS18B20.h的路径。

编译项目并下载到硬件中

连接硬件线路


三条线路,连接之后DS18B20模块电源指示灯亮起。

检验结果

烧录程序,并打开串口助手,这里推荐win10应用市场的串口调试助手,可以免费下载。

我们看到温度数据可以被读取出来,可以用手捂一下传感器看温度是否有变化。实验完成!

总结

该实验完成了对DS18B20温度传感器的使用,主要重点是对单总线器件通信时序的学习,掌握了单总线器件时序的原理可以帮助我们使用其他的器件。

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服