【STM32/HAL】嵌入式课程设计:简单的温室环境监测系统|DS18B20 、DHT11

前言  

  板子上的外设有限,加上想法也很局限,就用几个传感器实现了非常简单的监测,显示和效应也没用太复杂的效果。虽说很简单,但传感器驱动还是琢磨了不久,加上串口线坏了,调试了半天才发现不是代码错了而是线有问题,总而言之,课设不复杂,难度不高,凑合看吧。

电路图

系统的需求描述

温室环境监测系统的功能性需求描述如下:

1.光照监测与响应

系统对光敏电阻进行 AD 采样获取环境光照强度。当环境光照减弱至预设阈值以下时, 系统会自动点亮绿灯以提供照明。同时,LED 灯闪烁报警,蜂鸣器需发出报警声。

2.温度监测与响应

系统通过 DS18B20 数字温度传感器和 DHT11 数字湿温度传感器获取温室环境温度, 以两者平均值作为测量的温度。当温度低于预设的下限阈值时,系统自动启动加热装置进行 加热(开发板并无加热设备,这里使用点亮红灯来模拟),直到温度上升至正常水平。当温 度高于预设的上限阈值时,系统需驱动电机旋转(风扇)以进行散热。并且,温度异常(过 高或过低)时,LED 灯闪烁报警,蜂鸣器需发出报警声。

3.湿度监测与响应

系统通过 DHT11 数字湿温度传感器获取环境湿度。当湿度超出预设的正常范围时, LED 灯闪烁报警,蜂鸣器需发出报警声。湿度太高时,还会亮起蓝灯。湿度太低时,会驱动 电机模拟启动灌溉设备。

4.数据显示

LCD 屏幕会实时显示光照、温度和湿度的数据信息。显示要做到清楚、直观,更新频率 适中。

5.串口通信

上位机和系统能通过串口进行通信,系统能够将光照、温度和湿度的采样数据实时发送 给上位机,上位机可以将数据存储到本地文件或上传到云服务器,实现了环境数据的采集、 传输、存储,可以为后续大数据处理提供数据支持。数据传输需稳定可靠,数据格式要遵守 通信协议。

6.按键控制

管理员可以通过按键开关报警功能和手动开关全彩灯。按键操作简单直观,响应时间快, 如果系统自动化调整功能失效,还可以通过手动方式调整设备。 

结构图

 详细设计

只说明传感器的部分

DS18B20 模块:

用于环境温度的数据采集。

DS18B20 是常用的数字温度传感器,单总线结构。该传感器体积小、硬件开销低、抗干扰能力强、误差小。一般在启动传感器并与之通信前,需要先经过 ROM 检测,但是开发板上只挂载了一个 DS18B20 设备,可以在初始化总线之后直接发送 0xcc 跳过 ROM 检查。使用 Convert T 开始温度转化命令(0x44)开始温度转化之后,经过一定时间,DS18B20 会将温度转化之后的数据存储到暂存器内。通过 Read Scratchpad 读取命令(0xBE) 可以从暂存器读数据。只采集温度数据所以只用接受前两个字节,高八位的高五位是符号位,高八位的低三位和低八位的高四位表示温度的整数位,低八位的低四位表示小数位。在本系统中温度数据保留一位小数。该模块对应文件为"ds18b20.h"和"ds18b20.c"。

相关的讲解可看(这两篇文章并不是使用的stm32,主要看模块的时序):

蓝桥杯电子类单片机学习二——DS18B20温度传感器(onewire驱动)_蓝桥杯板子用ds18b20-CSDN博客

51单片机-18B20温度传感器-CSDN博客

 参考代码:

适配stm32板子 、hal库

#include "ds18b20.h"
#include "tim.h"


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

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

void DS18B20_Rst(void)
{
	DS18B20_IO_OUT();
	DS18B20_DQ_OUT_LOW;
	delay_us_by_Tim(750);
	DS18B20_DQ_OUT_HIGH;
	delay_us_by_Tim(15);
}
	
