STM32项目分享:矿井环境监测系统

目录

一、前言

二、项目简介

1.功能详解

2.主要器件

三、原理图设计

四、PCB硬件设计

PCB图 

五、程序设计 

六、实验效果 

七、资料内容

项目分享


一、前言

项目成品图片:

哔哩哔哩视频链接:

STM32矿井环境监测系统/粉尘监测

(资料分享见文末) 

二、项目简介

1.功能详解

基于STM32的矿井环境监测系统

功能如下:

  1. STM32F103C8T6单片机作为主控制器
  2. DS18B20测量环境温度,当温度不在设置的上下限,则声光报警
  3. PM2.5传感器测量粉尘浓度,当浓度大于设定最大值,则声光报警,并自动喷雾
  4. 可通过按键设置各阈值
  5. 通过OLED显示屏显示测量值
  6. 通过蓝牙可手机端接收数据,保存数据,手机端可远程开关喷雾

2.主要器件

  • STM32F103C8T6单片机
  • OLED 屏幕
  • DS18B20温度传感器
  • 粉尘传感器
  • BT04A蓝牙模块
  • 继电器
  • 有源蜂鸣器
  • 加湿器

三、原理图设计

四、PCB硬件设计

PCB图 

五、程序设计 

#include "sys.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "math.h"
#include "delay.h"
#include "gpio.h"
#include "key.h"
#include "oled.h"
#include "usart.h"
#include "adc.h"
#include "pm25.h"
#include "ds18b20.h"


/**********************************
变量定义
**********************************/
uint8_t key_num = 0;									//按键扫描标志位	
uint8_t flag_display = 0;							//显示界面标志位
uint32_t time_num = 0;								//10ms计时
short  temp_value = 0;									//温度值
u16 temp_max = 40;                    //温度最大值
u16 temp_min = 10;										//温度最小值
u16 pm25_value = 0;                   //粉尘值
u16 pm25_max = 200;                   //粉尘最大值
_Bool flag_mode = 0;									//模式标志位
extern uint8_t usart1_buf[256];				//串口1接收数组
char display_buf[32];									//显示缓存区
/**********************************
函数声明
**********************************/
void Key_function(void);							//按键函数
void Monitor_function(void);					//监测函数
void Display_function(void);					//显示函数
void Manage_function(void);						//处理函数


/****
*******	主函数 
*****/
int main(void)
{
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置中断优先分组
	Delay_Init();	    	 								//延时初始化	  
	Gpio_Init();		  									//IO初始化
	Key_Init();		  										//按键初始化
	Oled_Init();		  									//OLED初始化
	Oled_Clear_All();										//清屏
	Usart1_Init(9600);    							//串口1初始化
	
	PM25_Init();												//PM2.5初始化
	Adc_Init();													//ADC初始化
	DS18B20_Init();											//w温度初始化
	while(1)
	{
		Key_function();										//按键函数
		Monitor_function();								//监测函数
		Display_function();								//显示函数
		Manage_function();								//处理函数

		time_num++;												//计时变量+1
		Delay_ms(10);
		if(time_num %10 == 0)
			LED_SYS = ~LED_SYS;
		if(time_num >= 5000)
		{
			time_num = 0;
		}
	}
}

/****
*******按键函数
*****/
void Key_function(void)
{
	key_num = Chiclet_Keyboard_Scan(0);		//按键扫描
	if(key_num != 0)											//有按键按下
	{
		switch(key_num)
		{
			case 1:								            //按键1,切换设置界面
				flag_display++;
				if(flag_display >= 4)
					flag_display = 0;
				
				Oled_Clear_All();					      //清屏
			break;

			case 2:											      //按键2
				switch(flag_display)
				{
					case 0:									      //界面0:
						
					break;
					
					case 1:															//界面1:温度最大值+1
						if(temp_max < 99)
							temp_max++;
					break;

					case 2:															//界面2:温度最小值+1
						if(temp_min < temp_max-1)
							temp_min++;
					break;
					
					case 3:												//界面3:
						if(pm25_max < 650)
							pm25_max++;
					break;
					
					default:
					break;
				}
			break;

			case 3:														//按键3
				switch(flag_display)
				{
					case 0:									      //界面0:
						
					break;
					
					case 1:															//界面1:温度最大值-1
						if(temp_max > temp_min+1)
							temp_max--;
					break;
						
					case 2:															//界面2:温度最小值-1
						if(temp_min > 0)
							temp_min--;
					break;
					
					case 3:												//界面3:
						if(pm25_max > 0)
							pm25_max--;
					break;
					
					default:
					break;
				}
			break;

			default:
				
			break;
		}
	}
}

