目录
🤞大家好,这里是5132单片机毕设设计项目分享,今天给大家分享的是智能教室。
++设备的详细功能见网盘中的文章《8、基于STM32的大棚温湿度》:++
链接:https://pan.baidu.com/s/1uWSZX2zbZwy9sYwwnvyktQ?pwd=5132
提取码:5132
农业大棚是设施农业的重要组成部分,大棚测控系统是实现大棚自动化、科学化的基本保证。通过对监测数据的分析,结合作物生长规律,控制环境条件,使作物达到优质、高产、高效的栽培目的。计算机应用技术的发展,也使得用计算机控制的方面也涉及到各个领域,其中在大棚内用单片机控制温度、湿度是应用于实践的主要方面之一。
1、设计要求
本设计选用STM32F103C8T6芯片为核心,通过DHT11检测模块、光敏传感器、土壤湿度传感器输出模块、按键模块和显示模块等,完成一种大棚温湿度监控系统的设计。通过编写相应的程序实现按键控制温湿度的设定,DHT11温湿度传感器检测温湿度的变化并在OLED模块显示测量温湿度数据和设置参数值,最后通过STM32单片机控制风扇和发热片输出实现温湿度的调节。
3、演示视频和实物
D27-基于STM32的大棚温湿度监控系统设计
4、系统设计框图
5、软件设计流程图
大棚温湿度监测系统设计的主程序主要是对相关硬件环境初始化,只有在系统硬件环境初始化成功后,系统才能够正常的工作。初始化过程涵盖了多个方面主要包括外部中断初始化、采集模块初始化、输入模块初始化、输出模块初始化和显示模块初始化,程序完成初始化后,单片机采集到原始ADC数据后,将原始ADC数据经过比例运算得到当前的真实值;然后将当前真实值显示在OLED屏幕上;显示完成后单片机会将当前真实值与设置的阈值进行比较,如果超出了当前设置的阈值,单片机将控制执行对应的输出设备。
6、原理图
7、主程序
下面这个主程序,主要是设计的逻辑控制。
#include "stm32f10x.h" // 有问题和需求的,可以联系VX:lwfw123456789
#include <stdio.h>
#include <string.h>
#include "sys.h"
#include "delay.h"
#include "OLED.h"
#include "Key.h"
#include "OLED.h"
#include "Serial.h"
#include "led.h"
#include "Buzzer.h"
#include "MyRTC.h"
#include "dht11.h"
#include "AD.h"
uint8_t KeyNum; //存储按键值
uint8_t RxData; //蓝牙接收到的数据
u8 temp, humi;
uint32_t bufe[5];
uint16_t AD0, AD1, AD2, AD3; //存储ADC的值
u8 state1 = 1; //设备开关
u8 state2 = 0; //模式选择
u8 state3 = 0; //阈值切换
u8 state4 = 0; //阈值切换
u8 state5 = 0; //阈值切换
u8 t = 0; //温湿度读取值的间隔
short temperature; //存储DS18B20的温度值
u8 flag1; //清屏用到的标志,为了使OLED_Clear();执行一次
u8 flag2; //menu1()中为了使显示的提示信息执行一次
u8 flag3;
u8 flag4;
u8 flag5;
u8 flag6;
u8 wenyu = 23, shiyu = 65, guangyu = 50, tuyu = 50;
void ctrlue()
{
if(state1==0&&state3 == 0 )
{
if(bufe[1]>shiyu) //湿度大于设定阈值开风扇
{
LED4=0;
}else
{
LED4=1;
}
if(bufe[0]<wenyu ) //温度小于阈值开加热,关闭粉丝
{
LED3=1;
LED4=0;
}else
{
LED3=0;
LED4=1;
}
}
}
void shoudong()
{
if(state1==0&&state3 == 1 )
{
if (KeyNum == 4) //一键控制多媒体 PB10
{
delay_ms(20);
if (KeyNum == 4)
{
state4++;
if (state4 > 1)
{
state4 = 0;
}
}
}
if (state4 == 0)
{
LED3 = 1; //开启指示灯
}
if (state4 == 1)
{
LED3 = 0; //关闭设备指示灯
}
if (KeyNum == 5) //一键控制多媒体 PB10
{
delay_ms(20);
if (KeyNum == 5)
{
state5++;
if (state5 > 1)
{
state5 = 0;
}
}
}
if (state5 == 0)
{
LED4 = 1; //开启指示灯
}
if (state5 == 1)
{
LED4 = 0; //关闭设备指示灯
}
}
}
void menu0() //显示题目
{
if (flag3 == 0)
{
OLED_ShowString(1, 1, "XX/XX"); //第一行显示时间
OLED_ShowString(1, 12, "XX:XX");
flag3 = 1;
}
// OLED_ShowNum(1, 6, MyRTC_Time[0], 4); //年
OLED_ShowNum(1, 1, MyRTC_Time[1], 2); //月
OLED_ShowNum(1, 4, MyRTC_Time[2], 2); //日
OLED_ShowNum(1, 12, MyRTC_Time[3], 2); //时
OLED_ShowNum(1, 15, MyRTC_Time[4], 2); //分
// OLED_ShowNum(2, 12, MyRTC_Time[5], 2); //秒
OLED_ShowChinese(3, 3, 73); //显示题目
OLED_ShowChinese(3, 4, 74);
OLED_ShowChinese(3, 5, 75);
OLED_ShowChinese(3, 6, 76);
OLED_ShowChinese(4, 1, 77); //显示题目
OLED_ShowChinese(4, 2, 78);
OLED_ShowChinese(4, 3, 79);
OLED_ShowChinese(4, 4, 80);
OLED_ShowChinese(4, 5, 81);
OLED_ShowChinese(4, 6, 84);
OLED_ShowChinese(4, 7, 85);
}
void menu1() //核心页面,用来显示传感器参数和逻辑判断
{
if (flag4 == 0)
{
OLED_ShowString(1, 1, "XX/XX"); //第一行显示时间
OLED_ShowString(1, 12, "XX:XX");
flag4 = 1;
}
// OLED_ShowNum(1, 6, MyRTC_Time[0], 4); //年
OLED_ShowNum(1, 1, MyRTC_Time[1], 2); //月
OLED_ShowNum(1, 4, MyRTC_Time[2], 2); //日
OLED_ShowNum(1, 12, MyRTC_Time[3], 2); //时
OLED_ShowNum(1, 15, MyRTC_Time[4], 2); //分
// OLED_ShowNum(2, 12, MyRTC_Time[5], 2); //秒
if (flag2 == 0) //里面的代码执行一次
{
flag2 = 1;
OLED_ShowChinese(2, 1, 2); //温湿度
OLED_ShowChinese(2, 2, 4);
OLED_ShowString(2, 5, ":");
OLED_ShowChinese(2, 5, 3);
OLED_ShowChinese(2, 6, 4);
OLED_ShowString(2, 13, ":");
OLED_ShowChinese(3, 1, 51); //土壤湿度
OLED_ShowChinese(3, 2, 52);
OLED_ShowChinese(3, 3, 37);
OLED_ShowChinese(3, 4, 38);
OLED_ShowString(3, 9, ":");
OLED_ShowChinese(4, 1, 16); //光照强度
OLED_ShowChinese(4, 2, 17);
OLED_ShowChinese(4, 3, 37);
OLED_ShowChinese(4, 4, 38);
OLED_ShowString(4, 9, ":");
}
//******************************传感器数据采集****************************************************//
if (t % 10 == 0)
{
DHT11_Read_Data(&temp, &humi); //读取温湿度并显示在OLED上
bufe[0] = temp;
bufe[1] = humi;
OLED_ShowNum(2, 6, bufe[0], 2);
OLED_ShowString(2, 8, "%");
OLED_ShowNum(2, 14, bufe[1], 2);
OLED_ShowString(2, 16, "%");
}
t++;
AD0 = AD_GetValue(ADC_Channel_0); //土壤湿度传感器
if (AD0 > 4000)AD0 = 4000;
bufe[2] = (u8)(AD0 / 40);
OLED_ShowNum(3, 10, bufe[2], 2);
OLED_ShowString(3, 12, "%");
AD1 = AD_GetValue(ADC_Channel_1); //光照强度传感器
if (AD1 > 4000)AD1 = 4000;
bufe[3] = (u8)(100-AD1 / 40);
OLED_ShowNum(4, 10, bufe[3], 2);
OLED_ShowString(4, 12, "%");
//******************************设备开关****************************************************//
if (KeyNum == 1) //一键控制多媒体 PB10
{
state4=0;state5=0;
delay_ms(20);
if (KeyNum == 1)
{
state1++;
if (state1 > 1)
{
state1 = 0;
}
}
}
if (state1 == 0)
{
LED2 = 0; //开启指示灯
}
if (state1 == 1)
{
LED2 = 1; //关闭设备指示灯
Buzzer_OFF();
LED3 = 1;
LED4 = 1;
}
//**************************************模式切换*****************************************************//
if (KeyNum == 3 & state1 == 0) //一键控制自动或者手动 PB11
{
flag6 = 0; flag5 = 0;state4=0;state5=0;
delay_ms(20);
if (KeyNum == 3)
{
state3++;
if (state3 > 1)
{
state3 = 0;
}
}
}
if (state3 == 0 )
{
ctrlue(); // 开
OLED_ShowChinese(4, 8, 30);
if (flag5 == 0)
{
LED3 = 1;
LED4 = 1;
flag5 = 1;
}
}
if (state3 == 1 )
{
shoudong(); // 开
OLED_ShowChinese(4, 8, 29);
if (flag6 == 0) //目的就是使OLED_Clear();执行一次
{
LED3 = 1;
LED4 = 1;
flag6 = 1;
}
}
}
void menu2() //阈值控制
{
OLED_ShowChinese(1, 3, 86);
OLED_ShowChinese(1, 4, 87);
OLED_ShowChinese(1, 5, 88);
OLED_ShowChinese(1, 6, 89);
OLED_ShowChinese(2, 1, 2); //温湿度
OLED_ShowChinese(2, 2, 4);
OLED_ShowString(2, 5, ":");
OLED_ShowChinese(2, 5, 3);
OLED_ShowChinese(2, 6, 4);
OLED_ShowString(2, 13, ":");
OLED_ShowChinese(3, 1, 51); //土壤湿度
OLED_ShowChinese(3, 2, 52);
OLED_ShowChinese(3, 3, 37);
OLED_ShowChinese(3, 4, 38);
OLED_ShowString(3, 9, ":");
OLED_ShowChinese(4, 1, 16); //光照强度
OLED_ShowChinese(4, 2, 17);
OLED_ShowChinese(4, 3, 37);
OLED_ShowChinese(4, 4, 38);
OLED_ShowString(4, 9, ":");
if (KeyNum == 3) //
{
delay_ms(20);
if (KeyNum == 3)
{
state3++;
if (state3 > 4)
{
state3 = 0;
}
}
}
if (state3 == 0)
{
if (KeyNum == 4) wenyu++;
if (KeyNum == 5) wenyu--;
}
OLED_ShowNum(2, 6, wenyu, 2);
if (state3 == 1)
{
if (KeyNum == 4) shiyu++;
if (KeyNum == 5) shiyu--;
}
OLED_ShowNum(2, 14, shiyu, 2);
if (state3 == 2)
{
if (KeyNum == 4) tuyu++;
if (KeyNum == 5) tuyu--;
}
OLED_ShowNum(3, 10, tuyu, 2);
if (state3 == 3)
{
if (KeyNum == 4) guangyu++;
if (KeyNum == 5) guangyu--;
}
OLED_ShowNum(4, 10, guangyu, 2);
}
int main(void) //主函数
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
delay_init(); //延时函数初始化
SystemInit();
Key_Init(); //按键初始化
LED_Init();
OLED_Init();
Buzzer_Init();
Serial_Init(); //串口1初始化
MyRTC_Init();
DHT11_Init();
AD_Init();
while (1)
{
MyRTC_ReadTime(); //读取时间(每一个页面都有时间显示)
KeyNum = Key_GetNum(); //按键检查
//*********************页面切换*****************************************************
if (KeyNum == 2) //页面切换PB1
{
flag1 = 0;
flag3 = 0;
flag4 = 0;
delay_ms(20);
if (KeyNum == 2)
{
state2++;
if (state2 > 2) //3个页面
{
state2 = 0;
}
}
}
if (state2 == 0) //初始页面 显示题目"智能大棚温湿度采集"
{
if (flag1 == 0) //目的就是使OLED_Clear();执行一次
{
OLED_Clear();
flag1 = 1;
}
menu0();
}
else if (state2 == 1) //第一页面
{
if (flag1 == 0)
{
OLED_Clear();
flag1 = 1;
}
menu1();
}
else if (state2 == 2) //等二页面 阈值控制
{
flag2 = 0;
if (flag1 == 0)
{
OLED_Clear();
flag1 = 1;
flag2 = 1;
}
menu2();
}
}
}
8、总结
基于STM32的温湿度监控系统是将STM32单片机作为主控制器的,外接OLED显示模块、DHT11数字温湿度传感器、按键电路和输出模块,共同构成了大棚温湿度监控系统的硬件。