当前位置: 首页 > article >正文

基于STM32的智能垃圾桶的Proteus仿真

文章目录

  • 一、智能垃圾桶
    • 1.题目要求
    • 2.思路
    • 3.电路仿真
      • 3.1 未仿真
      • 3.2 开始仿真,显示屏显示环境温度等,虚拟终端打印信息
      • 3.3 红外检测到人。模拟垃圾桶盖翻盖
      • 3.4 光照强度低于30,自动开启灯光
      • 3.5 模拟垃圾桶容量100%,检测到垃圾桶满声光报警
    • 4.仿真程序
      • 4.1 程序说明
      • 4.2 主程序
      • 4.3 OLED显示程序
      • 4.4 超声波测距函数
      • 4.5 舵机函数
  • 二、总结



一、智能垃圾桶

1.题目要求

  1. 使用超声波测距模块HC-SR04模块进行检测垃圾桶容量,检测到垃圾桶容量满载后进行报警提示,此时需要处理垃圾;
  2. 红外传感器HCSR501检测有人或者无人,有人时垃圾桶盖自动打开,无人时自动合上(用舵机模拟翻盖动作);
  3. 光敏传感器检测周围光照环境控制Led灯的亮灭;
  4. DHT11温湿度传感器检测环境的温度,湿度;
  5. MQ-135空气质量传感器检测空气质量;
  6. OLED显示屏显示温湿度,空气质量,有人/无人信息;
  7. 模拟Wifi功能,自动接收温湿度,光照强度,空气质量,垃圾桶容量等信息。

2.思路

由上面的功能需求,我们可知需要一个主控选51或者32都行,然后超声波测距模块HC-SR04,声光报警,红外传感器HCSR501,舵机,光敏电阻,Led灯,DHT11传感器,MQ-135空气质量传感器,OLED显示屏,WIfi模块等。

单片机STM32F103C8T6:

在这里插入图片描述

超声波测距模块:

在这里插入图片描述

声光报警:

在这里插入图片描述

红外传感器:

在这里插入图片描述

舵机:

在这里插入图片描述

光敏电阻和灯:

在这里插入图片描述

温湿度传感器DHT11:

在这里插入图片描述

MQ-135 空气质量传感器:

在这里插入图片描述

OLED显示屏:

在这里插入图片描述

模拟Wifi模块:

在这里插入图片描述

3.电路仿真

3.1 未仿真

在这里插入图片描述

3.2 开始仿真,显示屏显示环境温度等,虚拟终端打印信息

在这里插入图片描述

3.3 红外检测到人。模拟垃圾桶盖翻盖

在这里插入图片描述

3.4 光照强度低于30,自动开启灯光

在这里插入图片描述

3.5 模拟垃圾桶容量100%,检测到垃圾桶满声光报警

在这里插入图片描述

4.仿真程序

4.1 程序说明

主控芯片:STM32F103C8
HSI:64MHZ
Systick: 1ms

超声波测距:
TR:PA0
ECHO:PA1

光照传感器:LDR(PA2)

空气质量传感器:ADC(PA3)

灯光:LED(PA4)

DHT11温湿度传感器:DATA(PA6)

模拟WIFI模块(Uart1):9600(PA9:tx1,PA10:rx1)

舵机:
PWM1(PB6)

声光报警:BUZZER(PB11)

OLED显示屏:SCL(PB14),SDA(PB15)

4.2 主程序

/* Includes ------------------------------------------------------------------*/
#include "Drv_UserSystem.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
/**
  * @brief  main function.
  * @param  none
  * @retval none
  */
int main(void)
{
	UserSystemInit();//用户配置初始化		
	while (1)
	{			
			if (stSysTime.flg._10ms + TEN_MILLISECOND < Time_millis()) //10ms
			{
				stSysTime.flg._10ms = Time_millis();	
                IR_Scan();//检测是否有人				
			}
			if (stSysTime.flg._50ms + FIFTY_MILLISECOND < Time_millis()) //50ms
			{
				stSysTime.flg._50ms = Time_millis();						
				ADC_Scan();//光照,空气质量检测		
                DHT11_Collect_data();//DHT11采集温度,湿度					
			    Measurement_function();//测距函数								
			}				
			if(stSysTime.flg._100ms + BEST_MILLISECOND < Time_millis()) //100ms
			{
				stSysTime.flg._100ms = Time_millis();											
				OLED_Handel();//OLED显示					
				IWDG_ReloadCounter();//清开门狗 				
			}
			if (stSysTime.flg._1s + THOUSAND_MILLISECOND < Time_millis()) //1s
			{
				stSysTime.flg._1s = Time_millis();		
                Printf_Task();//打印任务				
			}
  }
}

