【STM32+HAL】DS18B20读取环境温度

一、准备工作

有关CUBEMX的初始化配置,参见我的另一篇blog:【STM32+HAL】CUBEMX初始化配置

二、所用工具


1、芯片: STM32F407VET6

2、IDE: MDK-Keil软件

3、库文件:STM32F4xxHAL库

三、实现功能

串口打印当前温度值

四、HAL库配置

1、选择IO口连接输入输出端口DQ

2、打开串口

 

至此,HAL库配置完毕

五、Keil填写代码

1、us级延时函数
#define CPU_FREQUENCY_MHZ 168				/* CPU主频,根据实际进行修改 */


/**
 * 此延时函数代码适用于HAL库
 */
void delay_us(uint32_t delay)
{
    int last, curr, val;
    int temp;
    while (delay != 0)
    {
        temp = delay > 900 ? 900 : delay;
        last = SysTick->VAL;
        curr = last - CPU_FREQUENCY_MHZ * temp;
        if (curr >= 0)
        {
            do
            {
                val = SysTick->VAL;
            }
            while ((val < last) && (val >= curr));
        }
        else
        {
            curr += CPU_FREQUENCY_MHZ * 1000;
            do
            {
                val = SysTick->VAL;
            }
            while ((val <= last) || (val > curr));
        }
        delay -= temp;
    }
}

2、DS18B20.c
#include "ds18b20.h"
#include "tim.h"
#include "main.h"



#define CPU_FREQUENCY_MHZ 168				/* CPU主频,根据实际进行修改 */




/**
 * 此延时函数代码适用于HAL库
 */
void delay_us(uint32_t delay)
{
    int last, curr, val;
    int temp;
    while (delay != 0)
    {
        temp = delay > 900 ? 900 : delay;
        last = SysTick->VAL;
        curr = last - CPU_FREQUENCY_MHZ * temp;
        if (curr >= 0)
        {
            do
            {
                val = SysTick->VAL;
            }
            while ((val < last) && (val >= curr));
        }
        else
        {
            curr += CPU_FREQUENCY_MHZ * 1000;
            do
            {
                val = SysTick->VAL;
            }
            while ((val <= last) || (val > curr));
        }
        delay -= temp;
    }
}



static void DS18B20_IO_Init(void)
{
	/* 总线空闲为高电平 */
	HAL_GPIO_WritePin(DS18B20_GPIO_Port, DS18B20_Pin, GPIO_PIN_SET);
}




static void DS18B20_IO_OUT(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    GPIO_InitStruct.Pin = DS18B20_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(DS18B20_GPIO_Port, &GPIO_InitStruct);
}



static void DS18B20_IO_IN(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    GPIO_InitStruct.Pin = DS18B20_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(DS18B20_GPIO_Port, &GPIO_InitStruct);
}




static void DS18B20_DQ_OUT(int state)
{
    HAL_GPIO_WritePin(DS18B20_GPIO_Port, DS18B20_Pin, state ? GPIO_PIN_SET : GPIO_PIN_RESET);
}




static int DS18B20_DQ_IN(void)
{
    return HAL_GPIO_ReadPin(DS18B20_GPIO_Port, DS18B20_Pin) == GPIO_PIN_SET ? 1 : 0;
}






///
///  DS18B20驱动
///
///


//复位DS18B20
void DS18B20_Rst(void)
{
    DS18B20_IO_OUT(); 	//SET PA0 OUTPUT
    DS18B20_DQ_OUT(0); 	//拉低DQ
    delay_us(750);    	//拉低750us
    DS18B20_DQ_OUT(1); 	//DQ=1
    delay_us(15);     	//15US
}





