毕业设计 单片机家用燃气可视化实时监控报警仪 - 物联网 嵌入式 stm32

news2024/9/26 1:25:29

文章目录

  • 0 前言
  • 1 简介
  • 2 主要器件
  • 3 实现效果
  • 4 设计原理
    • 4.1 硬件部分
    • 4.2 软件部分
  • 5 部分核心代码
  • 6 最后


0 前言

🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。

为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是

🚩 基于单片机的家用燃气的可视化实时监控报警仪

🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:4分
  • 工作量:4分
  • 创新点:3分

1 简介

本项目设计主要功能是可以用于家用燃气的可视化实时监控的迷你报警器,传感器部分和米家等绝大多数网络上的家用燃气报警使用的一致,还支持便捷更换传感器。具备WIFI模块,支持AT命令的设置。

2 主要器件

  • HK32F031K6U6主控芯片
  • SP485E芯片
  • ch340e芯片
  • MIC5219-3.3稳压芯片
  • WiFi模块

3 实现效果

在这里插入图片描述

在这里插入图片描述

4 设计原理

4.1 硬件部分

本项目涉及到的功能模块有:

  • USB转TTL通信
  • USB与单片机通信
  • USB与WIFI模块通信
  • 单片机驱动OLED液晶屏
  • 单片机驱动AHT20/21温湿度芯片
  • 单片机PWM驱动蜂鸣器
  • 单片机AD采集可燃传感器的电压值等功能。

前面和USB相关的测试方法就是插电脑和正常使用的485转接线进行连线传输,尝试不同的波特率和传输速率进行收发通信,不丢包,稳定传输就是通过测试,否则要检查硬件电路上的问题,是否有虚焊和器件上的损坏。
OLED和温湿度芯片采用IIC相关的驱动,单输出IIC可以不加上拉电阻能实现功能,但是交互式的,要获取数据的就必须加上上拉电阻才能收数正常。而且燃气传感器是催化燃烧方式的,本身会发热,且发热量还不小,故应该尽可能的把温湿度芯片和可燃传感器分的远点,不然温度和湿度测试的都不准确。每个功能模块通过软件编程实现功能后都要进行对比。屏幕驱动比较直观,看到什么就是什么了,温湿度需要进行一定的补偿。
最后蜂鸣器和按键功能的增加,蜂鸣器是5020的封装,想要实现比较亮的声音就要分析和测试,不断调教,找到比较响亮的蜂鸣声。按键功能可以做很多的联动,这里把它做成了控制屏幕显示反转的功能。

主要原理图
在这里插入图片描述

4.2 软件部分

整体逻辑流程如下:
在这里插入图片描述

5 部分核心代码

void HAL_Delay_us_init(uint8_t SYSCLK)
{
	fac_us=SYSCLK; 
}
 
void HAL_Delay_us(uint32_t nus)
{
	uint32_t ticks;
	uint32_t told,tnow,tcnt=0;
	uint32_t reload=SysTick->LOAD;
	ticks=nus*fac_us; 
	told=SysTick->VAL; 
	while(1)
	{
		tnow=SysTick->VAL;
		if(tnow!=told)
		{
				if(tnow<told)tcnt+=told-tnow;
				else tcnt+=reload-tnow+told;
				told=tnow;
				if(tcnt>=ticks)break; 
		}
	};
}
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/*
****************************************************************************************************
** 函数名称: Get_analog_voltage(u8 ch)
** 完成时间:  2017.5.24
** 编 写 人:  DIX
** 入口参数: u8 ch
** 返 回 值: 电压值
** 功能说明: ADC信号转换为电压值mV
** 备注说明: 获得ADC模拟出的电压 12位精度 (0~3.3V之间的mV值)
****************************************************************************************************
*/
uint16_t Get_analog_voltage(uint8_t AD)                  
{
	uint32_t sum=0;                                 //采样20次的累计和
	uint8_t  count;	  
	uint16_t A_AD_Value;                            //单通道AD的变量值
	ADC_ChannelConfTypeDef sConfig;
	hadc.Instance->CHSELR = 0;	
  if(AD==8)
	{
		sConfig.Channel = ADC_CHANNEL_8;	
	}	
	else
	{
		sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
	}	
	sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
	sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
	HAL_ADC_ConfigChannel(&hadc, &sConfig);			
	A_AD_Value=0;                                   //AD值清0
	for(count=0;count<50;count++)                   //重复采样50次
	{
		HAL_ADCEx_Calibration_Start(&hadc);           //校准ADC
		HAL_ADC_Start(&hadc);                         //开启ADC
		HAL_ADC_PollForConversion(&hadc, 10);		      //等待转换过程
		sum += HAL_ADC_GetValue(&hadc);               //获得50采样的累计和
	}
	A_AD_Value=sum/50;                              //AD采样50次后取平均值
	A_AD_Value=(uint16_t)(A_AD_Value*3300/4096);    //扩大了1000倍整数为1mV值
	
	sum=0;                                          //清0总值
	return A_AD_Value;                              //返回值
}

