基于单片机DHT11温湿度NRF2401无线通信控制系统
一、系统方案
本设计采用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(y1)
 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 (k10)
 {
 presskeynum++;
 if(presskeynum5)
 presskeynum=0;
 while(k10);
 LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); //清屏
 }
 }
 if(presskeynum1)//温度上限设置
 {
 if(k20)// 加
 {
 delay(10);
 temp_high++;
 if (temp_high>99)
 temp_high=0;
 if (temp_high<0)
 temp_high=99;
 while(k20); //加上此句必须松按键才处理
 }
 if(k30)//减
 {
 delay(10);
 temp_high–;
 if (temp_high>99)
 temp_high=0;
 if (temp_high<0)
 temp_high=99;
 while(k30); //加上此句必须松按键才处理
 }
 }
 if(presskeynum2)//温度下限设置
 {
 if(k20)// 加
 {
 delay(10);
 temp_low++;
 if (temp_low>99)
 temp_low=0;
 if (temp_low<0)
 temp_low=99;
 while(k20);
 }
 if(k30)
 {
 delay(10);
 temp_low–;
 if (temp_low>99)
 temp_low=0;
 if (temp_low<0)
 temp_low=99;
 while(k30);
 }
 }
 if(presskeynum3)//湿度上限设置
 {
 if(k20)// 加
 {
 delay(10);
 humi_high++;
 if (humi_high>99)
 humi_high=0;
 if (humi_high<0)
 humi_high=99;
 while(k20);
 }
 if(k30)
 {
 delay(10);
 humi_high–;
 if (humi_high>99)
 humi_high=0;
 if (humi_high<0)
 humi_high=99;
 while(k30);
 }
 }
 if(presskeynum4)//湿度下限设置
 {
 if(k20)//加
 {
 delay(10);
 humi_low++;
 if (humi_low>99)
 humi_low=0;
 if (humi_low<0)
 humi_low=99;
 while(k20);
 }
 if(k30)// 减
 {
 delay(10);
 humi_low–;
 if (humi_low>99)
 humi_low=0;
 if (humi_low<0)
 humi_low=99;
 while(k30);
 }
 }
 if(k40)// 退出键
 {
 delay(10);
 if(k40)
 {
 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);
 }