//等待DS18B20的回应
//返回1:未检测到DS18B20的存在
//返回0:存在
uint8_t DS18B20_Check(void)
{
    uint8_t retry=0;
    DS18B20_IO_IN();//SET PA0 INPUT
    while (DS18B20_DQ_IN()&&retry<200)
    {
        retry++;
        delay_us(1);
    };
    if(retry>=200)return 1;
    else retry=0;
    while (!DS18B20_DQ_IN()&&retry<240)
    {
        retry++;
        delay_us(1);
    };
    if(retry>=240)return 1;
    return 0;
}





//从DS18B20读取一个位
//返回值:1/0
uint8_t DS18B20_Read_Bit(void) 			 // read one bit
{
    uint8_t data;
    DS18B20_IO_OUT();					//SET PA0 OUTPUT
    DS18B20_DQ_OUT(0);
    delay_us(2);
    DS18B20_DQ_OUT(1);
    DS18B20_IO_IN();					//SET PA0 INPUT
    delay_us(12);
    if(DS18B20_DQ_IN())data=1;
    else data=0;
    delay_us(50);
    return data;
}




//从DS18B20读取一个字节
//返回值:读到的数据
uint8_t DS18B20_Read_Byte(void)    // read one byte
{
    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)
{
    uint8_t j;
    uint8_t testb;
    DS18B20_IO_OUT();//SET PA0 OUTPUT;
    for (j=1; j<=8; j++)
    {
        testb=dat&0x01;
        dat=dat>>1;
        if (testb)
        {
            DS18B20_DQ_OUT(0);// Write 1
            delay_us(2);
            DS18B20_DQ_OUT(1);
            delay_us(60);
        }
        else
        {
            DS18B20_DQ_OUT(0);// Write 0
            delay_us(60);
            DS18B20_DQ_OUT(1);
            delay_us(2);
        }
    }
}




//开始温度转换
void DS18B20_Start(void)		// ds1820 start convert
{
    DS18B20_Rst();
    DS18B20_Check();
    DS18B20_Write_Byte(0xcc);	// skip rom
    DS18B20_Write_Byte(0x44);	// convert
}




//初始化DS18B20的IO口 DQ 同时检测DS的存在
//返回1:不存在
//返回0:存在
uint8_t DS18B20_Init(void)
{
	DS18B20_IO_Init();
    DS18B20_Rst();
    return DS18B20_Check();
}




//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值 (-550~1250)
short DS18B20_Get_Temp(void)
{
    uint8_t temp;
    uint8_t TL,TH;
    short tem;

    __disable_irq();    					/* 中断可能会单总线的时序从而导致读出来的温度值不正确,所以读取之前屏蔽中断 */

    DS18B20_Start();                    	// ds1820 start convert
    DS18B20_Rst();
    DS18B20_Check();
    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;								//获得底八位

    __enable_irq();    						/* 再将全局中断打开 */

    tem=(float)tem*0.625;					//转换
    if(temp) return tem; 					//返回温度值
    else return -tem;
}





/*
代码使用示例:

int main()
{
	short temp;

	while(DS18B20_Init())
	{
		printf(" ds18b20 init failed ! \r\n");
		HAL_Delay(1000);
	}

	while(1)
	{
		temp = DS18B20_Get_Temp();
		printf("当前温度:%0.2f \r\n", (float)temp / 10);
		HAL_Delay(1000);
	}
}

*/

3、DS18B20.h
#ifndef DS18B20_H__
#define DS18B20_H__

#include <stdint.h>

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_Check(void);		//检测是否存在DS18B20
void DS18B20_Rst(void);				//复位DS18B20

void delay_us(uint32_t delay);

#endif

六、巨人之肩

STM32 HAL库 DS18B20读取温度值 

【常用传感器】DS18B20温度传感器原理详解及例程代码

七、源码提供

资源【STM32+HAL】DS18B20读取环境温度

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/606648.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Day_3

1. HttpClient HttpClient是Apache的一个子项目&#xff0c;是高效的、功能丰富的支持HTTP协议的客户端编程工具包 作用&#xff1a;发送HTTP请求&#xff0c; 接受相应数据 <dependency><groupId>org.apache.httpcomponents</groupId><artifactId>…