uint8_t DS18B20_Check(void)
{
	uint8_t retry = 0;
	DS18B20_IO_IN();
	while(DS18B20_DQ_IN && retry < 200)
	{
		retry++;
		delay_us_by_Tim(1);
	}
	
	if(retry >= 200)
		return 1;
	else
		retry = 0;
	
	while(!DS18B20_DQ_IN && retry < 240)
	{
		retry++;
		delay_us_by_Tim(1);
	}
	
	if(retry >= 240)
		return 1;
	
	return 0;
}

uint8_t DS18B20_Read_Bit(void)
{
	uint8_t data;
	DS18B20_IO_OUT();
	DS18B20_DQ_OUT_LOW;
	delay_us_by_Tim(2);
	DS18B20_DQ_OUT_HIGH;
	DS18B20_IO_IN();
	delay_us_by_Tim(12);
	
	if(DS18B20_DQ_IN)
		data = 1;
	else
		data = 0;
	
	delay_us_by_Tim(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;
}

void DS18B20_Write_Byte(uint8_t data)
{
	uint8_t j;
	uint8_t testb;
	DS18B20_IO_OUT();
	for(j=1;j<=8;j++)
	{
		testb=data&0x01;
		data=data>>1;
		if(testb)
		{
			DS18B20_DQ_OUT_LOW;
			delay_us_by_Tim(2);
			DS18B20_DQ_OUT_HIGH;
			delay_us_by_Tim(60);
		}
		else
		{
			DS18B20_DQ_OUT_LOW;
			delay_us_by_Tim(60);
			DS18B20_DQ_OUT_HIGH;
			delay_us_by_Tim(2);
		}
	}
}

void DS18B20_Start(void)
{
	DS18B20_Rst();
	DS18B20_Check();
	DS18B20_Write_Byte(0xcc);
	DS18B20_Write_Byte(0x44);
}

uint8_t DS18B20_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.Pin = GPIO_PIN_2;
	GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStructure.Pull = GPIO_PULLUP;
	GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOE,&GPIO_InitStructure);
	
	DS18B20_Rst();
	return DS18B20_Check();
}

short DS18B20_Get_Temperature(void)
{
	//uint8_t temp;
	uint8_t TL,TH;
	short temperature;
	
	DS18B20_Start();
	DS18B20_Rst();
	DS18B20_Check();
	DS18B20_Write_Byte(0xcc);
	DS18B20_Write_Byte(0xbe);
	TL = DS18B20_Read_Byte();
	TH = DS18B20_Read_Byte();
	
	if(TH>7)
	{
		TH = ~TH;
		TL = ~TL;
	//	temp = 0;
	}
//	else
//		temp = 1;
	
	temperature = TH;
	temperature <<= 8;
	temperature += TL;
	temperature = (float)temperature*0.625;//0.0625*10,保留小数一位,后面处理的时候要除以10
	
	if(temperature)
		return temperature;
	else
		return -temperature;
}

DHT11 模块:

用于环境温度和湿度的数据采集。

DHT11 数字湿温度传感器采用单总线数据格式。即,单个数据引脚端口完成输入输出双向传输。一次完整的数据传输为 40bit,高位先出,数据格式为:8bit 湿度整数数据+8bit 湿度小数数据+8bit 温度整数数据+8bit 温度小数数据+8bit 校验和,校验和数据为前四个字节相加。

DHT11 传输时序为:总线空闲状态为高电平,主机把总线拉低等待 DHT11 响应(总线拉低必须大于 18 毫秒,保证 DHT11 能检测到起始信号),主机发送开始信号结束后,延时等待 20-40us,DHT11 接收到主机的开始信号后,等待主机开始信号结束,然后发送 80us(一般存在误差,20-100us 都可以认为是正常响应时间)低电平响应信号。如果读取总线为低电平,说明 DHT11 发送响应信号,如果读取总线为高电平,则 DHT11 没有响应。DHT11 发送响应信号后,再把总线拉高,准备发送数据,每 1bit 数据都以 50us 低电平时隙开始,告诉主机开始传输一位数据了。当 50us 低电平时隙过后拉高总线,高电平持续 26~28us 表示数据“0”;持续 70us 表示数据“1”。由于存在误差,程序中在延时 40us 后检测总线状态,为高说明该位数据为“1”,为低说明该位数据为“0”。当最后 1bit 数据传送完毕后,

