目录
一、主要功能
检测 分别是温湿度 光照 PM2.5、烟雾、红外,然后用OLED屏幕显示,
红外超过阈值则蜂鸣器报警,这是防盗报警;温度或烟雾超过阈值,则蜂鸣器也报警,
并且继电器驱动电机转动进行撒水,这是火灾预警;电压超过阈值,则所有模块包括显示屏全部熄灭,系统不起作用,这是过载保护。
二、硬件资源
基于KEIL5编写C++代码,PROTEUS8.15进行仿真,全部资源在页尾,提供安装包。
三、程序编程
cpp
#include "main.h"
#include "adc.h"
#include "gpio.h"
#include "./HAL/key/key.h"
#include "./HAL/OLED/OLED_NEW.H"
#include "./HAL/dht11/dht11.h"
void Monitor_function(void); //监测函数
void Display_function(void); //显示函数
void Manage_function(void); //处理函数
#define LED(a) (a?HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET):HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET))
#define LED1(a) (a?HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET):HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET))
#define BEEP(a) (a?HAL_GPIO_WritePin(BEEP_GPIO_Port, BEEP_Pin, GPIO_PIN_RESET):HAL_GPIO_WritePin(BEEP_GPIO_Port, BEEP_Pin, GPIO_PIN_SET))
uint8_t adc_ch; //adc的个数
uint32_t adc_buf[6]; //adc数值的存储数组
uint16_t temp,humi; //温湿度
uint16_t pm2,gz,hw,yw,dy;
uint16_t pwyz=60,gzyz=60,hwyz=60,ywyz=60,dyyz=60,WDYZ=300,SDYZ = 700;
uint8_t flag_led,flag_beep; //灯、报警标志位
uint16_t time_num;
static int flag = 0;
void SystemClock_Config(void);
uint16_t dong_get_adc(){
//开启ADC1
HAL_ADC_Start(&hadc1);
//等待ADC转换完成,超时为100ms
HAL_ADC_PollForConversion(&hadc1,100);
//判断ADC是否转换成功
if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1),HAL_ADC_STATE_REG_EOC)){
//读取值
return HAL_ADC_GetValue(&hadc1);
}
return 0;
}
/****
*******监测函数
*****/
void Monitor_function(void)
{
DHT11_Read_TempAndHumidity(&DHT11_Data);//调用获取温湿度、烟雾浓度、一氧化碳、甲烷、光照强度函数
temp = DHT11_Data.temperature; //获取温度
humi = DHT11_Data.humidity; //获取湿度
//将获取的值存储到adc_buf中
for(adc_ch=0;adc_ch<5;adc_ch++){
//分别存放通道1、2、3、4、5的ADC值
adc_buf[adc_ch]=dong_get_adc();
}
pm2=adc_buf[0]/4096.00*100;
gz=adc_buf[1]/4096.00*100;
hw=adc_buf[2]/4096.00*100;
yw=adc_buf[3]/4096.00*100;
dy=adc_buf[4]/4096.00*100;
}
/****
*******显示函数
*****/
void Display_function(void)
{
//第一行
Oled_ShowString(0,0,"PM2.5:");
OLED_ShowNum(48,0,pm2,2,16);
Oled_ShowCHinese(64,0,"光照:");
Oled_ShowString(96,0,":");
OLED_ShowNum(104,0,gz,2,16);
//第二行
Oled_ShowCHinese(0,2,"红外");
Oled_ShowString(32,2,":");
OLED_ShowNum(40,2,hw,2,16);
Oled_ShowCHinese(64,2,"烟雾:");
Oled_ShowString(96,2,":");
OLED_ShowNum(104,2,yw,2,16);
//第三行
Oled_ShowCHinese(0,4,"电压");
Oled_ShowString(32,4,":");
OLED_ShowNum(40,4,dy,2,16);
//第四行
OLED_Show_Temp(0,6,temp);
Oled_ShowCHinese(64,6,"湿度");
Oled_ShowString(96,6,":");
OLED_Show_Humi(96,6,humi/10);
}
/****
*******处理函数
*****/
void Manage_function(void)
{
if(hw > hwyz) //温度大于温度MAX
{
flag_beep=1;
Oled_ShowCHinese(64,4,"有人");
}
else{
Oled_ShowCHinese(64,4,"无人");
}
if(yw > ywyz) //温度大于温度MAX
{
flag_beep=1;
flag_led = 1;
}
if(temp > WDYZ) //温度大于温度MAX
{
flag_led=1;
flag_beep=1;
}
if(dy>dyyz)
{
flag = 1;
}
if(humi > SDYZ) //温度大于温度MAX
{
flag_led=1;
flag_beep=1;
}
if(hw < hwyz && yw < ywyz && dy < dyyz && temp < WDYZ )
{
flag_led=0;
flag_beep=0;
}
if(gz < gzyz)
{
LED1(1);
}
else
{
LED1(0);
}
if(flag_beep==1)
BEEP(1);
else
BEEP(0);
if(flag_led==1)
LED(1);
else
LED(0);
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC1_Init();
OLED_Init(); //OLED初始化
OLED_Clear(); //OLED清屏
while (1)
{
if(flag == 0)
{
Monitor_function(); //监测函数
Display_function(); //显示函数
Manage_function(); //处理函数
HAL_Delay(10);
}
else if(flag == 1){
OLED_Clear(); //OLED清屏
}
}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV2;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
四、实现现象
具体动态效果看B站演示视频:
基于单片机的博物馆安全监控系统设计
全部资料(源程序、仿真文件、安装包、原理图、演示视频):