Deep Learn Part Six Gated RNN-24.5.1

本章核心一句话&#xff1a; 卸下包袱&#xff0c;轻装上阵。--尼采 总述&#xff1a;本章所学内容 0.引子&#xff1a; 上一章介绍的 RNN 之所以不擅长学习时序数据的长期依赖关系&#xff0c;是因为 BPTT 会发生梯度消失和梯度爆炸的问题。本节我们将首先回顾一下上一章介…

21物联1班shift五次

1.选择推荐选项 2.等待 3.点击取消 4.选择查看问题详细信息 5.点击txt文件 6.找到system文件夹&#xff0c;将sethc改为qqq&#xff0c;将cmd文件改为sethc文件 7.单击完成。重新启动虚拟机。连续按五次shift出现cmd框&#xff0c;修改密码

MySql#MySql安装和配置

目录 一、卸载不需要的环境 二、安装mysql yum 源 三、开始安装 四、如果保证安装成功呢&#xff1f; 五、MySql 启动&#xff01; 六、登录mysql 七、配置文件说明 八、设置开机启动&#xff01; 本次安装是在Linux环境在centos7中完成 首先先将自己切换成root 一、…

彻底搞懂大小端存储and调试中内存窗口如何使用?

定义 首先我们有一个常识&#xff0c;Windows采用小端存储方式。 探究Windows下vs2019是什么存储&#xff1f; 在小端存储方式中&#xff0c;低字节存储在内存的低地址处&#xff0c;高字节存储在内存的高地址处。这与大端存储方式恰好相反&#xff0c;大端存储方式中高字节存…

[图解]DDD领域驱动设计浮夸,Eric Evans开了个坏头

0 00:00:00,630 --> 00:00:02,790 今天我们要讲的是 1 00:00:03,930 --> 00:00:07,420 DDD领域驱动设计浮夸 2 00:00:07,700 --> 00:00:10,590 Eric Evans开了个坏头 3 00:00:14,790 --> 00:00:17,380 在《领域驱动设计》的 4 00:00:18,650 --> 00:00:22,59…

QT:小项目:登录界面 (下一章连接数据库)

一、效果图 登录后&#xff1a; 二、项目工程结构 三、登录界面UI设计 四主界面 四、源码设计 login.h #ifndef LOGIN_H #define LOGIN_H#include <QDialog>namespace Ui { class login; }class login : public QDialog {Q_OBJECTpublic:explicit login(QWidge…

暴露自己IP地址有什么危险

暴露自己的IP地址确实存在一定的危险性&#xff0c;以下是关于这一问题的详细探讨&#xff1a; 一、IP地址的重要性 IP地址是互联网通信中的关键标识&#xff0c;它使得网络中的设备能够相互识别并进行数据传输。在网络世界中&#xff0c;每台设备都需要一个独特的IP地址来确…

2024蓝桥杯CTF writeUP--packet

根据流量分析&#xff0c;我们可以知道129是攻击机&#xff0c;128被留了php后门&#xff0c;129通过get请求来获得数据 129请求ls Respons在这 里面有flag文件 这里请求打开flag文件&#xff0c;并以base64编码流传输回来 获得flag的base64的数据 然后解码 到手

C语言 举例说明循环嵌套

今天 我们来说循环的嵌套 如果一个循环体内 又包含了另一个循环结构 我们称之为循环的嵌套 我们之前学的 While do-while for 都可以进行相互的嵌套 如下图 在 While 循环语句中再嵌套一个 While 循环语句 do-while 中嵌套 do-while for中嵌套 for 例如 我们做一个九九乘法…

mysql中varchar与bigint直接比较会导致精度丢失以至于匹配到多行数据

