基于51单片机+SHT30设计的环境温度与湿度检测设备(IIC模拟时序)

一、项目介绍

当前文章介绍基于51单片机和SHT30传感器设计的环境温度与湿度检测设备。设备采用IIC模拟时序通信协议,能够实时监测环境的温度和湿度,并将数据通过LCD显示屏显示出来;可以广泛应用于室内环境监测、气象观测、农业温室监测等领域。

在本项目中,使用了51单片机作为主控芯片,SHT30传感器作为温湿度传感器,LCD显示屏作为数据显示模块。通过51单片机的GPIO口模拟IIC通信协议,实现了与SHT30传感器的数据通信。

image-20230618123229983

二、硬件设计

2.1 硬件构成

本次设计所需的硬件主要包括以下部分:

  • STC89C52单片机
  • SHT30温湿度传感器
  • 串口通信模块
  • LCD1602显示屏
  • 电源模块
  • 杜邦线等连接线

2.2 硬件接口及信号

本次设计使用51单片机通过IIC总线与SHT30传感器进行通信,同时使用串口与上位机进行数据传输,并使用液晶显示屏显示当前温湿度值。

具体接口和信号定义如下:

(1) 51单片机与SHT30传感器之间的IIC接口:

端口功能说明
P2.0SDA数据线
P2.1SCL时钟线
P2.2RESET复位线

(2) 51单片机与串口通信模块之间的接口:

端口功能说明
P3.0TXD发送线
P3.1RXD接收线
P3.2GND地线

(3) 51单片机与液晶屏之间的接口:

端口功能说明
P1.0-P1.7DB0-DB7数据线
P0.0RS指令/数据选择线
P0.1RW读/写选择线
P0.2E使能线
P0.3CS片选线
VCC电源正极5V
GND电源地

三、软件设计

3.1 SHT30传感器代码

下面代码读取SHT30传感器的值并通过串口打印。

#include <REG52.h>
#include <stdio.h>#define uchar unsigned char
#define uint unsigned intsbit SDA=P2^0;
sbit SCL=P2^1;void delay(int n)
{int i;while(n--){for(i=0; i<120; i++);}
}void start()
{SDA = 1;_nop_();SCL = 1;_nop_();SDA = 0;_nop_();SCL = 0;_nop_();
}void stop()
{SDA = 0;_nop_();SCL = 1;_nop_();SDA = 1;_nop_();
}void ack()
{SDA = 0;_nop_();SCL = 1;_nop_();SCL = 0;_nop_();SDA = 1;_nop_();
}void nack()
{SDA = 1;_nop_();SCL = 1;_nop_();SCL = 0;_nop_();
}void write_byte(uchar dat)
{uchar i;for(i=0; i<8; i++){SDA = dat & 0x80;_nop_();SCL = 1;_nop_();SCL = 0;_nop_();dat <<= 1;}ack();
}uchar read_byte()
{uchar i, dat;for(i=0; i<8; i++){dat <<= 1;SCL = 1;_nop_();dat |= SDA;SCL = 0;_nop_();}return dat;
}void init_sht30()
{start();write_byte(0x80);if(read_byte() != 0x5A){stop();return;}write_byte(0xBE);if(read_byte() != 0x08 || read_byte() != 0x00){stop();return;}stop();
}float measure_temp(void)
{uchar temp_h, temp_l, crc;float temp;start();write_byte(0x80);  // 主机发送写地址write_byte(0x2C);  // 选择开始温度测量命令write_byte(0x06);stop();delay(15);    // 延时等待温度测量完成start();write_byte(0x81);  // 主机发送读地址temp_h=read_byte();  ack();temp_l=read_byte(); ack();crc=read_byte();stop();temp = ((temp_h<<8)+temp_l)*175.0/0xffff - 45.0; // 温度值转换公式return temp;
}float measure_humi(void)
{uchar humi_h, humi_l, crc;float humi;start();write_byte(0x80);  // 主机发送写地址write_byte(0x2C);  // 选择开始湿度测量命令write_byte(0x06);stop();delay(15);    // 延时等待湿度测量完成start();write_byte(0x81);  // 主机发送读地址humi_h=read_byte();  ack();humi_l=read_byte(); ack();crc=read_byte();stop();humi = ((humi_h<<8)+humi_l)*100.0/0xffff; // 湿度值转换公式return humi;
}void main()
{   float temp, humi;init_sht30();   // SHT30 初始化TMOD=0x20;      // 定时器0工作方式2,8位定时器,用于波特率设置TH1=0xfd;       // 波特率9600TL1=0xfd;TR1=1;          // 启动定时器0SCON=0x50;      // 设置串口工作方式1,允许接收,允许接收中断ES=1;           // 允许串口中断while(1){temp = measure_temp();humi = measure_humi();printf("Temperature: %.1fC, Humidity: %.1f%\n", temp, humi);delay(500); // 间隔时间500ms}
}void ser() interrupt 4 using 2
{if(RI)          // 接收到数据{RI=0;       // 清除标志位}if(TI)          // 发送完毕{TI=0;       // 清除标志位}
}

