基于单片机DHT11温湿度NRF2401无线通信控制系统

news2024/11/16 0:41:54

一、系统方案

本设计采用STC89C5单片机作为主控制器,从机采用DHT11传感器采集温湿度、按键设置报警阀值,液晶1602显示,蜂鸣器报警,无线NRF2401模块。
在这里插入图片描述

二、硬件设计
原理图如下:
在这里插入图片描述

三、单片机软件设计
1、首先是系统初始化:
init_io(); // 初始化IO
RX_Mode(); // 设置为接收模式
LCD_Initial(); //液晶初始化
2、液晶显示程序
//1602程序
//内部等待函数*************************************************************
unsigned char LCD_Wait(void)
{
RS=0;
RW=1; nop();
E=1; nop();
E=0;
return DBPort;
}
//向LCD写入命令或数据********************************************************
#define LCD_COMMAND 0 // Command
#define LCD_DATA 1 // Data
#define LCD_CLEAR_SCREEN 0x01 // 清屏
#define LCD_HOMING 0x02 // 光标返回原点
void LCD_Write(bit style, unsigned char input)
{
E=0;
RS=style;
RW=0; nop();
DBPort=input; nop();//注意顺序
E=1; nop();//注意顺序
E=0; nop();
LCD_Wait();
}

//设置显示模式************************************************************
#define LCD_SHOW 0x04 //显示开
#define LCD_HIDE 0x00 //显示关

#define LCD_CURSOR 0x02 //显示光标
#define LCD_NO_CURSOR 0x00 //无光标

#define LCD_FLASH 0x01 //光标闪动
#define LCD_NO_FLASH 0x00 //光标不闪动

void LCD_SetDisplay(unsigned char DisplayMode)
{
LCD_Write(LCD_COMMAND, 0x08|DisplayMode);
}

//设置输入模式************************************************************
#define LCD_AC_UP 0x02
#define LCD_AC_DOWN 0x00 // default

#define LCD_MOVE 0x01 // 画面可平移
#define LCD_NO_MOVE 0x00 //default

void LCD_SetInput(unsigned char InputMode)
{
LCD_Write(LCD_COMMAND, 0x04|InputMode);
}

//初始化LCD************************************************************
void LCD_Initial()
{
E=0;
LCD_Write(LCD_COMMAND,0x38); //8位数据端口,2行显示,5*7点阵
LCD_Write(LCD_COMMAND,0x38);
LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); //开启显示, 无光标
LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); //清屏
LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); //AC递增, 画面不动
}

//液晶字符输入的位置************************
void GotoXY(unsigned char x, unsigned char y)
{
if(y0)
LCD_Write(LCD_COMMAND,0x80|x);
if(y
1)
LCD_Write(LCD_COMMAND,0x80|(x-0x40));
}

//将字符输出到液晶显示
void Print(unsigned char *str)
{
while(*str!=‘\0’)
{
LCD_Write(LCD_DATA,*str);
str++;
}
}
3、按键检测程序
void key()
{
if (k10) //调整按键检测
{
delay(10);
if (k1
0)
{
presskeynum++;
if(presskeynum5)
presskeynum=0;
while(k1
0);
LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); //清屏
}
}
if(presskeynum1)//温度上限设置
{
if(k2
0)// 加
{
delay(10);
temp_high++;
if (temp_high>99)
temp_high=0;
if (temp_high<0)
temp_high=99;
while(k20); //加上此句必须松按键才处理
}
if(k3
0)//减
{
delay(10);
temp_high–;
if (temp_high>99)
temp_high=0;
if (temp_high<0)
temp_high=99;
while(k30); //加上此句必须松按键才处理
}
}
if(presskeynum
2)//温度下限设置
{
if(k20)// 加
{
delay(10);
temp_low++;
if (temp_low>99)
temp_low=0;
if (temp_low<0)
temp_low=99;
while(k2
0);
}
if(k30)
{
delay(10);
temp_low–;
if (temp_low>99)
temp_low=0;
if (temp_low<0)
temp_low=99;
while(k3
0);
}
}
if(presskeynum3)//湿度上限设置
{
if(k2
0)// 加
{
delay(10);
humi_high++;
if (humi_high>99)
humi_high=0;
if (humi_high<0)
humi_high=99;
while(k20);
}
if(k3
0)
{
delay(10);
humi_high–;
if (humi_high>99)
humi_high=0;
if (humi_high<0)
humi_high=99;
while(k30);
}
}
if(presskeynum
4)//湿度下限设置
{
if(k20)//加
{
delay(10);
humi_low++;
if (humi_low>99)
humi_low=0;
if (humi_low<0)
humi_low=99;
while(k2
0);
}
if(k30)// 减
{
delay(10);
humi_low–;
if (humi_low>99)
humi_low=0;
if (humi_low<0)
humi_low=99;
while(k3
0);
}
}
if(k40)// 退出键
{
delay(10);
if(k4
0)
{
while(k4==0);
presskeynum=0;

      LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);   			//清屏
   }

}
}

