【STM32项目】植物养护设计
本文设计了一款基于STM32的智能火灾报警系统,采用STM32F103C8T6作为主控芯片,集成温湿度、烟雾、火焰等传感器,实现环境监测与火灾预警功能。系统具备自动、手动、远程三种控制模式:自动模式下通过传感器数据触发喷水灭火、排风等联动操作;手动模式支持按键直接控制设备;远程模式通过ESP8266连接阿里云平台实现手机APP远程监控。系统还包含OLED显示、声光报警、后备电源等功能模块,通过模块

✌️✌️大家好,这里是5132单片机毕设设计项目分享,今天给大家分享的是基于《基于STM32的智能植物养护系统设计》。
目录
一、系统功能
2.1、硬件清单
STM32核心控制板 + OLED显示屏 + 光敏传感器 + 蜂鸣器 + 风扇 + 补光灯(LED) + 水泵(继电器控制) + 舵机(遮阳棚) + 温度传感器 + 土壤湿度传感器 + 二氧化碳传感器 + 蓝牙模块 + 4个按键 + 后备电池
2.2、功能介绍
(1)蓝牙模块:用于无线通信,通过手机APP连接(原文中通过“数字意识”APP),实现远程控制风扇、水泵、补光灯等设备,并在OLED显示屏上同步显示控制状态(如开关状态)。
(2)光敏传感器:检测环境光照强度,数据用于自动控制补光灯和遮阳棚(舵机)。
(3)温度传感器:检测环境温度,数据用于自动控制风扇(当温度过高时)。
(4)土壤湿度传感器:检测土壤湿度,数据用于自动控制水泵(当湿度过低时启动灌溉)。
(5)二氧化碳传感器:检测空气中二氧化碳浓度,数据用于触发蜂鸣器报警(当浓度过高时)。
(6)OLED显示屏:实时显示系统信息,包括时间、传感器数据(温度、土壤湿度、光照强度、二氧化碳浓度)及工作模式(手动、蓝牙、自动),并支持菜单导航。
(7)4个按键模块:在不同模式下提供控制功能:
第一个按键为确认键(在手动模式下控制风扇,在自动模式下用于阈值切换);
第二个按键为菜单/模式切换键(用于切换手动、蓝牙、自动模式);
第三个按键功能上下文相关(在手动模式下控制水泵,在自动模式下用于阈值加减操作);
第四个按键为返回键(退出菜单或返回上级界面)。
(8)蜂鸣器:用于声音报警,当二氧化碳浓度超过设定阈值时自动触发。
(9)风扇:在自动模式下,当温度超过阈值时启动以降温;手动或蓝牙模式下可通过按键或APP直接控制。
(10)补光灯(LED):在自动模式下,当光照强度低于设定阈值时开启以补光;手动或蓝牙模式下可通过按键或APP直接控制。
(11)水泵(继电器控制):用于植物灌溉,在自动模式下,当土壤湿度低于设定阈值时自动启动;手动或蓝牙模式下可通过按键或APP直接控制(继电器打开时绿灯亮起)。
(12)舵机(遮阳棚):控制遮阳棚(可安装纸片模拟),在自动模式下,当光照强度超过设定阈值时自动开启以遮阳;手动或蓝牙模式下可通过APP控制。
(13)STM32核心控制板(STM32F103C8T6):作为系统主控制器,处理所有传感器数据、执行控制逻辑(如阈值比较),并协调外设(如显示屏、按键、执行器)。
(14)后备电池:用于为系统时钟供电,确保上电后时间数据保持准确。
2.3、控制模式
系统支持三种工作模式,通过第二个按键(菜单/模式切换键)进行切换:
(1)蓝牙模式(远程控制):上电后可通过蓝牙模块连接手机APP(原文中APP名称为“数字意识”),实现远程控制风扇、水泵、补光灯、遮阳棚(舵机)等设备,并实时查看OLED显示屏上的传感器数据(温度、土壤湿度、光照强度、二氧化碳浓度)。
(2)手动模式:通过按键直接控制外设:
第一个按键控制风扇开关;
第三个按键控制水泵开关(继电器状态在OLED显示);
第三个按键控制补光灯开关;
第四个按键用于返回上级菜单。
(操作时无需长按,原文未提及延迟处理)。
(3)自动模式:系统根据传感器检测值与设定阈值的比较自动执行动作,支持通过按键调整阈值(第一个按键切换阈值类型,第二个按键增加阈值,第三个按键减少阈值):
温度 > 阈值时启动风扇(例如,温度 > 30°C);
二氧化碳浓度 > 阈值时触发蜂鸣器报警(例如,二氧化碳 > 500 ppm,正常空气为350 ppm);
土壤湿度 < 阈值时启动水泵(例如,土壤湿度 < 39%);
光照强度 < 阈值时开启补光灯(例如,光照强度 < 59 lux);
光照强度 > 阈值时开启舵机(遮阳棚)(例如,光照强度 > 59 lux)。
二、演示视频和实物
基于STM32的植物养护系统设计(加入了菜单)