int8_t Temper_Judgment(void)
{
	int8_t  temper;
	uint16_t adc_value=0;
	adc_value = Get_analog_voltage(0);
  temper = (int8_t)((adc_value-449)/1.61);
	return temper;                                   //返回值
}
//u16进制转换为字符串
void u16tostr(u16 dat) 
{
	u8 temp[4];
	u8 i=0,j=0,k=0;
	while(dat)
	{
		temp[i]=(dat%10+0x30);
		i++;
		dat/=10;
	}
	j=i;
	k=j;
//	for(i=0;i<j;i++)
//	{
//		str1[i] = temp[j-i-1];
//	}
	for(i=0;i<4;i++)
	{
		if(4-k>i)
			str1[i] =' ';
		else 
		{	
		  //j=j-1;
		  str1[i] = temp[--j];
		}
	}	
	if(!i) 
	{str1[i++]='0';}
	//return str1;
}



/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
	u8 x=1;
//	u32 CT_data[2]={0};
//  volatile float  hum=0,tem=0;   
  /* USER CODE END 1 */
  

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */
	HAL_Delay_us_init(24);   //系统24MHz时钟
  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_ADC_Init();
  MX_USART2_UART_Init();
  MX_TIM3_Init();
  MX_TIM1_Init();
  MX_TIM2_Init();
  MX_TIM6_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
	HAL_TIM_Base_Start_IT(&htim2);                           //开启定时器2
	HAL_TIM_Base_Start_IT(&htim3);                           //开启定时器3
	HAL_TIM_Base_Start_IT(&htim1);                           //开启定时器6
  OLED_Init();
	OLED_Clear(); 
	OLED_DisplayTurn(1);
	//AHT20.alive=!AHT20_Init();	                             //AHT20温湿度传感器初始化
	temphum_init();                                          //ATH20初始化
	/*打开串口1空闲中断*/
  //__HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE);           //使能串口2中断
	/*打开串口1接收DMA中断*/
  //HAL_UART_Receive_DMA(&huart2,rx_buffer,BUFFER_SIZE);   //串口接收DMA通道	
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		if(btimer)                                  //1s中断
		{
			btimer = 0;bcont++;
//			Now_U = Get_analog_voltage(8);            //采用内部ADC采样
			if(bcont==1)
			{			
				OLED_Clear();                             //清屏
				//HAL_Delay(1000);                          //延时1秒
				OLED_DrawBMP(0,0,64,6,BMP5);              //图片显示LOGO
			}
			if(bcont==5)
			{			
				OLED_Clear();                             //清屏
				OLED_ShowCHinese(4,0,11);                 //第
				OLED_ShowCHinese(24,0,12);                //六
				OLED_ShowCHinese(44,0,13);                //届
				OLED_ShowCHinese(4,2,14);                 //立
				OLED_ShowCHinese(24,2,15);                //创
				OLED_ShowCHinese(44,2,16);                //杯	
				OLED_ShowCHinese(0,4,3);                  //燃
				OLED_ShowCHinese(16,4,17);                //气
				OLED_ShowCHinese(32,4,19);                //监	
				OLED_ShowCHinese(48,4,20);                //测
				//OLED_ShowString(8,4,"Ex",16);  
				//OLED_ShowString(0,4," O L E D",16);  
				//OLED_ShowString(0,4," 29.1",16);           //数据
				//OLED_ShowCHinese(44,4,21);                 //℃
			}
			if(bcont==9)
			{	
				OLED_Clear();                             //清屏
				//OLED_ShowString(0,0,"12.6",16);           //数据
				//OLED_ShowString(32,0,"%LEL",16);          //可燃单位
				OLED_ShowCHinese(0,0,22);                 //温
				OLED_ShowCHinese(16,0,23);                //湿
				OLED_ShowCHinese(32,0,24);                //度	

				OLED_ShowString(0,2," 26.2",16);          //数据
				OLED_ShowCHinese(44,2,21);                //℃
				OLED_ShowString(0,4,"50.7",16);           //数据
				OLED_ShowString(40,4,"%RH",16);           //湿度单位
			}
			if(bcont>=19)
			{	
				Now_U = Get_analog_voltage(8);            //采用内部ADC采样
				Temper=Temper_Judgment();                 //温度换算函数
//				/*--------AHT20读取数据---------*/
//				if(AHT20.alive)// 如果AHT20传感器存在,则读取温湿度数据
//				{
//					//读取AHT20的 20Bit原始数据
//					AHT20.flag = AHT20_ReadHT(AHT20.HT);
//					//实际标准单位转换
// 					StandardUnitCon(&AHT20);
//				}
				if(bcont==19)
				{	
					OLED_Clear();                           //清屏
				}
				if(Now_U>=900 && Now_U<2000)
				{	
					OLED_ShowCHinese(32,4,7);               //警	
					OLED_ShowCHinese(48,4,8);               //戒
				}
        else if(Now_U>=2000)	
				{	
					OLED_ShowCHinese(32,4,9);               //危
					OLED_ShowCHinese(48,4,10);              //险
				}		
				else
				{	
					OLED_ShowCHinese(32,4,5);               //安
					OLED_ShowCHinese(48,4,6);               //全
				}			
				u16tostr(Now_U);
				OLED_ShowString(0,0,"U:",16);             //电压
				OLED_ShowString(16,0,str1,16);            //数据
				OLED_ShowString(48,0,"mV",16);            //电压单位
			  memset(str1,0,4);
				OLED_ShowNum(4,2,Calculate_Concentration(Now_U),3,16);  //显示浓度
				if(Calculate_Concentration(Now_U)>=10)
					HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4);
				else
					HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_4);
			  memset(str1,0,4);
				OLED_ShowString(32,2,"%LEL",16);          //可燃单位
				OLED_ShowString(0,4,"Ex",16);             //可燃标致
			}
			if(bcont>=50)
			{	
//				AHT20_Read_CTdata(CT_data);            //不经过CRC校验,直接读取AHT20的温度和湿度数据 
//        hum = CT_data[0]*100*10/1024/1024;     //计算得到湿度值(放大了10倍)
//        tem = CT_data[1]*200*10/1024/1024-500; //计算得到温度值(放大了10倍)
//				HAL_Delay(2000);                       //延时1秒
				bcont=0;
			}				
		}
		if(!HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin))
		{		//读取KEY按键引脚,低电平表示按下
			//HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);		//LED引脚电平取反
			HAL_Delay(10);								                  //延时
			OLED_Clear(); 
			x=!x;                                           //变量取反
			OLED_DisplayTurn(x);
			while(!HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin))//等待松手,防松手抖动
			HAL_Delay(10);								                  //延时
		}
		
	}
  /* USER CODE END 3 */
}