在mysql中&#xff0c;我们都知道如果一个索引字段使用了函数或者计算那么查询的时候索引会失效&#xff0c;可是我相信在联表的时候我们只会关注两个表关联字段是否都创建了索引&#xff0c;却没有关注过这两个字段的类型是否一致&#xff0c;如果不一致的话索引是会失效的&am…

Redis 实战3

系列文章目录 本文将从跳跃表的实现、整数集合来展开 Redis 实战 Ⅲ 系列文章目录跳跃表的实现跳跃表节点层 前进指针跨度 整数集合的实现升级升级的好处提升灵活性节约内存 降级整数集合 API总结 跳跃表的实现 Redis 的跳跃表由 redis.h/zskiplistNode 和 redis.h/zskiplist…

面向初学者:什么是图数据库

当数据成为关键生产要素&#xff0c;许多企业开始面临利用海量数据辅助企业复杂决策的现实难题。而在数据爆发式增长&#xff0c;关联复杂度激增的趋势下&#xff0c;图数据库成为企业加工关联数据、挖掘隐藏价值、智能决策升级的关键技术之一&#xff0c;在全球范围内开始被使…

如何更快地执行 Selenium 测试用例?

前言&#xff1a; 当我们谈论自动化时&#xff0c;首先想到的工具之一是 Selenium。我们都知道Selenium WebDriver 是一个出色的 Web 自动化工具。实施Selenium 自动化测试的主要原因是加速 selenium 测试。在大多数情况下&#xff0c;Selenium 的性能比手动的要好得多。但是&…

(2024,DONN,OCNN,复数域,交替的非线性激活层与振荡器层,复值反向传播)深度振荡神经网络

Deep Oscillatory Neural Network 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 1. 简介 2. 方法 2.1 深度振荡神经网络&#xff08;DONN&#xff09; 2.2 振荡卷积神经网…

人物特效游戏玩法,门坎低,适合新手上手项目【揭密】

项目简介&#xff1a; 本项目涉及我们日常使用的美肤产品和效果维持&#xff0c;我们需要提交自己的作品&#xff0c;完成官方网站发布的任务。任务完成后&#xff0c;提交审核&#xff0c;一旦审批通过&#xff0c;收益就会到账。 项 目 地 址 &#xff1a; laoa1.cn/1961.…

Python-VBA函数之旅-round函数

目录 一、round函数的常见应用场景 二、round函数使用注意事项 三、如何用好round函数&#xff1f; 1、round函数&#xff1a; 1-1、Python&#xff1a; 1-2、VBA&#xff1a; 2、推荐阅读&#xff1a; 个人主页&#xff1a; https://blog.csdn.net/ygb_1024?spm1010.2…

部署tomcat部署LNAMT

这里写目录标题 部署tomcatjava环境安装 部署LNAMT更改tomcat端口号 tomcat就是中间件之一&#xff0c;tomcat本身是一个容器&#xff0c;专门用来运行java程序&#xff0c;java语言开发的网页.jsp就应该运行于tomcat中。而tomcat本身的运行也依赖于jdk环境。 部署tomcat java…

LVS 负载均衡部署 NAT模式

一、环境准备 配置环境&#xff1a; 负载调度器&#xff1a;配置双网卡 内网&#xff1a;172.168.1.11(ens33) 外网卡&#xff1a;12.0.0.1(ens37)二台WEB服务器集群池&#xff1a;172.168.1.12、172.168.1.13 一台NFS共享服务器&#xff1a;172.168.1.14客户端&#xff…

2024年全网最新AI实景自动无人直播软件:引领智能直播新潮流;打造智能化、互动性强的直播平台

随着互联网的飞速发展&#xff0c;直播已经成为商家品牌推广和产品宣传的重要方式。然而&#xff0c;AI实景自动无人直播软件的问世&#xff0c;进一步推动了直播行业的智能化进程&#xff0c;为商家带来了全新的直播体验。&#xff08;ai无人自动直播大量招商加盟&#xff1b;…