嵌入式项目分享 单片机家用燃气的可视化实时监控报警仪 - 物联网 嵌入式 stm32


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 最后

🔥 项目分享与指导:https://gitee.com/sinonfin/sharing

  • 25
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值