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

这篇具有很好参考价值的文章主要介绍了基于51单片机+SHT30设计的环境温度与湿度检测设备(IIC模拟时序)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、项目介绍

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

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

基于51单片机+SHT30设计的环境温度与湿度检测设备(IIC模拟时序),STM32单片机开发基础,stm32,嵌入式硬件,单片机

二、硬件设计

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。文章来源地址https://www.toymoban.com/news/detail-541993.html

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

到了这里,关于基于51单片机+SHT30设计的环境温度与湿度检测设备(IIC模拟时序)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于AT89C51单片机的温度检测报警设计

    点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/87777752?spm=1001.2014.3001.5503 源码获取 主要内容: 基于51单片机设计一个温度检测报警器,至少具有以下功能:温度的检测和超过设定值时的报警功能 基本要求: 1、功能齐全,要配有功能说明;

    2024年02月03日
    浏览(45)
  • 基于AT89C51单片机的温度计设计

    点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/87773445 源码获取 主要内容: 设计一个简易温度计;要求电路实现如下功能: 设计通过单片机和数码管、led灯等组成,可以显示温度,并且可以显示大于零度的温度和小于零度的温度,还可以超出

    2024年02月05日
    浏览(38)
  • 43、基于51单片机数码管温控温度控制风扇系统设计

    温控风扇在现代社会中的生产以及人们的日常生活中都有广泛的应用,如工业生产中大型机械散热系统中的风扇、现在笔记本电脑上的广泛应用的智能CPU风扇等。本文设计了基于单片机的温控风扇系统,采用单片机作为控制器,利用温度传感器DS18B20作为温度采集元件,并根据

    2024年02月04日
    浏览(45)
  • 7、基于51单片机智能热水器温度水温水位检测控制系统设计

    毕设帮助、开题指导、技术解答(有偿)见文末。 目录 摘要 一、硬件方案 二、设计功能 三、实物图 四、原理图 五、PCB图 六、Proteus仿真  七、程序源码 八、资料包括 随着社会的发展,人类科技的进步,各行各业都在使自己的产品智能化、数字化,因老式的热水器使用煤

    2024年02月09日
    浏览(64)
  • 47、基于51单片机万年历温度闹钟农历阳历LCD 12864显示系统设计

    本文介绍了基于STC89C52单片机的多功能电子万年历的硬件结构和软硬件设计方法。本设计由数据显示模块、温度采集模块、时间处理模块和调整设置模块四个模块组成。系统以STC89C52单片机为控制器,以串行时钟日历芯片DS1302记录日历和时间,它可以对年、月、日、时、分、秒

    2024年02月09日
    浏览(74)
  • 基于51单片机的DS18B20温度控制加热降温系统设计

    仿真图:proteus8.9以上 程序代码:KEIL4/KEIL5 原理图:AD 设计编号:A0007 结合实际情况,基于51单片机设计一个排队叫号系统设计。该系统应满足的功能要求为: 系统由51单片机、DS18B20温度传感器、LCD1602液晶显示屏、继电器、风扇、加热膜、按键、蜂鸣器组成。 可实现以下基本功能

    2023年04月09日
    浏览(63)
  • 122、仿真-基于51单片机的电量监测电压电流和温度报警系统设计(Proteus仿真+程序+流程图+配套资料等)

    方案选择 单片机的选择 方案一:STM32系列单片机控制,该型号单片机为LQFP44封装,内部资源足够用于本次设计。STM32F103系列芯片最高工作频率可达72MHZ,在存储器的01等等待周期仿真时可达到1.25Mip/MHZ(Dhrystone2.1)。内部128k字节的闪存程序存储器,也就是说代码量可以写到128k字

    2024年02月16日
    浏览(33)
  • 基于51单片机的温度报警器

    设计任务: 以51单片机为核心,设计和制作一个温度报警器,能在LCD上显示环境的温度与希望温度上下限阀值,并能设置希望温度上下限阀值,系统上电的时候显示的是当前环境温度和设定的温度阀值,通过按键来修改温度上下限阀值,再次上电时保持上一次的温度设置。根

    2024年02月11日
    浏览(30)
  • 基于51单片机的数字温度计【开源】

    (1)温度实时显示(LCD2864) (2)温度上限下线调节 (3)万年历功能 (4)超温报警 (5)年月日时分秒可调节 (6)温度测量精度0.0625℃ (7)节日自动判定 STC89c52,DS18B20,DS1302,按键模块。LCD12864 main.c LCD12864.c ( 主要一些延时和LCD12864的驱动) LCD12864.h (主要一些函数的声

    2024年02月10日
    浏览(29)
  • 【Proteus仿真】【51单片机】温度报警控制系统设计

    本项目使用Proteus8仿真51单片机控制器,使用继电器模块、DS18B20温度传感器模块、LCD1602模块、蜂鸣器、按键模块等。 主要功能: 系统运行后,LCD1602显示DS18B20采集温度值、温度上下限阈值。可通过K1、K2键对温度上限设置,可通过K3、K4键对温度下限设置,若检测温度大于或小

    2024年02月09日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包