感应开关盖垃圾桶
-
功能描述
检测靠近时,垃圾桶自动开盖并伴随滴一声,2秒后关盖
发生震动时,垃圾桶自动开盖并伴随滴一声,2秒后关盖
按下按键时,垃圾桶自动开盖并伴随滴一声,2秒后关盖
-
硬件说明
SG90舵机,超声波模块,震动传感器,蜂鸣器
-
接线说明
舵机控制口 P1.1;超声波Trig接 P1.5 ,Echo接 P1.6 ;蜂鸣器接 P2.0 口; 震动传感器接 P3.2`口(外部中断0)
-
编程实现
-
舵机和超声波代码整合
舵机用定时器0
超声波用定时器1
实现物体靠近后,自动开盖,2秒后关盖
-
查询的方式添加按键控制
-
查询的方式添加震动控制
-
使用外部中断0配合震动控制
-
-
代码
c#include "reg52.h" #include <intrins.h> //垃圾桶感应开关盖 sbit Trig = P1^5;//超声波触发 sbit Echo = P1^6;//超声波计时 sbit D5 = P3^7;//led sbit D6 = P3^6; sbit vibrate = P3^2;//振动信号:不震动时输出1,振动输出0 sbit sw1 = P2^1;//按键1 sbit pwm = P1^1;//舵机信号 sbit beep = P2^0;//蜂鸣器 int cnt = 0;//定时器0溢出计数 int jd = 0;//舵机旋转角度:1为0°,每增加1,角度增加45° int mark_vibrate = 0;//振动标志 int mark_jd = 0;//角度标志 void time0_init()//定时器0初始化函数 { TMOD &= 0xF0;//选择定时器0模式 TMOD |= 0x01; TL0 = 0x33;//给定定时器0初值 TH0 = 0xFE; TR0 = 1;//开启定时器0 TF0 = 0; EA = 1;//开启中断 ET0 = 1; } void time1_init()//定时器1初始化函数 { TMOD &= 0x0F;//选择定时器1模式,16位 TMOD |= 0x10; TL1 = 0;//定时器1初值为0 TH1 = 0; } void sg90_init()//舵机初始化 { jd = 1;//0° cnt = 0; pwm = 1; } void ex0_init()//外部中断0 初始化 { EX0 = 1;//开启中断 IT0 = 1;//设置为下降沿触发 } void Delay50ms() //@11.0592MHz { unsigned char i, j; i = 90; j = 163; do { while (--j); } while (--i); } void Delay1000ms() //@11.0592MHz { unsigned char i, j, k; _nop_(); i = 8; j = 1; k = 243; do { do { while (--k); } while (--j); } while (--i); } void Delay10us() //@11.0592MHz { unsigned char i; i = 2; while (--i); } void start_HC()//给trig 10us高电平,触发超声波 { Trig = 0; Trig = 1; Delay10us(); Trig = 0; } double getDistance() { double time; TL1 = 0;//定时器归零 TH1 = 0; start_HC();//给trig一个10us的高电平开启测距 while(Echo == 0);//echo由低到高开始计时 TR1 = 1; while(Echo == 1);//echo由高到低结束计时 TR1 = 0; time = (TH1*256 + TL1) * 1.085;//计算时间,单位:us //将TH0和TL0两个8位合成一个16位,需要把TH0向左移8位,则需要将TH0 乘以 2的8次方 return (0.017 * time);//计算距离340m/s=34000cm/s=34cm/ms=0.034cm/us 单位:cm } void openLed() { D5 = 1; D6 = 0; } void closeLed() { D5 = 0; D6 = 1; } void openDustbin() { int n; jd = 3;//90° if(mark_jd != jd){//角度不发生变化 cnt = 0; beep = 0; for(n=0;n<4;n++){ Delay50ms(); } beep = 1; while(vibrate == 0); } mark_jd = jd; } void closeDustbin() { Delay1000ms();//延时2s关盖 Delay1000ms(); jd = 1; cnt = 0; mark_jd = jd; Delay50ms(); } void main() { double dis; Delay1000ms();//稳定一下 time1_init();//全部初始化 time0_init(); sg90_init(); ex0_init(); mark_jd = 1; beep = 1; while(1){ dis = getDistance(); if(dis < 10 || sw1 == 0 || mark_vibrate == 1){//接近垃圾桶、按键、振动 openLed(); openDustbin(); mark_vibrate = 0; }else{ closeLed(); closeDustbin(); } Delay50ms();//延时一下,防止程序buzy测不了距离 } } void time0_inter() interrupt 1//定时器0中断 { //定时器0溢出后cnt++,同时还原初值 cnt++; TL0 = 0x33; TH0 = 0xFE; if(cnt < jd){ pwm = 1; }else{ pwm = 0; } //cnt=40后,正好20ms一个周期 if(cnt == 40){ cnt = 0; pwm = 1; } } void ex0_inter() interrupt 0 { mark_vibrate = 1; }