基于STM32单片机的农业大棚恒温恒湿控制系统设计
摘要
随着现代农业技术的不断发展,智能化、自动化控制技术在农业生产中的应用日益广泛。本文设计了一种基于STM32单片机的农业大棚恒温恒湿控制系统,该系统集成了温湿度采集、显示、设定阈值以及自动控制等功能,旨在提高大棚内环境控制的精确度和效率。通过DHT11温湿度传感器实时监测大棚内的温湿度数据,利用LCD1602显示屏直观显示,并结合按键模块实现用户交互,最终通过控制电机实现对大棚环境的自动调节。本文详细阐述了系统的硬件设计、软件编程以及Proteus仿真过程。
关键词
STM32单片机;农业大棚;恒温恒湿控制;DHT11;LCD1602
一、引言
农业大棚作为现代农业的重要设施,为农作物提供了相对稳定的生长环境。然而,传统的人工调控方式存在精度低、响应慢等问题,难以满足现代高效农业的需求。因此,开发一种能够自动监测并调节大棚内温湿度的智能控制系统具有重要意义。本系统以STM32单片机为核心,结合DHT11温湿度传感器、LCD1602显示屏、按键模块和电机等硬件,实现了对大棚环境的精准控制。
二、系统功能介绍
2.1 系统架构
本系统主要由STM32单片机控制单元、DHT11温湿度传感器、LCD1602显示屏、按键模块、电机驱动电路以及排气电机、加湿电机、加热电机和制冷电机等部分组成。系统架构如图1所示。
<img src="%E6%AD%A4%E5%A4%84%E6%8F%92%E5%85%A5%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84%E5%9B%BE" />
图1 系统架构图
2.2 功能模块
- 温湿度采集与显示:
- DHT11温湿度传感器:DHT11是一款含有已校准数字信号输出的温湿度复合传感器,它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个DHT11传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式储存在OTP内存中,传感器内部在检测信号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,信号传输距离可达20米以上,使其成为各类应用甚至最为苛刻的应用场合的最佳选则。产品为4针单排引脚封装。连接方便,尤其适合于与单片机系统连接。
- LCD1602显示屏:用于实时显示大棚内的温湿度数据以及用户设定的温湿度阈值。LCD1602是一种工业字符型液晶,能够同时显示16x02即32个字符(16列2行)。
- 温湿度阈值设定:
- 通过按键模块,用户可以方便地设定大棚内期望的温湿度阈值,这些设定值将被显示在LCD1602屏幕上,供用户确认。
- 自动调节功能:
- 湿度控制:当检测到当前湿度大于设定湿度时,自动启动排气电机进行排气以降低湿度;当检测到当前湿度小于设定湿度时,自动启动加湿电机进行加湿。
- 温度控制:当检测到当前温度低于设定温度时,自动启动加热电机进行加热;当检测到当前温度高于设定温度时,自动启动制冷电机进行制冷。
三、硬件设计
3.1 STM32单片机控制单元
STM32系列单片机是意法半导体(STMicroelectronics)推出的一款基于ARM Cortex-M3内核的32位微控制器。本系统选用STM32F103C8T6型号单片机作为控制核心,其具有高性能、低功耗、丰富的外设资源等优点,能够满足本系统对数据处理和控制精度的要求。
3.2 DHT11温湿度传感器模块
DHT11温湿度传感器模块与STM32单片机通过单总线方式进行通信,数据格式为40位,高位在前。具体连接方式为:DHT11的VCC接STM32的3.3V电源,GND接地,DATA引脚接STM32的一个GPIO口(如PA0)。在通信过程中,STM32单片机作为主机,DHT11作为从机,主机发送开始信号后,等待从机响应并返回温湿度数据。
3.3 LCD1602显示屏模块
LCD1602显示屏模块采用并行接口与STM32单片机连接,具体连接方式为:LCD1602的RS、RW、E引脚分别接STM32的三个GPIO口(如PA1、PA2、PA3),D4D7引脚接STM32的另外四个GPIO口(如PA4PA7),用于传输数据。V0引脚用于调整对比度,可外接一个电位器进行调节。
3.4 按键模块
按键模块用于用户输入温湿度阈值,采用独立按键方式,每个按键对应一个GPIO口。当按键按下时,对应的GPIO口电平发生变化,STM32单片机通过检测这些变化来判断用户输入的指令。
3.5 电机驱动电路
电机驱动电路采用L298N电机驱动模块,该模块能够驱动两台直流电机或一台步进电机。本系统中,L298N的IN1~IN4引脚分别接STM32的四个GPIO口,用于控制电机的正反转和启停;ENA和ENB引脚分别接PWM信号输出引脚,用于调节电机转速。电机驱动电路与STM32单片机的连接如图2所示。
<img src="%E6%AD%A4%E5%A4%84%E6%8F%92%E5%85%A5%E7%94%B5%E6%9C%BA%E9%A9%B1%E5%8A%A8%E7%94%B5%E8%B7%AF%E5%9B%BE" />
图2 电机驱动电路图
四、软件设计
4.1 主程序设计
主程序负责初始化系统资源、读取温湿度数据、显示数据、检测按键输入以及控制电机等。主程序流程图如图3所示。
<img src="%E6%AD%A4%E5%A4%84%E6%8F%92%E5%85%A5%E4%B8%BB%E7%A8%8B%E5%BA%8F%E6%B5%81%E7%A8%8B%E5%9B%BE" />
图3 主程序流程图
4.2 DHT11温湿度数据采集程序
DHT11温湿度数据采集程序通过单总线协议与DHT11传感器进行通信,获取温湿度数据。具体步骤为:发送开始信号→等待DHT11响应→读取40位数据→校验数据→处理数据。DHT11温湿度数据采集程序流程图如图4所示。
<img src="%E6%AD%A4%E5%A4%84%E6%8F%92%E5%85%A5DHT11%E6%95%B0%E6%8D%AE%E9%87%87%E9%9B%86%E6%B5%81%E7%A8%8B%E5%9B%BE" />
图4 DHT11数据采集流程图
4.3 LCD1602显示程序
LCD1602显示程序负责将温湿度数据以及用户设定的温湿度阈值显示在屏幕上。具体步骤为:初始化LCD1602→发送显示指令→发送显示数据。LCD1602显示程序流程图如图5所示。
<img src="%E6%AD%A4%E5%A4%84%E6%8F%92%E5%85%A5LCD1602%E6%98%BE%E7%A4%BA%E6%B5%81%E7%A8%8B%E5%9B%BE" />
图5 LCD1602显示流程图
4.4 按键处理程序
按键处理程序负责检测按键输入,并根据按键值执行相应的操作。具体步骤为:初始化按键引脚→检测按键状态→判断按键值→执行相应操作。按键处理程序流程图如图6所示。
<img src="%E6%AD%A4%E5%A4%84%E6%8F%92%E5%85%A5%E6%8C%89%E9%94%AE%E5%A4%84%E7%90%86%E6%B5%81%E7%A8%8B%E5%9B%BE" />
图6 按键处理流程图
4.5 电机控制程序
电机控制程序根据当前温湿度与设定阈值的比较结果,控制相应电机的启停和转速。具体步骤为:读取当前温湿度→比较当前温湿度与设定阈值→根据比较结果发送电机控制指令。电机控制程序流程图如图7所示。
<img src="%E6%AD%A4%E5%A4%84%E6%8F%92%E5%85%A5%E7%94%B5%E6%9C%BA%E6%8E%A7%E5%88%B6%E6%B5%81%E7%A8%8B%E5%9B%BE" />
图7 电机控制流程图
五、Proteus仿真
5.1 Proteus软件介绍
Proteus是一款专业的EDA仿真软件,支持多种微控制器和外围器件的仿真,能够模拟电路的工作状态和微控制器的程序执行过程。本系统利用Proteus软件进行电路仿真,验证硬件设计的正确性和软件程序的可靠性。
5.2 仿真电路设计
在Proteus软件中,按照硬件设计搭建仿真电路,包括STM32单片机、DHT11温湿度传感器、LCD1602显示屏、按键模块以及电机驱动电路等。仿真电路图如图8所示。
<img src="%E6%AD%A4%E5%A4%84%E6%8F%92%E5%85%A5%E4%BB%BF%E7%9C%9F%E7%94%B5%E8%B7%AF%E5%9B%BE" />
图8 仿真电路图
5.3 仿真结果分析
在仿真过程中,通过STM32单片机向DHT11传感器发送采集指令,获取温湿度数据,并在LCD1602显示屏上显示。同时,通过按键模块设定温湿度阈值,观察电机驱动电路根据当前温湿度与设定阈值的比较结果控制电机的启停和转速。仿真结果表明,系统能够正确采集温湿度数据、显示数据、检测按键输入以及控制电机,达到了预期的设计目标。
六、结论
本文设计了一种基于STM32单片机的农业大棚恒温恒湿控制系统,通过DHT11温湿度传感器实时监测大棚内的温湿度数据,利用LCD1602显示屏直观显示,并结合按键模块实现用户交互,最终通过控制电机实现对大棚环境的自动调节。系统具有结构简单、成本低廉、易于扩展等优点,能够满足现代农业对大棚环境精准控制的需求。通过Proteus仿真验证了系统的正确性和可靠性,为实际应用提供了有力支持。未来,可以进一步优化系统性能,提高控制精度和响应速度,以适应更多样化的农业应用场景。
参考文献
[此处列出参考文献]
#include "adc.h"
#include "delay.h"
//初始化ADC
//这里我们仅以规则通道为例
//我们默认将开启通道0~3
void Adc_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1 , ENABLE ); //使能ADC1通道时钟
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
//PA1 作为模拟通道输入引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
GPIO_Init(GPIOA, &GPIO_InitStructure);
//PB1 作为脉冲输出引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GP2Y_High;
ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //模数转换工作在单通道模式
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //模数转换工作在单次转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目
ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1
ADC_ResetCalibration(ADC1); //使能复位校准
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
ADC_StartCalibration(ADC1); //开启AD校准
while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束
// ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
}
//获得ADC值
//ch:通道值 0~3
u16 Get_Adc(u8 ch)
{
//设置指定ADC的规则组通道,一个序列,采样时间
ADC_RegularChannelConfig(ADC1, ch, 0, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果
}
float GetGP2Y(void)
{
u32 AD_PM;
double pm;
GP2Y_Low;
delay_us(280);
AD_PM = Get_Adc(ADC_Channel_0); //PA0
delay_us(40);
GP2Y_High;
delay_us(9680);
pm = 0.17*AD_PM-0.1; //转换公式
printf("%f\n",pm);
return pm;
}
u16 Get_GP2Y_Average(u8 times)
{
u32 pm_val=0;
u8 t;
for(t=0;t<times;t++)
{
pm_val+=GetGP2Y();
delay_ms(5);
}
return pm_val/times;
}