6 最后

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/97561.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SAP ABAP 开发管理 代码内存标记 位置使用清单(Mark of memory id)

SAP ABAP 开发管理 代码内存标记 位置使用清单&#xff08;Mark of memory id&#xff09; 引言&#xff1a; 代码内存标记&#xff08;Mark of memory id&#xff09;是我开发中对 ABAP MEMORY ID 使用管理的一种方法&#xff0c;他能有效保障使用了 ABAP MEMORY ID 程序的可…

25岁从运维转向软件开发是选择Python还是Java

25岁的年龄不大&#xff0c;若是有扎实的基础&#xff0c;后期转转向软件开发是个不错的选择&#xff0c;Python是目前最火的编程语言&#xff0c;python作为人工智能的主要编程语言也有着不错的发展前景。 关于编程语言的选择&#xff0c;如果从就业的角度出发应该重点考虑一…

[附源码]Nodejs计算机毕业设计基于框架的校园爱心公益平台的设计与实现Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分…

Mechatrolink III转EtherCAT网关模块解决方案

概述 工业以太网在工业控制领域越来越流行&#xff0c;协议种类较多&#xff0c;例如Mechatrolink III、EtherCAT、Powerlink、Profinet、EtherNet/IP等等&#xff0c;在数控加工领域主流的协议有Mechatrolink III、EtherCAT。但是各种协议之间很难通信协作。 安川电机的Mech…

CPOFDM-16QAM性能仿真,输出接收端的星座图

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 CP-OFDM&#xff08;Cyclic Prefix Orthogonal Frequency Division Multiplexing&#xff0c;循环前缀正交频分复用&#xff09;通信系统采用多个正交子载波&#xff08;Orthogonalsub-Carrier&a…

非科班出身零基础能学好编程吗

近几年IT行业越来越火热&#xff0c;有很多人想转行跨界进入这个行业&#xff0c;那么作为初学者的你&#xff0c;是不是也很困惑&#xff0c;0基础非科班出身能学好编程吗&#xff1f; 编程是一个技术活&#xff0c;没有专业知识想进入这个行业是行不通的&#xff0c;这也决定…

Go工程化项目布局

如果你尝试学习Go&#xff0c;或者你正在为自己建立一个Poc或者一个玩具项目&#xff0c;这个项目布局是没有啥必要的&#xff0c;从一些简单的事情开始&#xff08;一个main文件绰绰有余&#xff09;。当有更多的人参与这个项目的时候&#xff0c;你讲需要更多的结构&#xff…

基于springboot超市进销存管理系统(Java毕业设计,包含部署文档)

