C51--项目--感应开关盖垃圾桶

1、项目概述

功能描述:

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

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

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

硬件说明:

c52单片机、sg90舵机、超声波模块、震动传感器、蜂鸣器

接线说明:

舵机控制口 P1.1

超声波 Trig 接 P1.5口

Echo 接 P1.6口

蜂鸣器接 P2.0口

震动传感器接 P3.2口(外部中断INT0)

2、编程实现

开发步骤

1、舵机和超声波代码整合,

舵机用定时器0,

超声波用定时器1,

(手册中高 4 位管定时器 1 ,低 4 位管定时器 0。0x0F:F四个一,保持低四位不变,高四位全部为0;0x10:低四位不变,使高四位M0变为16位定时器)

实现物体靠近自动滴一声开盖,2s后关盖

2、查询法实现按键控制

3、查询法实现震动控制

4、使用外部中断0配合震动控制

3、优化

解决靠近超2s抽搐问题,

添加延时关盖

优化关盖震动控制开盖问题

c 复制代码
#include "reg52.h"
#include <intrins.h>

//距离小于10cm,D5亮,D6灭,反之相反

sbit SW1			 = P2^1;	//按键开关接口
sbit D5		     = P3^7;
sbit D6 		   = P3^6;
sbit Trig		   = P1^5;
sbit Echo		   = P1^6;
sbit sg90_con  = P1^1;	//舵机
sbit vibrate   = P3^2;	//振动传感器(外部中断)
sbit beep			 = P2^0;	//蜂鸣器(低电平响)

