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

news2024/9/21 17:39:08

一、项目介绍

当前文章介绍基于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 int

sbit 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;       // 波特率9600
    TL1=0xfd;
    TR1=1;          // 启动定时器0

    SCON=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中写入数字12345
        RS = 0;  //选择指令寄存器

        LCD1602_DB = 0x80;  //设置地址为第一行的第一个字符位置(0x80 + 0x00)

        E = 1;
        delay(5);
        E = 0;

        RS = 1;  //选择数据寄存器

        LCD1602_DB = 0x31;  //写入数字1
        E = 1;
        delay(5);
        E = 0;

        LCD1602_DB = 0x32;  //写入数字2
        E = 1;
        delay(5);
        E = 0;

        LCD1602_DB = 0x33;  //写入数字3
        E = 1;
        delay(5);
        E = 0;

        LCD1602_DB = 0x34;  //写入数字4
        E = 1;
        delay(5);
        E = 0;

        LCD1602_DB = 0x35;  //写入数字5
        E = 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 int

sbit 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.coloradmin.cn/o/740089.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

路径规划算法:基于白冠鸡优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于白冠鸡优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于白冠鸡优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法…

leetcode 74. 搜索二维矩阵(java)

搜索二维矩阵 leetcode 74. 搜索二维矩阵题目描述抽象BST代码演示 抽象BST leetcode 74. 搜索二维矩阵 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problems/search-a-2d-matrix 题目描述 给你一个满足下述两条属性的 m x n 整…

033、TiDB特性_AUTO_INCREMENT

自增列 实现原理使用限制相关参数示例 实现原理 每一个自增列使用一个全局可见的键值对用于记录当前已分配的最大ID为了降低分布式系统分配自增ID的网络开销&#xff0c;每个TiDB节点会缓存一个不重复的ID段当前预分配的ID段使用完毕&#xff0c;或重启&#xff0c;都会重新再…

【数据结构导论】第 6 章:查找

目录 一、基本概念 二、静态查找表 &#xff08;1&#xff09;顺序表上的查找 —— 顺序查找 ① 过程 ② 算法 ③ 算法分析 &#xff08;2&#xff09;有序表上的查找 —— 二分查找 ① 二分查找思想 ② 二分查找过程 ③ 二分查找算法 ④ 示例 ⑤ 算法分析 &#…

CentOS系统内核升级(在线 离线)

centos7.x默认内核版本3.10.x&#xff0c;在安装docker时&#xff0c;部分功能&#xff08;如 overlay2 存储层驱动&#xff09;无法使用&#xff0c;并且部分功能可能不太稳定。所以建议大家升级到最新的稳定内核版本。 在线升级 1. 查看当前内核版本 uname -sr Linux 3.10…

python脚本编译成exe方式进行交付

Python自动化办公越来越方便&#xff0c;我们经常也会利用python来写一些自动化的小脚本&#xff0c;例如批量处理文档&#xff0c;自动发送邮件等等。 也许是平时吹得牛比较多&#xff0c;有一天秦医生就问起我说能不能给她写一个自动化处理生信数据的小脚本。 这当然是毫无问…