4、核心算法程序
/**************************************************/

/**************************************************
*函数名: SPI_RW
*函数功能: 读写一个字节
*输入: 无
*输出: 无
//
uchar SPI_RW(uchar byte)
{
uchar i;
for(i=0; i<8; i++) // 循环8次
{
MOSI = (byte & 0x80); // byte最高位输出到MOSI
byte <<= 1; // 低一位移位到最高位
SCK = 1; // 拉高SCK,nRF24L01从MOSI读取1位数据,同时从MISO输出1位数据
byte |= MISO; // 读MISO到byte最低位
SCK = 0; // SCK置低
}
return(byte); // 返回读取一个字节
}
/
/

/**************************************************
*函数名: SPI_RW_Reg
*函数功能: 写数据到reg
*输入: 无
*输出: 无
//
uchar SPI_RW_Reg(uchar reg, uchar value)
{
uchar status;
CSN = 0; // CSN置低,开始传输数据
status = SPI_RW(reg); // 选择寄存器,同时返回状态字
SPI_RW(value); // 写数据到寄存器
CSN = 1; // CSN拉高,结束数据传输
return(status); // 返回状态寄存器
}
/
/

/**************************************************
*函数名: SPI_Read
*函数功能: 从reg寄存器读字节
*输入: 无
*输出: 无
/**************************************************/
uchar SPI_Read(uchar reg)
{

uchar reg_val;

CSN = 0;                    // CSN置低,开始传输数据
  SPI_RW(reg);                // 选择寄存器
  reg_val = SPI_RW(0);        // 然后从该寄存器读数据

  CSN = 1;                    // CSN拉高,结束数据传输
  return(reg_val);            // 返回寄存器数据

}
/**************************************************/

/**************************************************
*函数名: SPI_Read_Buf
*函数功能: 从reg寄存器读数据
*输入: 无
*输出: 无
//
uchar SPI_Read_Buf(uchar reg, uchar * pBuf, uchar bytes)
{
uchar status, i;
CSN = 0; // CSN置低,开始传输数据
status = SPI_RW(reg); // 选择寄存器,同时返回状态字
for(i=0; i<bytes; i++)
pBuf[i] = SPI_RW(0); // 逐个字节从nRF24L01读出
CSN = 1; // CSN拉高,结束数据传输
return(status); // 返回状态寄存器
}
/
/

/**************************************************
*函数名: SPI_Write_Buf
*函数功能: 把缓存的数据写入NRF
*输入: 无
*输出: 无
//
uchar SPI_Write_Buf(uchar reg, uchar * pBuf, uchar bytes)
{
uchar status, i;
CSN = 0; // CSN置低,开始传输数据
status = SPI_RW(reg); // 选择寄存器,同时返回状态字
for(i=0; i<bytes; i++)
SPI_RW(pBuf[i]); // 逐个字节写入nRF24L01
CSN = 1; // CSN拉高,结束数据传输
return(status); // 返回状态寄存器
}
/
/

/**************************************************
*函数名: RX_Mode
*函数功能: 将nrf设置为接收模式
*输入: 无
*输出: 无
//
void RX_Mode(void)
{
CE = 0;
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 接收设备接收通道0使用和发送设备相同的发送地址
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 使能接收通道0自动应答
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 使能接收通道0
SPI_RW_Reg(WRITE_REG + RF_CH, 40); // 选择射频通道0x40
SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); // 接收通道0选择和发送通道相同有效数据宽度
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // CRC使能,16位CRC校验,上电,接收模式
delay_ms(150);
CE = 1; // 拉高CE启动接收设备
}
/
/

/**************************************************
*函数名: TX_Mode
*函数功能: 将nrf设置为发送模式
*输入: 无
*输出: 无
//
void TX_Mode(uchar * BUF)
{
CE = 0;
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写入发送地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 应答接收设备,接收通道0地址和发送地址相同
SPI_Write_Buf(WR_TX_PLOAD, BUF, TX_PLOAD_WIDTH); // 写数据包到TX FIFO
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 使能接收通道0自动应答
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 使能接收通道0
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x0a); // 自动重发延时等待250us+86us,自动重发
SPI_RW_Reg(WRITE_REG + RF_CH, 40); // 选择射频通道0x40
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // CRC使能,16位CRC校验,上电
delay_ms(150);
CE = 1;
}
/
/

/**************************************************
*函数名: Check_ACK
*函数功能: 检查接收设备有无数据包,设定没有应答信号重发
*输入: 无
*输出: 无
/**************************************************/
uchar Check_ACK(bit clear)
{
while(IRQ);
sta = SPI_RW(NOP); // 返回状态寄存器
if(TX_DS)
{
//blink(3);
}
//blink(5);
if(MAX_RT)
if(clear) // 是否清除TX FIFO,没有清除在复位MAX_RT中断标志后重发
SPI_RW(FLUSH_TX);
SPI_RW_Reg(WRITE_REG + STATUS, sta); // 清除TX_DS或MAX_RT中断标志
IRQ = 1;
if(TX_DS)
return(0x00);
else
return(0xff);
}

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

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