//int换为char,节省空间
char jiaodu;
char jiaodu_bak;
char cnt = 0;
char mark_vibrate = 0;	//外部中断标志位

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

	_nop_();
	i = 15;
	j = 2;
	k = 235;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} 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 Delay10us()		//@11.0592MHz
{
	unsigned char i;

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

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

//定时器0初始化
void Time0Init()
{
	TMOD &= 0xF0;		//设置定时器 0 模式
	TMOD |= 0x01;		
	TL0 = 0x33;		  //给初值,定一个0.5ms
	TH0 = 0xFE;									
	ET0 = 1;				//打开定时器0中断			
	EA = 1;					//打开总中断EA
	TR0 = 1;		    //开始计时
	TF0 = 0;
}

//定时器1初始化
void Time1Init()		
{
	TMOD &= 0x0F;		//设置定时器 1 模式
	TMOD |= 0x10;
	TH1 = 0;
	TL1 = 0;
	//设置定时器0工作模式1,初值设定为0开始数数,不着急启动定时器
}

/*
十进制左移一位相当于乘以10。例:2左移一位为20
二进制左移一位相当于乘以2.  例:1左移一位为10(十进制的2)
左移8位,相当于乘以2的8次方 = 256
*/

double get_distance()		//封装函数距离
{
	double time;//时间
	
	//定时器数据清零,方便下一次测距
		TH1 = 0;
		TL1 = 0;
	
	startHC();					//给TRIG一个10us的高电平
	while(Echo == 0);		//ECHO由**低电平跳转到高电平**表示开始发送波
	TR1 = 1;						//波发送时启动定时器
	while(Echo == 1);		//ECHO由**高电平跳转到低电平**表示波返回
	TR1 = 0;						//波回来时关闭定时器
	time = (TH1 * 256 + TL1)*1.085;		//计算中间经过的时间,以 um 为单位
	return (time * 0.017);
	//距离=(时间)*波的速度(340m/s)/ 2 ; 340m/s = 34cm/ms = 0.034cm/us
}

void openStatuslight()		//封装函数,状态灯开D5亮,开盖
{
	D5 = 0;
	D6 = 1;
}

void closeStatuslight()		//封装函数,状态灯关D5灭,关盖
{
	D5 = 1;
	D6 = 0;
}

void initSG90_0()		//封装函数,舵机角度
{
	jiaodu = 1;	//初始化角度,0°,0.5ms的高电平
	cnt = 0;		//角度变化,cnt从0计算
	
	sg90_con = 1;//给高电平
}

void openDustbin()//封装函数,舵机转动角度--打开垃圾桶
{
	char n;
	jiaodu = 4;//爆表4次,0.5*4=2ms高电平,转135度
	if(jiaodu_bak != jiaodu){
		cnt = 0;
	
		beep = 0;		//蜂鸣器响
		for(n = 0;n < 2;n++);
			Delay150ms();
		beep = 1;
		Delay2000ms();	//每隔两秒转一次
	}
	
	jiaodu_bak = jiaodu;

}

void closeDustbin()//封装函数,舵机转动角度--关闭垃圾桶
{
	jiaodu = 1;
	jiaodu_bak = jiaodu;
	cnt = 0;
	Delay150ms();
}

void EX0_Init()	//封装函数,外部中断
{
	EX0 = 1;		//打开外部中断  (下降沿触发IT0/TCON.0 = 1 ;低电平触发IT0/TCON.0 = 0 )
	IT0 = 0;		//低电平触发
}

void main()
{
	
	double dis;//距离
	
	Time0Init();//定时器0初始化
	Time1Init();//定时器1初始化
	
	EX0_Init();
	initSG90_0();//舵机角度
	
	while(1){
		
		dis = get_distance();//超声波测距
		
		if(dis < 10 || SW1 == 0 || mark_vibrate == 1){			//小于10cm,或者sw1按键被按下,或者震动产生
			//振动产生有可能发生在延时期间,电频转变急促,不稳定,所以要使用外部中断(INIT0 )
			openStatuslight();	//D5亮,开盖
			openDustbin();			//打开垃圾桶
			mark_vibrate = 0;		//恢复
			
		}else{
				closeStatuslight();	//D5灭,关盖
				closeDustbin();			//关闭垃圾桶
				
			}
	}
	
} 

//定时器0中断
void Time0Handler() interrupt 1
{
		cnt++;				//统计爆表的次数
		TL0 = 0x33;		//重新给初值
		TH0 = 0xFE;
		if(cnt < jiaodu){		//PWM波形控制
			sg90_con = 1;
		}else{
				sg90_con = 0;
			}
	
		if(cnt == 40){ //爆表40次,经过20ms
			cnt = 0;			//重新计算cnt
			sg90_con = 1;
		}
}

//外部中断
void EX0_Handler() interrupt 0
{
	mark_vibrate = 1;
}
相关推荐
SlientICE2 小时前
TCP是什么?不需要!使用ESP32网络层直接通信!
网络·单片机·网络协议·tcp/ip
BW.SU5 小时前
单片机 + 图像处理芯片 + TFT彩屏 触摸开关控件 v1.2
单片机·人机交互·ra8889·开关控件·触摸屏设计
双叶8365 小时前
(51单片机)点阵屏LED显示图片(点阵屏LED教程)(74Hc595教程)
c语言·开发语言·单片机·嵌入式硬件·51单片机
深圳市青牛科技实业有限公司5 小时前
D3502C:一款高性能降压转换器的技术解析,可替代U3502C采用ESOP8封装
单片机·嵌入式硬件·快充·扫地机器人吸尘·筋膜枪电机·驱动轮电机
顾念`6 小时前
履带小车+六轴机械臂(2)
单片机·嵌入式硬件
努力创造奇迹6 小时前
STM32 HAL库 ADC+TIM+DMA 3路 1S采样一次电压
stm32·单片机·嵌入式硬件
leoFY1237 小时前
STM32 BOOT设置,bootloader,死锁使用方法
stm32·单片机·嵌入式硬件
czhaii7 小时前
单片机任意普通IO引脚使用定时器扩展外部中断的巧妙方法
单片机·嵌入式硬件
二块烧肉9 小时前
STM32 认识STM32
stm32·单片机·嵌入式硬件
Born_t0ward10 小时前
基于STM32 的实时FFT处理(Matlab+MDK5)
stm32·嵌入式硬件·matlab·mdk5·快速fft