大家好✌&#xff01;我是CZ淡陌。一名专注以理论为基础实战为主的技术博主&#xff0c;将再这里为大家分享优质的实战项目&#xff0c;本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#xff0c;希望你能有所收获&#xff0c;少走一些弯路…

神经网络种类及应用领域,常用的神经网络有哪些

1、神经网络算法的三大类分别是&#xff1f; 神经网络算法的三大类分别是&#xff1a; 1、前馈神经网络&#xff1a; 这是实际应用中最常见的神经网络类型。第一层是输入&#xff0c;最后一层是输出。如果有多个隐藏层&#xff0c;我们称之为“深度”神经网络。他们计算出一…

[附源码]Python计算机毕业设计Django网上鲜花购物系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

一篇文章带你轻松手撕AVL树的构建

1.AVL树介绍 我们知道一般情况下二叉搜索树的查找效率是很高的&#xff0c;但是遇到极端情况下时间复杂度就会来到O(N) 那么为了消除这种极端情况的影响&#xff0c;我们就需要调节这个二叉树通过一些操作转成一颗二叉平衡树&#xff0c;调节完毕就会得到一颗AVL树。 2.AVL树模…

【Linux】第二部分 保姆级手把手教你如何安装Linux

【Linux】第二部分 保姆级手把手教你如何安装Linux 文章目录【Linux】第二部分 保姆级手把手教你如何安装Linux2.保姆级手把手教你如何安装Linux首先下载vmware接下来下载centOS**接着开启虚拟机,对操作系统进行配置**总结2.保姆级手把手教你如何安装Linux 首先下载vmware vm…

阿里云服务器安装oracle11g

1.服务器配置 //linux版本 CentOS-7-x86_64 //oracle版本 linux.x64_11gR2 //查看服务器的CPU个数 cat /proc/cpuinfo | grep physical | sort -n | uniq | wc -l //查看服务器的型号 dmidecode -s system-product-name //查看服务器的cpu型号…

LeetCode题解 14 (3,98) 无重复字符的最长子串,验证二叉搜索树

文章目录无重复字符的最长子串(3)代码解答&#xff1a;验证二叉搜索树(98)代码解答&#xff1a;无重复字符的最长子串(3) 从题目中可以得知我们要找到该字符串中没有重复元素的最长字串,这道题可以采用滑动窗口的方法来解决,今天在这里我们采用新的方法来解决。 首先我们先将该…

转行学Python开发 怎么快速入门

对于很多转行的新手而言&#xff0c;直接参加培训班是最省时省力的事情&#xff0c;参加培训班既不用担心自己学不会&#xff0c;也不用担心遇到不懂的问题时没有人解答&#xff0c;更重要的是培训班理论实践的教学更贴合实际市场需求。 Python目前是IT行业需求量最大的语言&a…

能够让你装逼的10个Python小技巧

列表推导式 你有一个list&#xff1a; bag [1, 2, 3, 4, 5] 现在你想让所有元素翻倍&#xff0c;让它看起来是这个样子&#xff1a; [2, 4, 6, 8, 10] 大多初学者&#xff0c;根据之前语言的经验会大概这样来做 bag [1, 2, 3, 4, 5] for i in range(len(bag)): bag[i] ba…

GitHub要求所有用户在2023年底前启用双因素身份验证

©网络研究院 GitHub 将要求所有在平台上贡献代码的用户在 2023 年底之前启用双因素身份验证 (2FA) 作为对其帐户的额外保护措施。 双因素身份验证通过在需要输入一次性代码的登录过程中引入额外步骤来提高帐户的安全性。 对于 GitHub 用户来说&#xff0c;账户接管可能…

猿如意中的【Wireshark】网络包分析工具详情介绍

一、工具名称 Wireshark-win64-3.6.5 二、下载安装渠道 Wireshark-win64-3.6.5 通过CSDN官方开发的【猿如意】客户端进行下载安装。 对&#xff0c;你没有看错&#xff0c;就是来自CSDN官方&#xff0c;这次&#xff0c;CSDN果然没有辜负广大技术人的期望&#xff0c;现在…

Redis详解

Redis详解1. 概述1.1 互联网架构的演变历程1.2 Redis入门介绍1.3 Redis/Memcache/MongoDB对比1.3.1 Redis和Memcache1.3.2 Redis和MongoDB1.4 分布式数据库CAP原理1.4.1 CAP简介1.4.2 CAP理论1.4.3 CAP总结2. 下载与安装2.1 下载2.2 安装2.3 安装后的操作2.3.1 后台运行方式2.3…

高级网络应用复习——三层生成树速端口实验(带命令,保姆级)

作者简介&#xff1a;一名在校云计算网络运维学生、每天分享网络运维的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.知识点总结 1.生成树STP 2.生成树的算法 3.人为配置的作用…