0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

DS小龙哥-嵌入式技术 来源:DS小龙哥-嵌入式技术 作者:DS小龙哥-嵌入式技 2023-06-19 09:02 次阅读

一、项目介绍

当前文章介绍基于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.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传感器的值并通过串口打印。

#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);    //显示温湿度值
     }
 }
 ​

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6002

    文章

    43982

    浏览量

    620916
  • 51单片机
    +关注

    关注

    269

    文章

    5649

    浏览量

    120824
  • IIC
    IIC
    +关注

    关注

    11

    文章

    285

    浏览量

    37810
  • 检测设备
    +关注

    关注

    0

    文章

    530

    浏览量

    16423
收藏 人收藏

    评论

    相关推荐

    基于STM32+SHT30设计的环境温度湿度检测系统(IIC模拟时序)

    当前介绍基于STM32F103ZCT6芯片设计的环境温度湿度检测系统设计过程。当前系统通过SHT30湿度传感器采集
    的头像 发表于 06-20 09:16 1293次阅读
    基于STM32+<b class='flag-5'>SHT30</b>设计的<b class='flag-5'>环境温度</b>与<b class='flag-5'>湿度</b><b class='flag-5'>检测</b>系统(<b class='flag-5'>IIC</b><b class='flag-5'>模拟</b><b class='flag-5'>时序</b>)

    SHT30湿度传感器的51程序

    SHT30湿度传感器的51程序
    发表于 05-16 22:22

    STM32+SHT30(DS18B20)+0.96寸OLED(IIC)的温度湿度显示程序

    程序,显示SHT30湿度模块的温湿度。OLED(IIC接口)屏幕的温湿度显示,串口数据输出。为了作对比,我顺便把DS18B20的
    发表于 03-16 10:31

    SHT30温度传感器使用记录

    SHT30使用记录(基于AVR)文章目录SHT30使用记录(基于AVR)硬件篇软件篇硬件篇硬件按照数据手册连接到单片机IIC接口或者任意两个IO口即可,加2个4.7K左右上拉电阻,本
    发表于 07-13 08:35

    SHT11传感器的温度湿度监控报警系统单片机Proteus设计

    注:资源分享请见文末…概述系统通过SHT11温湿度传感器感应周围的环境温度湿度,通过单片机
    发表于 07-21 06:11

    STM32F103是如何读取SHT30湿度数据的

    1 准备工作硬件设备:两个激光测距SHT30模块、六合一、USB-TTL、杜邦线、STM32F103C8T6单片机。给大家看下图片。SHT30 STM32F103C8T62)软件准备
    发表于 08-11 07:01

    怎样去使用基于AVR的SHT30湿度传感器

    怎样去使用基于AVR的SHT30湿度传感器?SHT30湿度传感器的软硬件分别是由哪些部分构成的?
    发表于 09-23 06:58

    如何使用STC15系列单片机操作sht30

    1.iiciic部分是最让人头疼的,至今自己写写不出能用的时序,看了大部分代码都觉得没区别但是就是不能用!2.sht30感觉用的比较多的是DHT11或DHT22,温湿度传感器。网上买了个sht
    发表于 12-02 08:14

    SHT30湿度模块怎么使用

    的STH30一般是用IIC(I2C)通信使用的,所以我们打开一个IIC通道,IIC默认配置就可以了。4、因为我们需要看见她的效果是什么,我开了一个串口,所有数据通过串口打印出来。5、然
    发表于 02-15 06:28

    怎样通过单片机普通IO口去模拟IIC时序

    一、实验目的:通过单片机普通IO口,模拟IIC时序,掌握IIC通讯协议。二、实验用到的主控芯片:STM32F103RCT6,
    发表于 02-17 06:30

    dfrobot SHT30模拟湿度传感器简介

    SHT30高精度温湿度测量,内部自动校准,线性模拟电压输出
    的头像 发表于 01-07 10:45 1.6w次阅读
    dfrobot <b class='flag-5'>SHT30</b><b class='flag-5'>模拟</b>温<b class='flag-5'>湿度</b>传感器简介

    湿度传感器SHT30参考代码资料

    湿度传感器SHT30参考代码资料
    发表于 08-30 16:40 34次下载

    SHT30湿度传感器使用记录(AVR atmega128)

    SHT30使用记录(基于AVR)文章目录SHT30使用记录(基于AVR)硬件篇软件篇硬件篇硬件按照数据手册连接到单片机IIC接口或者任意两个IO口即可,加2个4.7K左右上拉电阻,本
    发表于 11-15 20:06 21次下载
    <b class='flag-5'>SHT30</b>温<b class='flag-5'>湿度</b>传感器使用记录(AVR atmega128)

    SHT30湿度模块使用

    的STH30一般是用IIC(I2C)通信使用的,所以我们打开一个IIC通道,IIC默认配置就可以了。4、因为我们需要看见她的效果是什么,我开了一个串口,所有数据通过串口打印出来。5、然
    发表于 12-16 16:53 71次下载
    <b class='flag-5'>SHT30</b>温<b class='flag-5'>湿度</b>模块使用

    STM32之IIC通讯-SHT30湿度采集

    一、实验目的:通过单片机普通IO口,模拟IIC时序,掌握IIC通讯协议。二、实验用到的主控芯片:STM32F103RCT6,
    发表于 12-22 18:49 35次下载
    STM32之<b class='flag-5'>IIC</b>通讯-<b class='flag-5'>SHT30</b>温<b class='flag-5'>湿度</b>采集