三、系统设计框图

四、软件设计流程图

五、原理图

六、主程序
#include "main.h"
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
delay_init(); //延时函数初始化
LED_Init(); //初始化与LED连接的硬件接口
Buzzer_Init(); //下面为外设初始化
OLED_Init();
Key_Init();
AD_Init();
Serial_Init(); //串口1初始化
MyRTC_Init();
Servo_Init(); //舵机初始化,并设置舵机初始角度
USART2_Config();
while (1)
{
TimeRead();
if (YiJiMenu) menu();
if (t % 10 == 0) //读取传感器信息
{
sensor.Guang = AD_GetValue(ADC_Channel_4); //光敏传感器 PA4
if (sensor.Guang > 4000)sensor.Guang = 4000;
sensor.Guang = (u8)(100 - (sensor.Guang / 40));
sensor.Tu_Humi = AD_GetValue(ADC_Channel_5); //土壤传感器 PA5
if (sensor.Tu_Humi > 4000)sensor.Tu_Humi = 4000;
sensor.Tu_Humi = (u8)(100 - (sensor.Tu_Humi / 40));
temperature = DS18B20_Get_Temp();
CO2GetData(&co2);
}
t++;
KeyNum = Key_GetNum(); //按键扫描
if (KeyNum == 1) //确认键
{
qingping = 0;
delay_ms(20);
if (KeyNum == 1)
{
YiJiMenu = 0;
}
}
if (KeyNum == 4) //返回键
{
qingping = 0;
delay_ms(20);
if (KeyNum == 4)
{
YiJiMenu = 1;
}
}
if (YiJiMenu == 0)
{
switch (state)
{
case 0:
{
if (qingping == 0)
{
OLED_Clear();
qingping = 1;
}
zhidong();
ChuanGan();
}
break;
case 1:
{
if (qingping == 0)
{
OLED_Clear();
qingping = 1;
}
shoudong();
}
break;
case 2:
{
if (qingping == 0)
{
OLED_Clear();
qingping = 1;
}
LanYa();
}
break;
}
}
}
}
void menu() //菜单
{
if (qingping == 0)
{
OLED_Clear();
qingping = 1;
}
if (KeyNum == 2)
{
delay_ms(20);
if (KeyNum == 2)
{
state++;
if (state > Mode - 1)
{
state = 0;
}
}
}
switch (state)
{
case 0:
{
OLED_ShowString(2, 1, ">>");
OLED_ShowString(2, 15, "<<");
OLED_ShowString(3, 1, " ");
OLED_ShowString(3, 15, " ");
OLED_ShowString(4, 1, " ");
OLED_ShowString(4, 15, " ");
OLED_ShowChinese(2, 3, 51);
OLED_ShowChinese(2, 4, 52);
OLED_ShowChinese(2, 5, 8);
OLED_ShowChinese(2, 6, 9);
OLED_ShowChinese(3, 3, 18);
OLED_ShowChinese(3, 4, 52);
OLED_ShowChinese(3, 5, 8);
OLED_ShowChinese(3, 6, 9);
OLED_ShowChinese(4, 3, 69);
OLED_ShowChinese(4, 4, 70);
OLED_ShowChinese(4, 5, 8);
OLED_ShowChinese(4, 6, 9);
}
break;
case 1:
{
OLED_ShowString(2, 1, " ");
OLED_ShowString(2, 15, " ");
OLED_ShowString(3, 1, ">>");
OLED_ShowString(3, 15, "<<");
OLED_ShowString(4, 1, " ");
OLED_ShowString(4, 15, " ");
OLED_ShowChinese(2, 3, 51);
OLED_ShowChinese(2, 4, 52);
OLED_ShowChinese(2, 5, 8);
OLED_ShowChinese(2, 6, 9);
OLED_ShowChinese(3, 3, 18);
OLED_ShowChinese(3, 4, 52);
OLED_ShowChinese(3, 5, 8);
OLED_ShowChinese(3, 6, 9);
OLED_ShowChinese(4, 3, 69);
OLED_ShowChinese(4, 4, 70);
OLED_ShowChinese(4, 5, 8);
OLED_ShowChinese(4, 6, 9);
}
break;
case 2:
{
OLED_ShowString(2, 1, " ");
OLED_ShowString(3, 1, " ");
OLED_ShowString(2, 15, " ");
OLED_ShowString(3, 15, " ");
OLED_ShowString(4, 1, ">>");
OLED_ShowString(4, 15, "<<");
OLED_ShowChinese(2, 3, 51);
OLED_ShowChinese(2, 4, 52);
OLED_ShowChinese(2, 5, 8);
OLED_ShowChinese(2, 6, 9);
OLED_ShowChinese(3, 3, 18);
OLED_ShowChinese(3, 4, 52);
OLED_ShowChinese(3, 5, 8);
OLED_ShowChinese(3, 6, 9);
OLED_ShowChinese(4, 3, 69);
OLED_ShowChinese(4, 4, 70);
OLED_ShowChinese(4, 5, 8);
OLED_ShowChinese(4, 6, 9);
}
break;
case 3:
{
OLED_ShowString(2, 1, " ");
OLED_ShowString(3, 1, " ");
OLED_ShowString(2, 15, " ");
OLED_ShowString(3, 15, " ");
OLED_ShowString(4, 1, ">>");
OLED_ShowString(4, 15, "<<");
OLED_ShowChinese(2, 3, 18);
OLED_ShowChinese(2, 4, 52);
OLED_ShowChinese(2, 5, 8);
OLED_ShowChinese(2, 6, 9);
OLED_ShowChinese(3, 3, 57);
OLED_ShowChinese(3, 4, 58);
OLED_ShowChinese(3, 5, 8);
OLED_ShowChinese(3, 6, 9);
OLED_ShowChinese(4, 3, 61);
OLED_ShowChinese(4, 4, 62);
OLED_ShowChinese(4, 5, 8);
OLED_ShowChinese(4, 6, 9);
}
break;
}
}
void shoudong()
{
OLED_ShowString(2, 1, "FengShan:");
OLED_ShowString(3, 1, "Shui Ben:");
OLED_ShowString(4, 1, "LED:");
if (KeyNum == 1) //按键
{
delay_ms(20);
if (KeyNum == 1)
{
state2++;
if (state2 > 1)
{
state2 = 0;
}
}
}
if (state2 == 0)
{
FengShan_ON();
OLED_ShowString(2, 10, "ON ");
}
if (state2 == 1)
{
FengShan_OFF();
OLED_ShowString(2, 10, "OFF");
}
if (KeyNum == 2) //按键
{
delay_ms(20);
if (KeyNum == 2)
{
state2_1++;
if (state2_1 > 1)
{
state2_1 = 0;
}
}
}
if (state2_1 == 1)
{
ShuiBen_ON();
OLED_ShowString(3, 10, "ON ");
}
if (state2_1 == 0)
{
ShuiBen_OFF();
OLED_ShowString(3, 10, "OFF");
}
if (KeyNum == 3) //按键
{
delay_ms(20);
if (KeyNum == 3)
{
state2_2++;
if (state2_2 > 1)
{
state2_2 = 0;
}
}
}
if (state2_2 == 1)
{
LED_ON();
OLED_ShowString(4, 10, "ON ");
}
if (state2_2 == 0)
{
LED_OFF();
OLED_ShowString(4, 10, "OFF");
}
}
void zhidong()
{
if (sensor.Tu_Humi < sensor.Tu_Humi_Yu)
{
ShuiBen_ON();
}
else
{
ShuiBen_OFF();
}
if (temperature > temperature_Yu)
{
FengShan_ON();
}
else
{
FengShan_OFF();
}
if (sensor.Guang < sensor.Guang_Yu)
{
LED_ON();
Servo_SetAngle(0);//外设操作
}
else
{
LED_OFF();
Servo_SetAngle(90);//外设操作
}
if (co2< 500)
{
Buzzer_OFF();
}
else
{
Buzzer_ON();
}
if (KeyNum == 1) //自动模式下PB0按键控制阈值切换
{
delay_ms(20);
if (KeyNum == 1)
{
state3++;
if (state3 > 2)
{
state3 = 0;
}
}
}
if (state3 == 1)
{
if (KeyNum == 2)temperature_Yu += 10; //光照强度上限加
if (KeyNum == 3)temperature_Yu -= 10; //光照强度上限减
}
if (state3 == 2)
{
if (KeyNum == 2)sensor.Tu_Humi_Yu++;
if (KeyNum == 3)sensor.Tu_Humi_Yu--;
}
if (state3 == 0)
{
if (KeyNum == 2)sensor.Guang_Yu++;
if (KeyNum == 3)sensor.Guang_Yu--;
}
}
void LanYa()
{
OLED_ShowString(2, 1, "FengShan:");
OLED_ShowString(3, 1, "Shui Ben:");
OLED_ShowString(4, 1, "LED:");
if (Serial_GetRxFlag() == 1)
{
RxData = Serial_GetRxData(); //蓝牙接收
switch (RxData)
{
case 1:
state2++;
if (state2 > 1)
{
state2 = 0;
}
break;
case 2:
state2_1++;
if (state2_1 > 1)
{
state2_1 = 0;
}
break;
case 3:
state2_2++;
if (state2_2 > 1)
{
state2_2 = 0;
}
break;
default:
break;
}
}
if (state2 == 0)
{
FengShan_ON();
OLED_ShowString(2, 10, "ON ");
}
if (state2 == 1)
{
FengShan_OFF();
OLED_ShowString(2, 10, "OFF");
}
if (state2_1 == 1)
{
ShuiBen_ON();
OLED_ShowString(3, 10, "ON ");
}
if (state2_1 == 0)
{
ShuiBen_OFF();
OLED_ShowString(3, 10, "OFF");
}
if (state2_2 == 1)
{
LED_ON();
OLED_ShowString(4, 10, "ON ");
}
if (state2_2 == 0)
{
LED_OFF();
OLED_ShowString(4, 10, "OFF");
}
}
void ChuanGan()
{
OLED_ShowChinese(3, 1, 63);
OLED_ShowChinese(3, 2, 65);
OLED_ShowString(3, 5, ":");
OLED_ShowNum(3, 6, sensor.Tu_Humi, 2);
OLED_ShowString(3, 8, "%");
OLED_ShowChinese(2, 1, 26);
OLED_ShowChinese(2, 2, 28);
OLED_ShowString(2, 5, ":");
if (temperature < 0)
{
OLED_ShowString(2, 6, "-"); //显示负号
temperature = -temperature; //转为正数
}
else OLED_ShowString(2, 6, "+"); //去掉负号
OLED_ShowNum(2, 7, temperature / 10, 2);
OLED_ShowString(2, 9, ".");
OLED_ShowNum(2, 10, temperature % 10, 1);
OLED_ShowNum(2, 12, co2, 4);
OLED_ShowChinese(3, 5, 4);
OLED_ShowChinese(3, 6, 6);
OLED_ShowString(3, 13, ":");
OLED_ShowNum(3, 14, sensor.Guang, 2);
OLED_ShowChinese(4, 1, 67);
OLED_ShowChinese(4, 2, 68);
OLED_ShowString(4, 5, ":");
OLED_ShowNum(4, 6, temperature_Yu / 10, 2);
OLED_ShowNum(4, 9, sensor.Tu_Humi_Yu, 2);
OLED_ShowNum(4, 12, sensor.Guang_Yu, 2);
}
void TimeRead()
{
MyRTC_ReadTime();
OLED_ShowNum(1, 2, MyRTC_Time[1], 2); //时
OLED_ShowString(1, 4, "/");
OLED_ShowNum(1, 5, MyRTC_Time[2], 2); //分
OLED_ShowNum(1, 8, MyRTC_Time[3], 2); //时
OLED_ShowString(1, 10, ":");
OLED_ShowNum(1, 11, MyRTC_Time[4], 2); //分
OLED_ShowString(1, 13, ":");
OLED_ShowNum(1, 14, MyRTC_Time[5], 2); //秒
}
七、总结
本文设计了一款基于STM32的智能火灾报警系统,采用STM32F103C8T6作为主控芯片,集成温湿度、烟雾、火焰等传感器,实现环境监测与火灾预警功能。系统具备自动、手动、远程三种控制模式:自动模式下通过传感器数据触发喷水灭火、排风等联动操作;手动模式支持按键直接控制设备;远程模式通过ESP8266连接阿里云平台实现手机APP远程监控。系统还包含OLED显示、声光报警、后备电源等功能模块,通过模块化程序设计实现了火灾检测、报警和联动控制的完整解决方案。该设计具有实用性强、响应快速、操作灵活等特点。
八、资料内容

更多推荐



所有评论(0)