相关文章

SQL-每日一题【1527. 患某种疾病的患者】

题目 患者信息表&#xff1a; Patients 查询患有 I 类糖尿病的患者 ID &#xff08;patient_id&#xff09;、患者姓名&#xff08;patient_name&#xff09;以及其患有的所有疾病代码&#xff08;conditions&#xff09;。I 类糖尿病的代码总是包含前缀 DIAB1 。 按 任意顺序…

aardio开发语言Excel数据表读取修改保存实例练习

import win.ui; /*DSG{{*/ var winform win.form(text"aardio form";right759;bottom479) winform.add( buttonEnd{cls"button";text"末页";left572;top442;right643;bottom473;z6}; buttonExcelRead{cls"button";text"读取Exce…

基于Java/springboot铁路物流数据平台的设计与实现

摘要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;铁路物流数据平台当然也不能排除在外&#xff0c;从文档信息、铁路设计的统计和分析&#xff0c;在过程中会产生大量的、各…

云原生反模式

通过了解这些反模式并遵循云原生最佳实践&#xff0c;您可以设计、构建和运营更加强大、可扩展和成本效益高的云原生应用程序。 1.单体架构&#xff1a;在云上运行一个大而紧密耦合的应用程序&#xff0c;妨碍了可扩展性和敏捷性。2.忽略成本优化&#xff1a;云服务可能昂贵&am…

攻防世界-Training-WWW-Robots

原题 解题思路 robots.txt是网站的爬虫声明&#xff0c;说明允许哪些部分被爬取&#xff0c;进robots.txt看看。 f1.g.php不让看&#xff0c;进去看看。

AWS复制EC2文件到S3,g4dn.2xlarge没有NVIDIA GPU 驱动问题

1、给instances权限 action > Security > modify IAM role 把提前创建好的role给这个instance即可 2、复制到bucket aws s3 cp gogo.tar.gz s3://ee547finalbucket不需要手动安装GPU驱动 如果要自己安装&#xff0c;参考https://docs.aws.amazon.com/AWSEC2/latest/U…

snpEff变异注释的一点感想

snpEff变异注释整成人生思考 1.介绍2.安装过程以及构建物种参考数据库3.坑货来了4.结果文件判读5.小tips 1.介绍 &nbsp SnpEff&#xff08;Snp Effect&#xff09;是一个用于预测基因组变异&#xff08;例如单核苷酸变异、插入、缺失等&#xff09;对基因功能的影响的生物…

嵌入式开发之configure

1 前述 在Linux的应用或者驱动开发过程中&#xff0c;编写makefile是无法避免的问题&#xff0c;但是由于makefile的各种规则&#xff0c;或显式&#xff0c;或隐式&#xff0c;非常多&#xff0c;不经常写的话&#xff0c;很难写出一个可用的makefile文件。为了“偷懒”&…

07_缓存预热缓存雪崩缓存击穿缓存穿透

缓存预热&缓存雪崩&缓存击穿&缓存穿透 一、缓存预热 提前将数据从数据库同步到redis。 在程序启动的时候&#xff0c;直接将数据刷新到redis懒加载&#xff0c;用户访问的时候&#xff0c;第一次查询数据库&#xff0c;然后将数据写入redis 二、缓存雪崩 发生情…

Python 的下一代 HTTP 客户端

迷途小书童 读完需要 9分钟 速读仅需 3 分钟 1 环境 windows 10 64bitpython 3.8httpx 0.23.0 2 简介 之前我们介绍过使用 requests ( https://xugaoxiang.com/2020/11/28/python-module-requests/ ) 来进行 http 操作&#xff0c;本篇介绍另一个功能非常类似的第三方库 httpx&…

深入探索JavaScript中的5种经典算法

在本文中&#xff0c;您将了解到&#xff1a; 冒泡排序、快速排序等常见排序算法原理及其在 JavaScript 中的实现&#xff1b; 经典算法示例 1. 冒泡排序算法 冒泡排序算法&#xff1a;冒泡排序是一种简单但效率较低的排序算法。它通过多次遍历数组&#xff0c;比较相邻元素并…

JVM前世今生之JVM内存模型

JVM内存模型所指的是JVM运行时区域&#xff0c;该区域分为两大块 线程共享区域 堆内存、方法区&#xff0c;即所有线程都能访问该区域&#xff0c;随着虚拟机和GC创建和销毁 线程独占区域 虚拟机栈、本地方法栈、程序计数器&#xff0c;即每个线程都有自己独立的区域&#…

生成式AI系列 —— DCGAN生成手写数字

1、模型构建 1.1 构建生成器 # 导入软件包 import torch import torch.nn as nnclass Generator(nn.Module):def __init__(self, z_dim20, image_size256):super(Generator, self).__init__()self.layer1 nn.Sequential(nn.ConvTranspose2d(z_dim, image_size * 32,kernel_s…

基于web的停车场收费管理系统/基于springboot的停车场管理系统

摘 要 随着汽车工业的迅猛发展&#xff0c;我国汽车拥有量急剧增加。停车场作为交通设施的组成部分,随着交通运输的繁忙和不断发展&#xff0c;人们对其管理的要求也不断提高&#xff0c;都希望管理能够达到方便、快捷以及安全的效果。停车场的规模各不相同,对其进行管理的模…

深入理解ASP.NET Core中的Program类和Startup类

一、背景介绍 本文以ASP.NET Core 6以前版本API程序来说明。 在我们新建ASP.NET Core项目时&#xff0c;项目根目录下会自动建立Program.cs和Startup.cs两个类文件。 Program.cs 作为 Web 应用程序的默认入口&#xff0c;不做任何修改的情况下&#xff0c;会调用同目录下 Star…

Dubbo 融合 Nacos 成为注册中心

快速上手 Dubbo 融合 Nacos 成为注册中心的操作步骤非常简单&#xff0c;大致步骤可分为“增加 Maven 依赖”以及“配置注册中心“。 增加 Maven 依赖 只需要依赖Dubbo客户端即可&#xff0c;关于推荐的使用版本&#xff0c;请参考Dubbo官方文档或者咨询Dubbo开发人员&#…

Vue 2 组件基础

一个简单的组件示例&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</titl…

暴力模拟入门+简单:零件组装、塔子的签到题、塔子哥考试、平均像素值、换座位

暴力模拟入门 P1038 小红书-2022.9.23-零件组装 #include <bits/stdc.h> #include <cstdint> using namespace std;typedef long long LL; const int N 100001; int num[4]; LL d; vector<vector<LL>> v(4, vector<LL>(N));int main() {for(in…

python中的__name__是个啥?

pycharm中随便打开一个文件&#xff0c;在special variables中能看到一个__name__的变量 在很多python脚本中&#xff0c;也经常能看到if name "main"这样一行 所以_name_到底是个啥&#xff1f; 首先&#xff0c;我们可以确定这是一个str字符变量 “在 Python 中&…