DHT11 拉低总线 50us,表示数据传输完毕,随后总线由上拉电阻拉高进入空闲状态。该模块对应文件为"dht11.h"和"dht11.c"。

该模块可从下面博客移植:

HAL库:

STM32F103ZET6——DHT11温湿度传感器(hal库)_dht11stm32f103-CSDN博客

 标准库(主要参考其的时序讲解):

DHT11详细介绍(内含51和STM32代码)-CSDN博客

基于STM32的温湿度传感器(DHT11)+OLED屏显示(超详细)_stm32控制dht11-CSDN博客

参考代码

(注意这里的延时函数命名成了delay_us_by_Tim()): 

#include "dht11.h"
#include "tim.h"
 
void DHT11_IO_IN(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	GPIO_InitStructure.Pin = GPIO_PIN_3;
	GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
	HAL_GPIO_Init(GPIOE,&GPIO_InitStructure);
}
 
void DHT11_IO_OUT(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.Pin = GPIO_PIN_3;
	GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOE,&GPIO_InitStructure);
}
 
 
//复位DHT11
void DHT11_Rst(void)	   
{                 
	DHT11_IO_OUT(); 	//设置为输出
	DHT11_DQ_OUT_LOW; 	//拉低DQ
	HAL_Delay(20);    	//拉低至少18ms
	DHT11_DQ_OUT_HIGH; 	//DQ=1 
	delay_us_by_Tim(30);     	//主机拉高20~40us
}
 
//等待DHT11的回应
//返回1:未检测到DHT11的存在
//返回0:存在
uint8_t DHT11_Check(void) 	   
{   
	uint8_t retry=0;
	DHT11_IO_IN();      //设置为输出	 
	while (DHT11_DQ_IN&&retry<100)//DHT11会拉低40~80us
	{
		retry++;
		delay_us_by_Tim(1);
	};	 
	if(retry>=100)return 1;
	else retry=0;
	while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高40~80us
	{
		retry++;
		delay_us_by_Tim(1);
	};
	if(retry>=100)return 1;	    
	return 0;
}
 
//从DHT11读取一个位
//返回值:1/0
uint8_t DHT11_Read_Bit(void) 			 
{
 	uint8_t retry=0;
	while(DHT11_DQ_IN&&retry<100)//等待变为低电平
	{
		retry++;
		delay_us_by_Tim(1);
	}
	retry=0;
	while(!DHT11_DQ_IN&&retry<100)//等待变高电平
	{
		retry++;
		delay_us_by_Tim(1);
	}
	delay_us_by_Tim(40);//等待40us
	if(DHT11_DQ_IN)return 1;
	else return 0;		   
}
 
//从DHT11读取一个字节
//返回值:读到的数据
uint8_t DHT11_Read_Byte(void)    
{        
	uint8_t i,dat;
	dat=0;
	for (i=0;i<8;i++) 
	{
   		dat<<=1; 
	    dat|=DHT11_Read_Bit();
    }						    
    return dat;
}
 
//从DHT11读取一次数据
//temp:温度值(范围:0~50°)
//humi:湿度值(范围:20%~90%)
//返回值:0,正常;1,读取失败
uint8_t DHT11_Read_Data(uint16_t *temp,uint16_t *humi)    
{        
 	uint8_t buf[5];
	uint8_t i;
	DHT11_Rst();
	if(DHT11_Check()==0)
	{
		for(i=0;i<5;i++)//读取40位数据
		{
			buf[i]=DHT11_Read_Byte();
		}
		if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
		{
			*humi=(buf[0]<<8) + buf[1];
			*temp=(buf[2]<<8) + buf[3];
		}
	}else return 1;
	return 0;	    
}
 
//初始化DHT11的IO口 DQ 同时检测DHT11的存在
//返回1:不存在
//返回0:存在     	 
uint8_t DHT11_Init(void)
{ 
  DHT11_Rst();
	return DHT11_Check();
}