在上面的代码中,定义了两个函数 measure_tempmeasure_humi,分别用于测量温度和湿度值,并返回结果。在主函数中,利用这两个函数得到当前的温湿度值,然后通过串口打印出来。

3.2 LCD1602显示屏代码

下面代码是LCD1602驱动代码,完成数字字符显示。

#include <REG52.h>#define LCD1602_DB P0
sbit  RS = P2^5;
sbit  RW = P2^6;
sbit  E  = P2^7;void delay(int n)
{int i;while(n--){for(i=0; i<120; i++);}
}void main()
{   //LCD 初始化delay(1000);LCD1602_DB = 0x38;E = 1;delay(5);E = 0;delay(500);LCD1602_DB = 0x08;E = 1;delay(5);E = 0;delay(500);LCD1602_DB = 0x01;E = 1;delay(5);E = 0;delay(500);LCD1602_DB = 0x06;E = 1;delay(5);E = 0;delay(500);LCD1602_DB = 0x0C;E = 1;delay(5);E = 0;while(1){//向LCD中写入数字12345RS = 0;  //选择指令寄存器LCD1602_DB = 0x80;  //设置地址为第一行的第一个字符位置(0x80 + 0x00)E = 1;delay(5);E = 0;RS = 1;  //选择数据寄存器LCD1602_DB = 0x31;  //写入数字1E = 1;delay(5);E = 0;LCD1602_DB = 0x32;  //写入数字2E = 1;delay(5);E = 0;LCD1602_DB = 0x33;  //写入数字3E = 1;delay(5);E = 0;LCD1602_DB = 0x34;  //写入数字4E = 1;delay(5);E = 0;LCD1602_DB = 0x35;  //写入数字5E = 1;delay(5);E = 0;delay(500); //间隔时间为500ms}
}

在上面的代码中,定义了函数 delay 用于延时等待,并且实现了LCD1602的初始化和写入操作。在主函数中,执行LCD1602的初始化操作,然后循环不断向LCD中写入数字12345,并且间隔时间为500ms。

3.3 完整代码