4.3 OLED显示程序

/*******************************************************************************
 * 函数名:OLED_Handel
 * 描述  :OLED显示
 * 输入  :void
 * 输出  :void
 * 调用  :初始化
 * 备注  :100ms
*******************************************************************************/
void OLED_Handel(void)
{  	
   if(ADC_Flag)
   {
				OLED_Show_Character(1,1,0,16);//环
				OLED_Show_Character(1,2,1,16);//境	
				OLED_Show_Character(1,3,2,16);//温
				OLED_Show_Character(1,4,3,16);//度			 
				OLED_Show_Character(1,5,4,16);//:	 	
		 
				OLED_ShowNum(1,11,DHT11_temp_high,2);				

				OLED_Show_Character(1,7,5,16);//°	
				OLED_ShowString(1, 15, "C");				

				OLED_Show_Character(2,1,0,16);//环
				OLED_Show_Character(2,2,1,16);//境	
				OLED_Show_Character(2,3,6,16);//湿
				OLED_Show_Character(2,4,7,16);//度			 
				OLED_Show_Character(2,5,4,16);//:
				
				OLED_ShowNum(2,11,DHT11_humi,2);
			
				OLED_ShowString(2, 13, "%");	

				OLED_Show_Character(3,1,8,16);//空
				OLED_Show_Character(3,2,9,16);//气
				OLED_Show_Character(3,3,10,16);//质
				OLED_Show_Character(3,4,11,16);//量			 
				OLED_Show_Character(3,5,4,16);//:	 	

				OLED_ShowNum(3,11,ADC2_Value,2);
				
				OLED_ShowString(3, 13, "%");	

                if(IR_flag)
				{
				  OLED_Show_Character(4,1,12,16);//有
				  OLED_Show_Character(4,2,13,16);//人					
				}
				else
				{
				  OLED_Show_Character(4,1,14,16);//无
				  OLED_Show_Character(4,2,15,16);//人						
				}
	 }
}

4.4 超声波测距函数

如果对距离要求比较精确,最好是用10us的定时器,否则距离会有误差。

/*******************************************************************************
 * 函数名:Measurement_function
 * 描述  :HCSR04测距函数
 * 输入  :void
 * 输出  :void
 * 调用  :内部调用
 * 备注  :50ms
 *******************************************************************************/
void Measurement_function(void)
{
  Trig_Out_High();  
  DDelay_20us();
  Trig_Out_Low();	
  while(Read_Echo_Level()==0);//等待低电平结束
  ditance_count = 0;	
  while(Read_Echo_Level()==1);//等待高电平结束	
  ditance_flag = 1;	
	if(ditance_count < Overtime)//小于超时时间 38ms
	{
	   MM_ditance = ((ditance_count * 340)/2/10);//单位毫米
	}
	if(MM_ditance < 40)
	{
		capacity = 100;
	}
	else if((MM_ditance > 40) && (MM_ditance < 60))
	{
		capacity = 90;
	}
	else if((MM_ditance > 60) && (MM_ditance < 80))
	{
		capacity = 80;
	}
	else if((MM_ditance > 80) && (MM_ditance < 100))
	{
		capacity = 70;
	}
	else if((MM_ditance > 100) && (MM_ditance < 110))
	{
		capacity = 60;
	}
	else if((MM_ditance > 110) && (MM_ditance < 120))
	{
		capacity = 50;
	}
	else if((MM_ditance > 120) && (MM_ditance < 140))
	{
		capacity = 40;
	}
	else if((MM_ditance > 140) && (MM_ditance < 160))
	{
		capacity = 30;
	}
	else if((MM_ditance > 160) && (MM_ditance < 180))
	{
		capacity = 20;
	}	
	else if((MM_ditance > 180) && (MM_ditance < 190))
	{
		capacity = 10;
	}	
	else if(MM_ditance > 190)
	{
		capacity = 0;
	}
	
	if(capacity == 100)
	{
		Beep_On();
	}
	else
	{
		Beep_Off();
	}	
//	printf("MM_ditance=%d\r\n",MM_ditance);
}

4.5 舵机函数

舵机角度为-90°-90°

