感应关盖垃圾桶项目

1.功能描述

检测靠近时,垃圾桶自动开盖并伴随滴一声,2秒后关盖

发生震动时,垃圾桶自动开盖并伴随滴一声,2秒后关盖

按下按键时,垃圾桶自动开盖并伴随滴一声,2秒后关盖

2.硬件说明

SG90舵机,超声波模块,震动传感器,蜂鸣器

接线说明

舵机控制口 P1.1;超声波Trig接 P1.5 ,Echo接 P1.6 ;

蜂鸣器接 P2.0 口; 震动传感器接 P3.2`口(外部中断0)

3.开发步骤:

3.1. 舵机和超声波代码整合

舵机用定时器0

超声波用定时器1

实现物体靠近后,自动开盖,2秒后关盖

3.2. 查询的方式添加按键控制

3.3. 查询的方式添加震动控制

3.4. 使用外部中断0配合震动控制

4.烧录代码时,先检查每一个模块的功能是否完整

4.1超声波模块改为定时器1代码

#include "reg52.h"
#include <intrins.h>

sbit D5   = P3^7;//
sbit D6   = P3^6;
sbit Trig = P1^5;
sbit Echo = P1^6;


void Delay10us()		//@11.0592MHz
{
	unsigned char i;

	i = 2;
	while (--i);
}

void Delay200ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 2;
	j = 103;
	k = 147;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void Time1Init()
{
	TMOD &= 0x0F; //保持低四位不变,高四位为0
	TMOD |= 0x10; //低四位保持不变, 把M1和M0改为 0 1 
	TH1 = 0;
	TL1 = 0;
	//
}

void StartHC()
{
	Trig = 0;
	Trig = 1;
	Delay10us();
	Trig = 0;
}

void main()
{
	double time;
	double dis;
	
	Time1Init();
	//
	while(1){
		
		Delay200ms();
		StartHC();
		//
		while(Echo == 0); //
		//
		TR1 = 1;
		//
		while(Echo == 1); //
		//
		TR1 = 0;
		//
		time = (TH1 * 256 + TL1 )*1.085;
		
		//340m/s == 34000cm/s == 34cm/ms = 0.034cm/us
		dis = time * 0.017;
		if(dis < 10){
				D5 = 0;
				D6 = 1;
		}else{
				D5 = 1;
				D6 = 0;
		}
			//¶¨Ê±Æ÷Êý¾ÝÇåÁã¡£ÒÔ±ãÏÂÒ>>´Î²â¾à
			TH1 = 0;
			TL1 = 0;
	}
}

4.2舵机模块代码

#include "reg52.h"
#include <intrins.h>
 
sbit sg90_con = P1^1;  //P1^1
int cnt = 0;
int jd;
 
void Time0Init()
{
		
	//1.		配置定时器0工作模式位16位计时
	TMOD = 0x01;
 
	//2.		给初值,定一个0.5出来
	TL0 = 0x33;
	TH0 = 0xFE;
	
	//3.		开始计时
	TR0 = 1; // 允许计时
	TF0 = 0; // 溢出中断标志,溢出置1
	
	//4.        打开定时器0中断
	ET0 = 1;
	
	//5.        打开总中断
	EA = 1;
}
 
void Delay2000ms()		//@11.0592MHz
{
	unsigned char i, j, k;
 
 
	i = 15;
	j = 2;
	k = 235;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}
 
 
void Delay500ms()		//@11.0592MHz
{
	unsigned char i, j, k;
 
	
	i = 4;
	j = 129;
	k = 119;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}
 
 
void main()
{
	Delay500ms(); //让硬件稳定一下
	Time0Init();
	jd = 1;        //初始角度是0度,0.5ms,溢出1就是0.5ms,高电平
	cnt = 0; //角度变了初始化cnt为0
    sg90_con = 1;//一开始从高电平开始
 
    //每隔两秒切换一次角度
	while(1)
	{
		jd = 4;     //135度 2ms高电平
		cnt = 0;
		Delay2000ms();
		jd = 1;    //0度
		cnt = 0;
		Delay2000ms();
	}
}
 
//定时器0的中断函数
void Time0Handler() interrupt 1
{
	
					cnt++;  //统计爆表的次数. cnt=1的时候,报表了1
                            //重新给初值
				    TL0 = 0x33;
					TH0 = 0xFE;
					
					//控制PWM波
					if(cnt < jd){   
							sg90_con = 1;
					}else{
							sg90_con = 0;
					}
					
					//20ms的周期
				  if(cnt == 40){//爆表40次,经过了20ms
							cnt = 0;  //当100次表示1s,重新让cnt从0开始,计算下一次的1s
							sg90_con = 1;
					}
}

4.3.1

用外部中断来控制震动传感器模块,因为我们用查询的方式,电平的传递是非常的急促的,不稳定,导致CPU在数数的时候检测不到震动传感器模块;我们可以选择利用外部中断,一旦外部发生震动,外部震动函数立马标记1;查到标记为1,开盖;然后恢复标记为0

4.3.2

打开外部中断

外部中断0中断允许位。EX0 = 1,允许中断,EX0 = 0禁止中断

代码:

#include "reg52.h"
#include <intrins.h>

sbit D5   		= P3^7;//
sbit D6   		= P3^6;
sbit SW1      = P2^1;
sbit Trig 		= P1^5;
sbit Echo 		= P1^6;
sbit sg90_con = P1^1;  //
sbit vibrate  = P3^2;
sbit beep     = P2^0;

char cnt = 0;
char jd;
char mark_vibrate = 0;
int jd_back;


void Delay10us()		//@11.0592MHz
{
	unsigned char i;

	i = 2;
	while (--i);
}

void Delay150ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 2;
	j = 13;
	k = 237;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void Delay200ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 2;
	j = 103;
	k = 147;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void Delay2000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	i = 15;
	j = 2;
	k = 235;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void Time0Init()
{
		
	//1.		
	TMOD &= 0xF0;
	TMOD |= 0x01;
	//2.		
	TL0 = 0x33;
	TH0 = 0xFE;
	
	//3.		
	TR0 = 1; // 
	TF0 = 0; // 
	
	//4.´ò¿ª¶¨Ê±Æ÷0ÖжÏ
	ET0 = 1;
	
	
	EA = 1;
}

void Time1Init()
{
	TMOD &= 0x0F; //
	TMOD |= 0x10; //
	TH1 = 0;
	TL1 = 0;
	//
}

void StartHC()
{
	Trig = 0;
	Trig = 1;
	Delay10us();
	Trig = 0;
}

double get_distance()
{
		double time;
		//
			TH1 = 0;
			TL1 = 0;
		Delay200ms();
		StartHC();
		//
		while(Echo == 0); //
		//
		TR1 = 1;
		//
		while(Echo == 1); //
		//
		TR1 = 0;
		//
		time = (TH1 * 256 + TL1 )*1.085;
		
		//340m/s == 34000cm/s == 34cm/ms = 0.034cm/us
		return (time * 0.017);

}

void OpenstatusLight()
{
	D5 = 0;
	D6 = 1;
}

void ClosestatusLight()
{
	D5 = 1;
	D6 = 0;

}

void initSG90_0()
{
	jd = 1;       //
	cnt = 0; 			/
	sg90_con = 1; //
}

void Opendusbin()
{
	char n;
    jd = 3;
    if(jd_back != jd){
        cnt = 0;
	    beep = 0;
	    for(n = 0;n<2;n++)
			Delay150ms();
	    beep = 1;
	    Delay2000ms();
        }

       jd_back = jd;
}

void Closedusbin()
{
	jd = 1;
	cnt = 0;
	Delay150ms();
}

void EX0_Init()
{
		//
	EX0 = 1;
	//
	IT0 = 0;
}

void main()
{
	double dis;
	Time0Init();
	Time1Init();
	EX0_Init();

	
	initSG90_0();
	//
	while(1){
		//³¬Éù²¨²â¾à
		dis = get_distance(); 
		if(dis < 10 || SW1 == 0 || mark_vibrate == 1){
				/
				OpenstatusLight();
				Opendusbin();
				mark_vibrate = 0;
		}else{
				/
				ClosestatusLight();
				Closedusbin();
		}
			
	}
}


void Time0Handler() interrupt 1
{
	
					cnt++;   
					
				    TL0 = 0x33;
					TH0 = 0xFE;
					
				
					if(cnt < jd){   
							sg90_con = 1;
					}else{
							sg90_con = 0;
					}
					
					//
				  if(cnt == 40){ //
							cnt = 0;  //
							sg90_con = 1;
					}
}

void EX0_Handler() interrupt 0  //
{
	mark_vibrate = 1;
}
相关推荐
南城花随雪。13 分钟前
单片机:实现驱动超声波(附带源码)
单片机·嵌入式硬件
yutian06069 小时前
Keil MDK下载程序后MCU自动重启设置
单片机·嵌入式硬件·keil
析木不会编程12 小时前
【小白51单片机专用教程】protues仿真独立按键控制LED
单片机·嵌入式硬件·51单片机
枯无穷肉16 小时前
stm32制作CAN适配器4--WinUsb的使用
stm32·单片机·嵌入式硬件
不过四级不改名67716 小时前
基于HAL库的stm32的can收发实验
stm32·单片机·嵌入式硬件
嵌入式大圣16 小时前
单片机UDP数据透传
单片机·嵌入式硬件·udp
云山工作室17 小时前
基于单片机的视力保护及身姿矫正器设计(论文+源码)
stm32·单片机·嵌入式硬件·毕业设计·毕设
嵌入式-老费17 小时前
基于海思soc的智能产品开发(mcu读保护的设置)
单片机·嵌入式硬件
qq_3975623118 小时前
MPU6050 , 设置内部低通滤波器,对于输出数据的影响。(简单实验)
单片机
liyinuo201719 小时前
嵌入式(单片机方向)面试题总结
嵌入式硬件·设计模式·面试·设计规范