#include<reg52.h>
#include<intrins.h>#define uchar unsigned char
#define uint unsigned intsbit SDA = P2^0;	//定义SDA引脚
sbit SCL = P2^1;	//定义SCL引脚
sbit CS = P0^3;		//定义液晶屏片选引脚
sbit RW = P0^1;		//定义液晶屏读/写引脚
sbit RS = P0^0;		//定义液晶屏指令/数据引脚
sbit E = P0^2;		//定义液晶屏使能引脚void delay(int n)	//延时函数,n为延时时间
{int i;while(n--){for(i=0; i<120; i++);}
}void start()		//开始信号
{SDA = 1;		//数据线高电平_nop_();SCL = 1;		//时钟线高电平_nop_();SDA = 0;		//数据线低电平_nop_();SCL = 0;		//时钟线低电平_nop_();
}void stop()			//结束信号
{SDA = 0;		//数据线低电平_nop_();SCL = 1;		//时钟线高电平_nop_();SDA = 1;		//数据线高电平_nop_();
}void ack()			//应答信号
{SDA = 0;		//数据线低电平_nop_();SCL = 1;		//时钟线高电平_nop_();SCL = 0;		//时钟线低电平_nop_();SDA = 1;		//数据线高电平_nop_();
}void nack()			//非应答信号
{SDA = 1;		//数据线高电平_nop_();SCL = 1;		//时钟线高电平_nop_();SCL = 0;		//时钟线低电平_nop_();
}void write_byte(uchar dat)	//写一个字节
{uchar i;for(i=0; i<8; i++){SDA = dat & 0x80;_nop_();SCL = 1;_nop_();SCL = 0;_nop_();dat <<= 1;}ack();
}uchar read_byte()	//读一个字节
{uchar i, dat;for(i=0; i<8; i++){dat <<= 1;SCL = 1;_nop_();dat |= SDA;SCL = 0;_nop_();}return dat;
}void init_sht30()	//SHT30初始化
{start();write_byte(0x80);if(read_byte() != 0x5A){stop();return;}write_byte(0xBE);if(read_byte() != 0x08 || read_byte() != 0x00){stop();return;}stop();
}void measure()			//测量温湿度值
{float humi, temp;uint i;start();write_byte(0x80);read_byte();read_byte();read_byte();write_byte(0x2C);write_byte(0x06);for(i=0; i<40000; i++);	//等待测量结果start();write_byte(0x80);read_byte();read_byte();read_byte();humi = read_byte() * 256;humi += read_byte();temp = read_byte() * 256;temp += read_byte();stop();temp = -45 + (175*temp)/65535;	//转化温度humi = 100 * humi / 65535;		//转化湿度//将温湿度值通过串口发送printf("Temperature: %.1fC\n", temp);printf("Humidity: %.1f%%RH\n", humi);
}void init_lcd()			//液晶屏初始化
{RW = 0;RS = 0;E = 0;delay(15);write_byte(0x30);delay(15);write_byte(0x30);delay(5);write_byte(0x30);delay(5);write_byte(0x38);write_byte(0x08);write_byte(0x01);write_byte(0x06);write_byte(0x0c);
}void display(float temp, float humi)	//显示温湿度值
{uchar i;uchar temp_str[5];uchar humi_str[5];//转化为字符串sprintf(temp_str, "%.1f", temp);sprintf(humi_str, "%.1f", humi);//显示温度RS = 0;E = 1;P1 = 0x80;	//第一行第一个字符E = 0;RS = 1;for(i=0; i<5; i++){E = 1;P1 = temp_str[i];E = 0;}//显示湿度RS = 0;E = 1;P1 = 0xc0;	//第二行第一个字符E = 0;RS = 1;for(i=0; i<5; i++){E = 1;P1 = humi_str[i];E = 0;}
}void main()
{init_sht30();	//SHT30初始化init_lcd();		//液晶屏初始化while(1){measure();	//测量温湿度值并通过串口发送delay(1000);display(temp, humi);	//显示温湿度值}
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

音视频开发实战03-FFmpeg命令行工具移植

一&#xff0c;背景 作为一个音视频开发者&#xff0c;在日常工作中经常会使用ffmpeg 命令来做很多事比如转码ffmpeg -y -i test.mov -g 150 -s 1280x720 -codec libx265 -r 25 test_h265.mp4 &#xff0c;水平翻转视频&#xff1a;ffmpeg -i src.mp4 -vf hflip -acodec copy …

常用的访问控制权限模型DAC RBAC

常用的访问控制权限模型DAC RBAC 文章目录 常用的访问控制权限模型DAC RBACLinux 自主访问控制与强制访问控制术语概念存取访问控制 Access Control自主访问控制强制访问控制 基于角色的权限控制模型RBAC模型管理方法RBAC0的管理命令RBAC0的系统支持方法RBAC0的高级审查持方法 …

Table Recognition Metric: 表格识别算法评测工具包及相关评测基准数据集

Table Recognition Metric 该库用于计算TEDS指标&#xff0c;用来评测表格识别算法效果。可与魔搭-表格识别测试集配套使用。TEDS计算代码参考&#xff1a;PaddleOCR 和 DAVAR-Lab-OCR 使用说明&#xff1a; Install package by pypi.pip install table_recognition_metricRu…

【SCI一区】互联燃料电池混合动力汽车通过信号交叉口的生态驾驶双层凸优化(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

支付宝接入

支付宝接入 python-alipay-sdk pycryptodome一、电脑网站支付 1.1 获取支付宝密钥 沙箱网址 1.APPID 2.应用私钥 3.支付宝公钥1.2 存放密钥 在与 settings.py 的同级目录下创建 pem 文件夹pem 文件夹下创建 app_private_key.pem 和 alipay_public_key.pem app_private_key…

python pytest脚本执行工具

pytest脚本执行工具 支持获取当前路径下所有.py脚本 添加多个脚本&#xff0c;一起执行 import tkinter as tk from tkinter import filedialog import subprocess import os from datetime import datetimedef select_script():script_path filedialog.askopenfilename(fil…

11. 利用Tomcat服务器配置HTTPS双向认定

文章目录 Tomcat配置HTTPS1.为服务器生成证书2.为客户端生成证书3.让服务器信任客户端证书4.将该文件导入到服务器的证书库&#xff0c;添加为一个信任证书使用命令如下&#xff1a;5.查看证书库6.让客户端信任服务器证书7.配置tomcat8.验证 Tomcat配置HTTPS 1.启动cmd控制台&…

使用Pytorch加载预训练模型及修改网络结构

Pytorch有自带的训练好的AlexNet、VGG、ResNet等网络架构。详见官网 1.加载预训练模型 import torch import torchvision import torch.nn as nn import torch.optim as optim import torch.nn.functional as F import torchvision.transforms as transforms import torchvis…

逆波兰式是什么?

1. 逆波兰式是什么&#xff1f; 逆波兰式&#xff0c;也称逆波兰记法&#xff08;Reverse Polish Notation&#xff0c;缩写为RPN&#xff09;&#xff0c;是一种在数学和计算机科学中用于表示算术表达式的方法。它的特点是操作符在操作数的后面&#xff0c;不需要括号来改变运…

DevOps基础服务2——Jenkins

文章目录 一、基本了解1.1 CI/CD介绍1.2 基于Docker的CI/CD 二、安装jenkins三、页面管理3.1 当前系统用户配置3.2 系统配置3.3 全局工具配置3.4 插件管理3.4.1 安装插件3.4.2 上传插件 3.5 用户设置3.6 查看日志3.7 汉化设置 一、基本了解 DEVOPS概念&#xff1a; DevOps是一种…

网络ping丢包什么原因(附解决方案)

​  数据包丢失是一种网络问题&#xff0c;当通过网络(或设备之间或通过 Internet)传输的数据包在传输过程中丢失或丢弃并且无法到达目的地时&#xff0c;就会发生这种情况。简单来说&#xff0c;数据包丢失是指数据包无法通过互联网从发送者成功传输到接收者。 如何检测数据…

LiveGBS流媒体平台GB/T28181功能-支持UDP、TCP被动、TCP主动模式流传输模式之间有什么区别?

LiveGBS流媒体平台-国标流媒体服务几种流传输模式UDP、TCP被动、TCP主动模式区别是什么 1、背景1、GB28181流传输模式1.1、UDP1.2、TCP 被动1.3、TCP 主动 2、切换流传输模式2.1、编辑2.2、下拉切换 3、搭建GB28181视频直播平台 1、背景 国标GB28181协议中&#xff0c;视频流到…