报告与源文件下载:

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

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

相关文章

多标签问题

一、多标签问题与单标签问题的区别&#xff1a; 多标签问题是单标签问题的推广。 举个例子&#xff0c;同时识别图片中的小汽车&#xff0c;公交车&#xff0c;行人时&#xff0c;标签值有三个&#xff1a;小汽车&#xff0c;公交车&#xff0c;行人。 单标签问题仅对一个标签…

网络安全——防御实验

防御实验一 拓扑结构展示&#xff1a; 一、 根据题目&#xff0c;先为办公区做安全策略主要策略有以下几点&#xff1a; 1、书写名称和描述&#xff0c;名称和描述要明确&#xff0c;让除本人以外的人也能理解 2、确定源地址为办公区&#xff0c;目标地址为DMZ区 3、确定时间…

utf8mb4和utf8的不同、若依框架,代码生成器,gitee,前端vue的下载、修复和启动(寻求大佬帮助若依框架三、2.3)

2024.7.9 一、数据库的排序和统一问题。utf8mb4和utf8的不同1.1 发现问题1.2 解决问题-在idea中用sql生成器&#xff0c;生成sql语句&#xff0c;然后在里面修改1.3 utf8和utf8mb4的区别 二、若依前后端框架。代码生成器&#xff08;还没研究懂&#xff0c;但有三个方案&#x…

2024前端面试真题【JS篇】

DOM DOM&#xff1a;文本对象模型&#xff0c;是HTML和XML文档的编程接口。提供了对文档的结构化的表述&#xff0c;并定义可一种方式可以使从程序中对该结构进行访问&#xff0c;从而改变文档的结构、样式和内容。 DOM操作 创建节点&#xff1a;document.createElement()、do…

ER模型理论和三范式

ER模型理论和三范式 各种关系多对一一对一一对多多对多 三范式理论函数依赖完全函数依赖部分函数依赖传递&#xff08;间接&#xff09;函数依赖 第一范式&#xff1a;属性&#xff08;表字段&#xff09;不可切割第二范式&#xff1a;不能存在 部分函数依赖(都存在完全函数依赖…

最全windows提权总结(建议收藏)

当以低权用户进去一个陌生的windows机器后&#xff0c;无论是提权还是后续做什么&#xff0c;第一步肯定要尽可能的搜集信息。知己知彼&#xff0c;才百战不殆。 常规信息搜集 systeminfo 查询系统信息hostname 主机名net user 查看用户信息netstat -ano|find "3389&quo…

充电宝哪个牌子公认质量好?哪家充电宝好用?4款口碑好充电宝

在如今这个电子设备不离手的时代&#xff0c;充电宝成为了我们生活中的必备品。然而&#xff0c;面对市场上琳琅满目的充电宝品牌和型号&#xff0c;选择一款质量可靠、性能出色的充电宝并非易事。大家都在问&#xff1a;充电宝哪个牌子公认质量好&#xff1f;哪家充电宝好用&a…

【鸿蒙学习笔记】UIAbility组件概述

官方文档&#xff1a;UIAbility组件 目录标题 UIAbility组件概述 [Q&A] 什么是UIAbility&#xff1f;声明周期UIAbility组件-启动模式UIAbility组件-与UI的数据同步 UIAbility组件概述 [Q&A] 什么是UIAbility&#xff1f; UIAbility组件是一种包含UI界面的应用组件&a…

红酒知识百科:从入门到精通

红酒&#xff0c;这个深邃而迷人的世界&#xff0c;充满了无尽的知识与奥秘。从葡萄的选择、酿造工艺&#xff0c;到品鉴技巧&#xff0c;每一步都蕴藏着深厚的文化底蕴和精细的技艺。今天&#xff0c;就让我们一起踏上这场红酒知识之旅&#xff0c;从入门开始&#xff0c;逐步…

量产工具一一UI系统(四)

