前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >基于51单片机+SHT30设计的环境温度与湿度检测设备(IIC模拟时序)

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

作者头像
DS小龙哥
发布于 2023-07-11 07:22:05
发布于 2023-07-11 07:22:05
81601
代码可运行
举报
运行总次数:1
代码可运行

一、项目介绍

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

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

二、硬件设计

2.1 硬件构成

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

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

2.2 硬件接口及信号

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

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

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

端口

功能

说明

P2.0

SDA

数据线

P2.1

SCL

时钟线

P2.2

RESET

复位线

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

端口

功能

说明

P3.0

TXD

发送线

P3.1

RXD

接收线

P3.2

GND

地线

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

端口

功能

说明

P1.0-P1.7

DB0-DB7

数据线

P0.0

RS

指令/数据选择线

P0.1

RW

读/写选择线

P0.2

E

使能线

P0.3

CS

片选线

VCC

电源正极

5V

GND

电源地

三、软件设计

3.1 SHT30传感器代码

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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驱动代码,完成数字字符显示。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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 完整代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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);	//显示温湿度值
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-07-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
STM32F103ZE+SHT30检测环境温度与湿度(IIC模拟时序)
程序采用模块化编程,iic时序为一个模块(iic.c 和 iic.h),SHT30为一个模块(sht30.c 和 sht30.h);IIC时序采用模拟时序方式实现,IO口都采用宏定义方式,方便快速移植到其他平台使用。
DS小龙哥
2022/01/17
1.1K0
STM32F103ZE+SHT30检测环境温度与湿度(IIC模拟时序)
基于单片机的数字温度计设计
数字温度计是一种用于测量和显示环境温度的设备。本文章介绍基于STC89C52主控芯片的数字温度计的设计过程和实现原理。该设计采用DS18B20温度传感器进行温度采集,使用LCD1602显示屏进行温度显示,通过按键设置温度的上限和下限阀值,并通过蜂鸣器进行报警。
DS小龙哥
2023/09/01
9990
基于单片机的数字温度计设计
基于STM32+SHT30设计的环境温度与湿度检测系统(IIC模拟时序)
当前介绍基于STM32F103ZCT6芯片设计的环境温度与湿度检测系统设计过程。当前系统通过SHT30温湿度传感器采集环境温度和湿度数据,并通过模拟IIC时序协议将数据传输到STM32芯片上。然后,STM32芯片通过处理这些数据并将它们显示在0.91寸OLED显示屏上,以便用户能够方便地观察环境温度和湿度的变化情况。
DS小龙哥
2023/07/11
1.4K0
基于STM32+SHT30设计的环境温度与湿度检测系统(IIC模拟时序)
51单片机LCD1602程序详解[通俗易懂]
LCD1602 工业字符型液晶。1602是指LCD显示的内容为16X2,即可以显示两行,每行16个字符.
全栈程序员站长
2022/09/13
2.1K0
51单片机+DS1302设计一个电子钟(LCD1602显示时间)
电子钟是一种能够准确显示时间的设备,广泛应用于家庭、办公场所和公共场所,为人们提供了方便和准确的时间信息。本项目设计一个基于51单片机的电子钟,使用DS1302作为RTC时钟芯片,LCD1602作为显示屏,并通过串口方式连接上位机进行时间设置和闹钟设置。
DS小龙哥
2023/11/15
2K1
51单片机+DS1302设计一个电子钟(LCD1602显示时间)
DS3231高精度时钟,LCD1602显示,QXmini151版本「建议收藏」
1.时钟方案设计及选择:目前有DS3231、DS302、DS12C887三种时钟芯片。本次设计选择DS3231,
全栈程序员站长
2022/07/29
1.8K0
DS3231高精度时钟,LCD1602显示,QXmini151版本「建议收藏」
基于51单片机的6位密码锁设计
多功能电子密码锁系统由AT89C52单片机最小系统、4×4矩阵键盘、LCD1602显示、AT24C02存储模块以及报警系统等组成,具有设置、修改六位用户密码、超次报警、超次锁定、密码错误报警等功能。
芯动大师
2024/05/26
1700
基于51单片机的6位密码锁设计
山东大学单片机原理与应用实验 3.8 ADC0808/9信号采集实验
利用LCD1602和AD0808实现简单的交流信号过零检测与频率分析。要求信号幅度变化时(满量程的5%—95%),不影响检测到结果。频率检测的结果通过LCD1602的第一行显示出来,信号过零时,能够通过P2.6输出一个脉冲宽度为5μs的脉冲信号。
timerring
2022/07/20
9690
山东大学单片机原理与应用实验 3.8 ADC0808/9信号采集实验
米家蓝牙温湿度计2-拆解报告,固件重定制
米家温湿度传感器支持蓝牙连接,可以通过米家蓝牙网关或手机接入到米家app,实时查看温湿度,适宜度分析数据,也可以通过米家app实现设备联动
iot-me.club
2022/02/11
11.6K2
米家蓝牙温湿度计2-拆解报告,固件重定制
MCS-51单片机温度控制系统的设计
注塑机是一种常用的制造设备,用于生产塑料制品。在注塑机的工作过程中,溶胶必须达到一定的温度才能被注入模具中进行成型。因此,在注塑机的生产过程中,温度控制是非常重要的一环。
DS小龙哥
2023/09/07
3600
MCS-51单片机温度控制系统的设计
别怕!51 单片机从入门到应用,小白也能轻松吃透
这篇教程专为单片机小白打造,从 51 单片机基础讲起,带你搭建开发环境,学习汇编与 C 语言编程。通过 LED 灯闪烁、按键控制、数码管显示等基础实验,以及简易电子钟、温度检测系统等应用案例,结合代码实操,助你快速掌握 51 单片机开发。
羑悻的小杀马特.
2025/03/24
4860
蓝桥杯单片机必备知识—–(11)EEPROM
由于EPROM操作的不便,后来出的主板上BIOS ROM芯片大部分都采用EEPROM(Electrically Erasable Programmable ROM,电可擦除可编程ROM)。EEPROM的擦除不需要借助于其它设备,它是以电子信号来修改其内容的,而且是以Byte为最小修改单位,不必将资料全部洗掉才能写入,彻底摆脱了EPROM Eraser和编程器的束缚。EEPROM在写入数据时,仍要利用一定的编程电压,此时,只需用厂商提供的专用刷新程序就可以轻而易举地改写内容,所以,它属于双电压芯片。借助于EEPROM芯片的双电压特性,可以使BIOS具有良好的防毒功能,在升级时,把跳线开关打至“on”的位置,即给芯片加上相应的编程电压,就可以方便地升级;平时使用时,则把跳线开关打至“off”的位置,防止CIH类的病毒对BIOS芯片的非法修改。所以,仍有不少主板采用EEPROM作为BIOS芯片并作为自己主板的一大特色。 IIC.H添加
全栈程序员站长
2021/04/16
6620
蓝桥杯单片机必备知识—–(11)EEPROM
设计分享|基于单片机LCD数字测速仪的设计
51单片是一种低功耗、高性能CMOS8位微控制器,具有 8K 在系统可编程Flash 存储器。在单芯片上,拥有灵巧的8 位CPU 和在系统可编程Flash,使得STC89C51为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。具有以下标准功能:8k字节Flash,512字节RAM,32 位I/O 口线,看门狗定时器,内置4KB EEPROM,MAX810复位电路,三个16 位 定时器/计数器,一个6向量2级中断结构,全双工串行口。另外 STC89X51 可降至0Hz 静态逻辑操作,支持2种软件可选择节电模式。空闲模式下,CPU 停止工作,允许RAM、定时器/计数器、串口、中断继续工作。掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。最高运作频率35Mhz,6T/12T可选。
电子工程师成长日记
2022/07/27
4520
设计分享|基于单片机LCD数字测速仪的设计
设计分享|单片机数字温度计
51单片是一种低功耗、高性能CMOS8位微控制器,具有 8K 在系统可编程Flash 存储器。在单芯片上,拥有灵巧的8 位CPU 和在系统可编程Flash,使得STC89C51为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。具有以下标准功能:8k字节Flash,512字节RAM,32 位I/O 口线,看门狗定时器,内置4KB EEPROM,MAX810复位电路,三个16 位 定时器/计数器,一个6向量2级中断结构,全双工串行口。另外 STC89X51 可降至0Hz 静态逻辑操作,支持2种软件可选择节电模式。空闲模式下,CPU 停止工作,允许RAM、定时器/计数器、串口、中断继续工作。掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。最高运作频率35Mhz,6T/12T可选。
电子工程师成长日记
2022/07/27
6420
设计分享|单片机数字温度计
STM32读取SHT3x系列温湿度传感器,标准库和HAL库
STM32读取SHT3x系列(SHT30、SHT31、SHT35)温湿度传感器的数据并显示在0.96寸OLED屏上。
zeruns
2023/03/03
1.6K0
STM32读取SHT3x系列温湿度传感器,标准库和HAL库
DHT11传感器模块温湿度监测,51单片机项目资料
Proteus7版本的仿真软件只有SHT11温湿度传感器元件,没有DHT11传感器元件。Proteus8版本经过升级更新后,元件库已添加了DHT11传感器元件。因此,本设计采用Proteus8.6版本的仿真软件进行开发。
蒋宇智
2024/03/25
3850
DHT11传感器模块温湿度监测,51单片机项目资料
基于单片机的太阳能热水器控制器设计
随着环保意识的逐渐增强,太阳能热水器作为一种清洁能源应用得越来越广泛。然而,传统的太阳能热水器控制器通常采用机械式或电子式温控器,存在精度低、控制不稳定等问题。为了解决这些问题,本项目基于单片机技术设计了一款太阳能热水器控制器,主控芯片采用STC89C52。该控制器可以实现对太阳能热水器的水温、水位等参数进行准确、稳定的控制,提高了太阳能热水器的能源利用效率和使用寿命,同时也符合节能环保的社会需求。
DS小龙哥
2023/09/06
6270
基于单片机的太阳能热水器控制器设计
STC89C52+HX711完成电子秤设计
电子秤是一种通过传感器测量物体质量的设备,被广泛应用于商业和工业领域。传统的机械秤已经逐渐被电子秤取代,因为电子秤具有更高的精度、更方便的使用和更多的功能。
DS小龙哥
2023/11/16
4020
STC89C52+HX711完成电子秤设计
蓝桥杯单片机必备知识—–(10)DS1302时钟
extern time[]; //标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义
全栈程序员站长
2022/06/29
3850
蓝桥杯单片机必备知识—–(10)DS1302时钟
基于单片机设计的电子指南针(LSM303DLH模块(三轴磁场 + 三轴加速度)
本项目是基于单片机设计的电子指南针,主要利用STC89C52作为主控芯片和LSM303DLH模块作为指南针模块。通过LCD1602液晶显示屏来展示检测到的指南针信息。
DS小龙哥
2023/11/18
4620
基于单片机设计的电子指南针(LSM303DLH模块(三轴磁场 + 三轴加速度)
推荐阅读
相关推荐
STM32F103ZE+SHT30检测环境温度与湿度(IIC模拟时序)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验