/****
*******监测函数
*****/
void Monitor_function(void)
{
	if(flag_display == 0)									//测量界面
	{

		pm25_value = Pm25_Get_Value(3);												//获取PM2.5
		temp_value = DS18B20_Get_Temp();
		
		
		if(time_num % 30 == 0)							//发送数据
		{
			UsartPrintf(USART1,"温度:%d.%dC\r\n",temp_value/10,temp_value%10);
			UsartPrintf(USART1,"粉尘:%dppm\r\n",pm25_value);
		}
		
		if(USART1_WaitRecive() == 0)				//如果接收到蓝牙数据
		{
			switch(usart1_buf[0])
			{
				case('A'):											//A:切换自动模式
					flag_mode = 0;
				break;

				case('B'):											//B:					
					RELAY_JS = ~RELAY_JS;
					flag_mode = 1;
				break;
				

				default:
				
				break;
			}	
			USART1_Clear();
		}
	}
}

/****
*******显示函数
*****/
void Display_function(void)
{
	switch(flag_display)									//根据不同的显示模式标志位,显示不同的界面
	{
		case 0:									      			//界面0:
			Oled_ShowCHinese(1,0,"温度:");
			sprintf(display_buf,"%d.%dC  ",temp_value/10,temp_value%10);
			Oled_ShowString(1, 6, display_buf);
			Oled_ShowCHinese(2,0,"粉尘:");
			sprintf(display_buf,"%dppm  ",pm25_value);
			Oled_ShowString(2, 6, display_buf);
			if(flag_mode == 0)															//显示模式
				Oled_ShowCHinese(3, 0, "模式:自动");
			else
				Oled_ShowCHinese(3, 0, "模式:手动");
		break;
		
		case 1:																								//界面1:显示设置温度最大值
			Oled_ShowCHinese(1,0,"设置温度最大值");
			if(time_num % 5 == 0)
			{
				sprintf(display_buf,"%d ",temp_max);
				Oled_ShowString(2, 6, display_buf);
			}
			if(time_num % 10 == 0)
			{
				Oled_ShowString(2, 6, "    ");
			}
		break;

		case 2:																								//界面2:显示设置温度最小值
			Oled_ShowCHinese(1,0,"设置温度最小值");
			if(time_num % 5 == 0)
			{
				sprintf(display_buf,"%d ",temp_min);
				Oled_ShowString(2, 6, display_buf);
			}
			if(time_num % 10 == 0)
			{
				Oled_ShowString(2, 6, "    ");
			}
		break;
		
		case 3:															//界面3:
			Oled_ShowCHinese(1,0,"设置粉尘最大值");
			if(time_num % 5 == 0)
			{
				sprintf(display_buf,"%d  ",pm25_max);
				Oled_ShowString(2, 7, display_buf);
			}
			if(time_num % 10 == 0)
			{
				Oled_ShowString(2, 7, "    ");
			}
		break;
		
		default:
			
		break;
	}
}

/****
*******处理函数
*****/
void Manage_function(void)
{
	if(flag_display == 0)                  //测量界面
	{
		if(flag_mode == 0)
		{
			if(pm25_value > pm25_max || temp_value > temp_max*10 || temp_value < temp_min*10) //声光报警
			{
				if(time_num % 3 == 0)
				{
					BEEP =~BEEP;
					LED =~ LED;
				}
			}
			else
			{
				BEEP = 0;
				LED = 1;
			}
			
			if(pm25_value > pm25_max)
			{
				RELAY_JS = 1;
			}
			else
			{
				RELAY_JS = 0;
			}
		}
	}
	else													         //设置界面
	{
		RELAY_JS = 0;
		BEEP = 0;
		LED = 1;
	}
}

六、实验效果 

七、资料内容

项目分享

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值