目录 前言 一、按钮数据结构抽象 1.ui.h 二、按键处理 1.button.c 2.disp_manager.c 3.disp_manager.h 三、单元测试 1.ui_test.c 2.上机测试 前言 前面我们实现了显示系统框架&#xff0c;输入系统框架和文字系统框架&#xff0c;链接&#xff1a; 量产工具一一显…

docker笔记1

docker笔记1 一、为什么要学docker?二、docker是什么三、docker安装 一、为什么要学docker? 在过去&#xff0c;开发人员编写的代码在不同的环境中运行时常常面临一些问题&#xff0c;例如“在我的机器上可以运行&#xff0c;但在你的机器上却不行”的情况。这种问题部分原因…

如何在 CentOS 上配置本地 YUM 源

引言 CentOS 作为一个流行的企业级 Linux 发行版&#xff0c;依赖 YUM&#xff08;Yellowdog Updater, Modified&#xff09;来管理软件包。YUM 源&#xff08;Repository&#xff09;是软件包存储和分发的中心&#xff0c;它们通常位于互联网上。然而&#xff0c;在某些情况下…

六、数据可视化—flask框架入门(爬虫及数据可视化)

六、数据可视化—flask框架入门&#xff08;爬虫及数据可视化&#xff09; 1&#xff0c;数据可视化简介2&#xff0c;flask&#xff08;1&#xff09;创建flask项目&#xff08;2&#xff09;开启debug模式&#xff08;3&#xff09;通过访问路径传递参数&#xff08;4&#x…

实时温湿度监测系统:Micropython编码ESP32与DHT22模块的无线数据传输与PC端接收项目

实时温湿度监测系统 前言项目目的项目材料项目步骤模拟ESP32接线连接测试搭建PC端ESP32拷录环境对ESP32进行拷录PC端搭建桌面组件本地数据接收桌面小组件部分 实验总结 前言 人生苦短&#xff0c;我用Python。 由于我在日常工作中经常使用Python&#xff0c;因此在进行该项目…

核密度估计KDE和概率密度函数PDF(深入浅出)

目录 1. 和密度估计&#xff08;KDE&#xff09;核密度估计的基本原理核密度估计的公式核密度估计的应用Python中的KDE实现示例代码 结果解释解释结果 总结 2. 概率密度函数&#xff08;PDF&#xff09;概率密度函数&#xff08;PDF&#xff09;是怎么工作的&#xff1a;用图画…

澳大利亚TikTok直播为什么需要海外直播专线?

近年来&#xff0c;许多卖家为了解决澳大利亚TikTok直播中的卡顿和高延迟问题&#xff0c;纷纷选择使用海外直播专线。这种专线服务是一种高效、低延迟的数据传输解决方案&#xff0c;专为需要高质量网络连接的场合设计。 与公共互联网相比&#xff0c;海外直播专线提供更稳定、…

在Linux下直接修改磁盘镜像文件的内容

背景 嵌入式Linux系统通常在调试稳定后&#xff0c;会对磁盘&#xff08;SSD、NVME、SD卡、TF卡&#xff09;做个镜像&#xff0c;通常是.img后缀的文件&#xff0c;以后组装新设备时&#xff0c;就将镜像文件烧录到新磁盘即可&#xff0c;非常简单。 这种方法有个不便之处&a…

99%的人忽视了这一点:活着本身就是人生的意义,别让抑郁和内耗成为你的枷锁!

人没必要抑郁和精神内耗&#xff0c;不结婚&#xff0c;不生子&#xff0c;赚不到钱&#xff0c;没考上名牌大学&#xff0c;没有好工作等等&#xff0c;其实都没什么关系。 因为大多数人生是没有什么意义&#xff0c;或者说&#xff0c;活着就是最大的意义。 抑郁和精神内耗…

接口测试(2)

单接口测试 CtrlD 复制 因为单接口的时候主要改变测试用例数据 自动判定响应结果 postman断言 //断言响应状态码为200 pm.test("Status code is 200", function () {pm.response.to.have.status(200); }); //断言返回数据中包括&#xff08;成功&#xff09; //预期结…

14.x86游戏实战-汇编指令cmp test

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 工具下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd6tw3 提…