相关文章:
基于单片机DHT11温湿度NRF2401无线通信控制系统
一、系统方案 本设计采用STC89C5单片机作为主控制器,从机采用DHT11传感器采集温湿度、按键设置报警阀值,液晶1602显示,蜂鸣器报警,无线NRF2401模块。 二、硬件设计 原理图如下: 三、单片机软件设计 1、首先是系统…...
AutoSAR配置与实践(基础篇)2.5 RTE对数据一致性的管理
传送门 点击返回 ->AUTOSAR配置与实践总目录 AutoSAR配置与实践(基础篇)2.5 RTE对数据一致性的管理 一、 数据一致性问题引入二、 数据一致性的管理2.1 RTE管理 (SWC间)2.2 中断保护 (SWC内)2.3 变量保护IRVS (SWC内)2.4 Task分配2.5 任务抢占控制 一…...
ASP.NET WEB API通过SugarSql连接MySQL数据库
注意:VS2022企业版可以,社区版可能存在问题。实体名称和字段和数据库中的要一致。 1、创建项目,安装SqlSugarCore、Pomelo.EntityFrameworkCore.MySql插件 2、文件结构 2、appsettings.json { “Logging”: { “LogLevel”: { “Default”: …...
08-微信小程序视图层
08-微信小程序视图层 文章目录 视图层 ViewWXML数据绑定列表渲染条件渲染模板引用importimport 的作用域include WXSS尺寸单位样式导入内联样式选择器全局样式与局部样式 WXS注意事项页面渲染数据处理 视图层 View 框架的视图层由 WXML 与 WXSS 编写,由组件来进行…...
[机器学习]特征工程:特征降维
特征降维 1、简介 特征降维是指通过减少特征空间中的维度,将高维数据映射到一个低维子空间的过程。 在机器学习和数据分析中,特征降维可以帮助减少数据的复杂性、降低计算成本、提高模型性能和可解释性,以及解决维度灾难等问题。特征降维通…...
12. Docker可视化工具
目录 1、前言 2、Docker UI 2.1、部署Docker UI 2.2、管理容器 3、Portainer 3.1、部署Portainer 3.2、管理容器 3.3、添加远程Docker 4、Shipyard 1、前言 Docker 提供了命令行工具来管理 Docker 的镜像和运行 Docker 的容器。我们也可以使用图形工具来管理 Docker。…...
css层叠关系
文章目录 cascading声明冲突应用重置样式表a元素的类选择器顺序问题 cascading cascading – 层叠 解决声明冲突的过程,浏览器会自动处理;就是计算样式的权重,权重大的就被选择; 声明冲突 是指多个选择器选中同一个标签&#x…...
【Unity实战篇 】| 如何在小游戏中快速接入一个新手引导教程
前言 【Unity实战篇 】 | 如何在小游戏中快速接入一个新手引导教程一、简单教程描述二、接入Tutorial Master 实现游戏引导2.1 导入Tutorial Master2插件2.2 添加TutorialMasterManager脚本对象2.3 配置Tutorial,用于管理第一段引导内容2.4 配置Stage,用…...
Lookup Singularity
1. 引言 Lookup Singularity概念 由Barry WhiteHat在2022年11月在zkResearch论坛 Lookup Singularity中首次提出: 其主要目的是:让SNARK前端生成仅需做lookup的电路。Barry预测这样有很多好处,特别是对于可审计性 以及 形式化验证ÿ…...
idea 本地版本控制 local history
idea 本地版本控制 local history 如何打开 1 自定义快捷键 settings->keymap->搜索框输入 show history -》Add Keyboard Shortcut -》设置为 CtrlAltL 2 右键文件-》local history -》show history 新建文件 版本1,creating class com.geekmice…这个是初…...
【Freertos基础入门】深入浅出freertos互斥量
文章目录 前言一、互斥量是什么?二、互斥量的使用场景三、互斥量的使用1.创建 2.删除互斥量3.give和take四、示例代码总结 前言 FreeRTOS是一款开源的实时操作系统,提供了许多基本的内核对象,其中包括互斥锁(Mutex)。…...
皮爷咖啡基于亚马逊云科技的数据架构,加速数据治理进程
皮爷咖啡(Peet’s Coffee)是美国精品咖啡品牌,于2017年进入中国,为中国消费者带来传统经典咖啡饮品,并特别呈现更加丰富的品质咖啡饮品体验。通过深入应用亚马逊云科技云原生数据库产品Amazon Redshift以及Amazon DMS等…...
C++ string类详解
⭐️ string string 是表示字符串的字符串类,该类的接口与常规容器的接口基本一致,还有一些额外的操作 string 的常规操作,在使用 string 类时,需要使用 #include <string> 以及 using namespace std;。 ✨ 帮助文档&…...
深入浅出Pytorch函数——torch.nn.init.ones_
分类目录:《深入浅出Pytorch函数》总目录 相关文章: 深入浅出Pytorch函数——torch.nn.init.calculate_gain 深入浅出Pytorch函数——torch.nn.init.uniform_ 深入浅出Pytorch函数——torch.nn.init.normal_ 深入浅出Pytorch函数——torch.nn.init.c…...
一、docker及mysql基本语法
文章目录 一、docker相关命令二、mysql相关命令 一、docker相关命令 (1)拉取镜像:docker pull <镜像ID/image> (2)查看当前docker中的镜像:docker images (3)删除镜像&#x…...
【计算机网络】13、ARP 包:广播自己的 mac 地址和 ip
机器启动时,会向外广播自己的 mac 地址和 ip 地址,这个即称为 arp 协议。范围是未经过路由器的部分,如下图的蓝色部分,范围内的设备都会在本地记录 mac 和 ip 的绑定信息,若有重复则覆盖更新(例如先收到 ma…...
通过微软Azure调用GPT的接口API-兼容平替OpenAI官方的注意事项
众所周知,我们是访问不通OpenAI官方服务的,但是我们可以自己通过代理或者使用第三方代理访问接口 现在新出台的规定禁止使用境外的AI大模型接口对境内客户使用,所以我们需要使用国内的大模型接口 国内的效果真的很差,现在如果想使…...
回归预测 | MATLAB实现BO-SVM贝叶斯优化支持向量机多输入单输出回归预测(多指标,多图)
回归预测 | MATLAB实现BO-SVM贝叶斯优化支持向量机多输入单输出回归预测(多指标,多图) 目录 回归预测 | MATLAB实现BO-SVM贝叶斯优化支持向量机多输入单输出回归预测(多指标,多图)效果一览基本介绍程序设计…...
GAN!生成对抗网络GAN全维度介绍与实战
目录 一、引言1.1 生成对抗网络简介1.2 应用领域概览1.3 GAN的重要性 二、理论基础2.1 生成对抗网络的工作原理2.1.1 生成器生成过程 2.1.2 判别器判别过程 2.1.3 训练过程训练代码示例 2.1.4 平衡与收敛 2.2 数学背景2.2.1 损失函数生成器损失判别器损失 2.2.2 优化方法优化代…...
自动驾驶仿真:基于Carsim开发的加速度请求模型
文章目录 前言一、加速度输出变量问题澄清二、配置Carsim动力学模型三、配置Carsim驾驶员模型四、添加VS Command代码五、Run Control联合仿真六、加速度模型效果验证 前言 1、自动驾驶行业中,算法端对于纵向控制的功能预留接口基本都是加速度,我们需要…...
K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...
【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...
Python训练营-Day26-函数专题1:函数定义与参数
题目1:计算圆的面积 任务: 编写一个名为 calculate_circle_area 的函数,该函数接收圆的半径 radius 作为参数,并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求:函数接收一个位置参数 radi…...
Java多线程实现之Runnable接口深度解析
Java多线程实现之Runnable接口深度解析 一、Runnable接口概述1.1 接口定义1.2 与Thread类的关系1.3 使用Runnable接口的优势 二、Runnable接口的基本实现方式2.1 传统方式实现Runnable接口2.2 使用匿名内部类实现Runnable接口2.3 使用Lambda表达式实现Runnable接口 三、Runnabl…...
