基于单片机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(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.mzph.cn/news/44353.shtml

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

相关文章

使用 umap 图形化展示原文在嵌入后的位置情况

使用 umap_plot 图形化展示原文在嵌入后的位置情况 1. 效果展示2. 工具函数3. 示例代码14. 示例代码2 1. 效果展示 2. 工具函数 import umap import altair as altfrom numba.core.errors import NumbaDeprecationWarning, NumbaPendingDeprecationWarning import warningswar…

G0第26章:微服务概述与gRPCprotocol buffers

Go微服务与云原生 1、微服务架构介绍 单体架构&#xff08;电商&#xff09; SOA架构&#xff08;电商&#xff09; 微服务架构&#xff08;电商&#xff09; 优势 挑战 拆分 发展史 第一代:基于RPC的传统服务架构 第二代:Service Mesh(istio) 微服务架构分层 核心组件 Summar…

【GaussDB】 SQL 篇

建表语句 表的分类 普通的建表语句 复制表内容 只复制表结构 create table 新表名(like 源表名 including all); 如果希望注释被复制的话要指定including comments 复制索引、主键约束和唯一约束&#xff0c;那么需要指定including indexes including constraints &#xf…

MsrayPlus多功能搜索引擎采集软件

MsrayPlus多功能搜索引擎采集软件 摘要&#xff1a; 本文介绍了一款多功能搜索引擎软件-MsrayPlus&#xff0c;该软件能够根据关键词从搜索引擎中检索相关数据&#xff0c;并提供搜索引擎任务、爬虫引擎任务和联系信息采集三大功能。我们将分析该软件在不同领域的应用&#xf…

VBA技术资料MF43:VBA_Excel中自动填充

【分享成果&#xff0c;随喜正能量】以时寝息&#xff0c;当愿众生&#xff0c;身得安隐&#xff0c;心无动乱。愿我们都能&#xff0c;梦见幸福&#xff01;在踉跄中前进&#xff0c;在跌倒后跃进&#xff0c;逐渐强大.。 我给VBA的定义&#xff1a;VBA是个人小型自动化处理的…

使用Jmeter自带recorder代理服务器录制接口脚本

脚本录制 配置线程组 添加代理服务器 端口 和 录制脚本放置位置可根据需要设置 启动录制 点击启动后 弹出创建证书提示&#xff0c;点击OK 这个证书后续需要使用到 然后可见 一个弹窗。 Recorder . 本质是代理服务录制交易控制 可设置对应数据 方便录制脚本的查看 证书配置…

jenkins一键部署github项目

个人目前理解jenkins部署分为两步&#xff1a; 构建项目&#xff0c;如生成jar自动执行sh脚本 如果没有jenkins&#xff0c;我们可能需要将jar移动到服务器&#xff0c;然后执行java -jar跑程序&#xff0c;jenkins可以替代我们执行这些东西&#xff0c;下面从0开始&#xff0…

前端 -- 基础 网页、HTML、 WEB标准 扫盲详解

什么是网页 : 网页是构成网站的基本元素&#xff0c;它通常由 图片、链接、文字、声音、视频等元素组成。 通常我们看到的网页 &#xff0c;常见以 .html 或 .htm 后缀结尾的文件&#xff0c; 因此俗称 HTML 文件 什么是 HTML : HTML 指的是 超文本标记语言&#xff0c…

Python入门--变量和数据类型

什么是变量&#xff1f; 在编程中&#xff0c;变量是指内存中的一段存储空间&#xff0c;用于存储数据。使用变量可以方便地存储数据并在程序中进行操作。 如何定义变量&#xff1f; 在Python中&#xff0c;可以使用“”符号来定义变量&#xff0c;例如&#xff1a; a 1 b …

基于IMX6ULLmini的linux裸机开发系列七:中断处理流程

中断上下文 cpu通过内核寄存器来运行指令并进行数据的读写处理的&#xff0c;它在进入中断前一个时刻的具体值&#xff0c;称为中断上下文 中断上下文是指CPU在进入中断之前保存的寄存器状态和其他相关信息。当CPU接收到中断请求时&#xff0c;它会保存当前正在执行的指令的状…

[python爬虫] 爬取图片无法打开或已损坏的简单探讨

本文主要针对python使用urlretrieve或urlopen下载百度、搜狗、googto&#xff08;谷歌镜像&#xff09;等图片时&#xff0c;出现"无法打开图片或已损坏"的问题&#xff0c;作者对它进行简单的探讨。同时&#xff0c;作者将进一步帮你巩固selenium自动化操作和urllib…

sklearn机器学习库(二)sklearn中的随机森林

sklearn机器学习库(二)sklearn中的随机森林 集成算法会考虑多个评估器的建模结果&#xff0c;汇总之后得到一个综合的结果&#xff0c;以此来获取比单个模型更好的回归或分类表现。 多个模型集成成为的模型叫做集成评估器&#xff08;ensemble estimator&#xff09;&#xf…

CloudCompare——统计滤波

目录 1.统计滤波2.软件实现3.完整操作4.算法源码5.相关代码 本文由CSDN点云侠原创&#xff0c;CloudCompare——统计滤波&#xff0c;爬虫自重。如果你不是在点云侠的博客中看到该文章&#xff0c;那么此处便是不要脸的爬虫。 1.统计滤波 算法原理见&#xff1a;PCL 统计滤波器…

基于IMX6ULLmini的linux裸机开发系列八:按键处理实验

目录 GIC相关寄存器 GPIO中断相关寄存器 中断服务函数表 中断向量表偏移位置 make有报错 解决方法&#xff1a;error: for loop initial declarations are only allowed in C99 mode_‘for’ loop initial declarations are only allowed i_Young_2717的博客-CSDN博客 GIC…

智慧工地一体化云平台源码:监管端、工地端、危大工程、智慧大屏、物联网、塔机、吊钩、升降机

智慧工地解决方案依托计算机技术、物联网、云计算、大数据、人工智能、VR&AR等技术相结合&#xff0c;为工程项目管理提供先进技术手段&#xff0c;构建工地现场智能监控和控制体系&#xff0c;弥补传统方法在监管中的缺陷&#xff0c;最终实现项目对人、机、料、法、环的全…

linux RabbitMQ-3.8.5 安装

软件版本操作系统CentOS Linux release 7.9.2009erlangerlang-23.0.2-1.el7.x86_64rabbitMQrabbitmq-server-3.8.5-1.el7 RabbitMQ的安装首先需要安装Erlang,因为它是基于Erlang的VM运行的。 RabbitMQ安装需要依赖:socat和logrotate&#xff0c;logrotate操作系统已经存在了&…

【Redis】什么是缓存穿透,如何预防缓存穿透?

【Redis】什么是缓存穿透&#xff0c;如何预防缓存穿透&#xff1f; 缓存穿透是指查询一个一定不存在的数据&#xff0c;由于缓存中不存在&#xff0c;这时会去数据库查询查不到数据则不写入缓存&#xff0c;这将导致这个不存在的数据每次请求都要到数据库去查询&#xff0c;这…

Redis中常见的缓存穿透、缓存击穿、缓存雪崩、缓存预热解决方案

文章目录 一、缓存穿透1. 什么是缓存穿透2. 解决方案2.1 无效的key存放到Redis2.2 引入布隆过滤器2.3 如何选择&#xff1a; 二、缓存击穿1. 什么是缓存击穿2. 解决方案 三、缓存雪崩1. 什么是缓存雪崩2. 解决方案2.1 均匀过期2.2 热点数据缓存永远不过期2.3 采取限流降级的策略…

零基础如何学习 Web 安全,如何让普通人快速入门网络安全?

前言 网络安全现在是朝阳行业&#xff0c;缺口是很大。不过网络安全行业就是需要技术很多的人达不到企业要求才导致人才缺口大 【一一帮助安全学习&#xff08;网络安全面试题学习路线视频教程工具&#xff09;一一】 初级的现在有很多的运维人员转网络安全&#xff0c;初级…

Linux0.11内核源码解析-truncate.c

truncate文件只要实现释放指定i节点在设备上占用的所有逻辑块&#xff0c;包括直接块、一次间接块、二次间接块。从而将文件节点对应的文件长度截为0&#xff0c;并释放占用的设备空间。 索引节点的逻辑块连接方式 释放一次间接块 static void free_ind(int dev,int block) {…