/*******************************************************************************
 * 函数名:User_TIM4_Init
 * 描述  :定时器4的初始化
 * 输入  :void
 * 输出  :void
 * 调用  :初始化
 * 备注  :
*******************************************************************************/
void User_TIM4_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);			//开启TIM4的时钟
	RCC_APB2PeriphClockCmd(Motor_GPIO_RCC, ENABLE);			//开启GPIOA的时钟
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//受外设控制的引脚,均需要配置为复用模式
	GPIO_InitStructure.GPIO_Pin = PWM1_Pin;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(Motor_GPIO_Port, &GPIO_InitStructure);//将PB6引脚初始化为复用推挽输出	
																	
	/*配置时钟源*/
	TIM_InternalClockConfig(TIM4);		//选择TIM4为内部时钟,若不调用此函数,TIM默认也为内部时钟
	
	/*时基单元初始化*/
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;				//定义结构体变量
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;     //时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器模式,选择向上计数
	TIM_TimeBaseInitStructure.TIM_Period = 20000 - 1;				//计数周期,即ARR的值
	TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;				//预分频器,即PSC的值
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;            //重复计数器,高级定时器才会用到
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStructure);             //将结构体变量交给TIM_TimeBaseInit,配置TIM2的时基单元
	
	/*输出比较初始化*/ 
	TIM_OCInitTypeDef TIM_OCInitStructure;							//定义结构体变量
	TIM_OCStructInit(&TIM_OCInitStructure);                         //结构体初始化,若结构体没有完整赋值
	                                                                //则最好执行此函数,给结构体所有成员都赋一个默认值
	                                                                //避免结构体初值不确定的问题
    // 配置通道1
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;            // 输出比较模式,选择PWM模式1
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;    // 输出极性,选择为高,若选择极性为低,则输出高低电平取反
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 输出使能
    TIM_OCInitStructure.TIM_Pulse = 0;                           // 初始的CCR值
    TIM_OC1Init(TIM4, &TIM_OCInitStructure);                     // 将结构体变量交给TIM_OC1Init,配置TIM4的输出比较通道1
	
	/*TIM使能*/
	TIM_Cmd(TIM4, ENABLE);			//使能TIM1,定时器开始运行	
}

/*******************************************************************************
 * 函数名:PWM1_SetCompare
 * 描述  :PWM设置CCR
 * 输入  :Compare 要写入的CCR的值,范围:0~100
 * 输出  :void
 * 调用  :初始化
 * 备注  :CCR和ARR共同决定占空比,此函数仅设置CCR的值,并不直接是占空比.占空比Duty = CCR / (ARR + 1)
*******************************************************************************/
void PWM1_SetCompare(uint16_t Compare)
{
	TIM_SetCompare1(TIM4, Compare);		//设置CCR2的值
}

/*******************************************************************************
 * 函数名:Servo1_SetAngle
 * 描述  :舵机设置角度
 * 输入  :Angle 要设置的舵机角度,范围:0~180
 * 输出  :void
 * 调用  :
 * 备注  :
*******************************************************************************/
void Servo1_SetAngle(float Angle)
{
	PWM1_SetCompare(Angle / 180 * 2000 + 500);	//设置占空比
	//将角度线性变换,对应到舵机要求的占空比范围上										
}

二、总结

今天主要讲了基于STM32的智能垃圾桶的Proteus仿真。

感谢你的观看!

在这里插入图片描述


http://www.kler.cn/a/458036.html

相关文章:

  • VueRouter之props参数
  • OpenHarmony源码编译后烧录镜像教程,RK3566鸿蒙开发板演示
  • Android MediaExtractor JNI 实现详解
  • scala概念
  • 安全漏洞合集
  • LabVIEW冷却风机性能测试系统
  • 使用 pushy 热更新后 sentry 不能正常显示源码
  • 玉米中的元基因调控网络突出了功能上相关的调控相互作用。/biosample_parser.py
  • 秒鲨后端之MyBatis【2】默认的类型别名、MyBatis的增删改查、idea中设置文件的配置模板、MyBatis获取参数值的两种方式、特殊SQL的执行
  • py打包工具
  • Python + 深度学习从 0 到 1(02 / 99)
  • 基于深度学习(HyperLPR3框架)的中文车牌识别系统-Qt调用Python
  • 在vue3中使用tsx结合render封装一个项目内通用的弹窗组件
  • Docker的概述与安装
  • 算法基础一:冒泡排序
  • React引入Echart水球图
  • systemverilog语法:assertion sequence
  • node-js Express防盗链
  • Spring Boot 多数据源解决方案:dynamic-datasource-spring-boot-starter 的奥秘(下)
  • 1.flask介绍、入门、基本用法
  • Python-网络爬虫
  • Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin(自测问题解决!)
  • 【每日学点鸿蒙知识】页面反向传值、图片撑满问题、清除Web缓存、Refresh支持swiper、POP颜色没效果
  • 验证ETL程序产生数据的正确性以及确保数据质量的方法
  • 【畅购商城】详情页详情之商品详情
  • Windows下C++使用SQLite