Stable Diffusion - 扩展插件 (Extensions) 功能的配置与使用

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/131576762 Prompt: (masterpiece, top quality, best quality, ((standing in centre)), ((1girl, black hair)), ((upper body, symmetrical com…

视频无损放大修复工具:Topaz Video AI对Mac和Windows的系统要求

Topaz Video AI是一款基于人工智能技术的视频增强软件&#xff0c;旨在提供高质量的视频修复、增强和转换功能。它可以通过智能算法和图像处理技术&#xff0c;改善视频的清晰度、稳定性、降噪效果&#xff0c;还能进行视频转码和格式转换。 Mac&#xff1a;Topaz Video AI fo…

[pyqt5]designer设计界面设计工具栏上图标和文字同时显示

打开设计师界面 右侧先选择toolBar然后去属性找到toolButtonStyle设置对应选项即可。

图扑 AR 技术应用与管理:施工建造、机柜扫描、办公室导航解决方案

随着科技的不断革新和创新&#xff0c;越来越多的行业开始迎来数字化时代的变革。建筑行业作为人类历史上最重要的产业之一&#xff0c;在数字化转型方面同样也在不断推进。图扑软件结合 AR 技术的应用&#xff0c;为建筑行业带来了更加便捷高效的建筑施工过程管理。 传统的建筑…

MathType7.4中文版下载安装教程

MathType7.4版是一款功能强大、专业实用、应用范围广的数学公式编辑器软件&#xff0c;这款软件采用了简体中文操作界面并且完美兼容office、wps等一系列常见办公工具&#xff0c;这样就能够很好的为相关用户省去了许多繁琐的操作步骤&#xff0c;用户在这里可以轻轻松松进行公…

使用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…

VBA系列技术资料MF33:VBA_将文本文件转换为Excel

【分享成果&#xff0c;随喜正能量】一心热枕对待生活&#xff0c;静静的安抚自己内心的急迫和焦虑&#xff0c;你人生的好运&#xff0c;常常在你沉醉于生活时悄悄临门的。。 我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高…

vue本地开发集成https

背景&#xff1a;在本地项目开发中&#xff0c;调用第三方服务获取音视频通话&#xff0c;音视频通话是采用 WebRTC 来实现的&#xff0c;而 WebRTC 中使用音视频设备进行取流是需要在安全域下才可以调起的设备权限 解决方案&#xff1a;使用npm安装mkcert&#xff0c;配置证书…

spring boot+MySQL实现学习平台

本次设计任务是要设计一个学习平台&#xff0c;通过这个系统能够满足学习信息的管理及学生和教师的学习管理功能。系统的主要功能包括首页&#xff0c;个人中心&#xff0c;学生管理&#xff0c;教师管理&#xff0c;课程信息管理&#xff0c;类型管理&#xff0c;作业信息管理…

Hive(18):DML之Load加载数据

1 背景 回想一下,当在Hive中创建好表之后,默认就会在HDFS上创建一个与之对应的文件夹,默认路径是由参数hive.metastore.warehouse.dir控制,默认值是/user/hive/warehouse。 要想让hive的表和结构化的数据文件产生映射,就需要把文件移到到表对应的文件夹下面,当然,可以在…

天天刷题-->LeetCode(无重复字符的最长字串)

个人名片&#xff1a; &#x1f405;作者简介&#xff1a;一名大二在校生&#xff0c;热爱生活&#xff0c;爱好敲码&#xff01; \ &#x1f485;个人主页 &#x1f947;&#xff1a;holy-wangle ➡系列内容&#xff1a; &#x1f5bc;️ tkinter前端窗口界面创建与优化 &…

轻松学会Java导出word,一篇文章就够了!

很多小伙伴在工作中&#xff0c;可能又这样一个需求&#xff1a;根据word模板去填充数据&#xff0c;变成我们想要的word文档&#xff0c;这是很多刚进入职场的小白都会碰到的需求。 当遇上这种需求&#xff0c;我们可以通过这篇文章要讲的poi-tl 来做处理。 导入依赖 <dep…

下载pycharm专业版

PyCharm: the Python IDE for Professional Developers by JetBrainsThe Python & Django IDE with intelligent code completion, on-the-fly error checking, quick-fixes, and much more...https://www.jetbrains.com/pycharm/Pycharm安装使用与版本切换_pycharm专业版换…

华为开发者大会2023(Cloud)之旅

【摘要】 金鱼哥畅游记&#xff1a;华为开发者大会2023&#xff08;Cloud&#xff09; 2023年7月7日华为开发者大会2023&#xff08;Cloud&#xff09;在广东东莞正式揭开帷幕&#xff0c;金鱼哥很庆幸能有机会参加此次盛大聚会&#xff0c;看到众开发者共聚一堂&#xff0c;在…